--- /dev/null
+Library: Libgcrypt
+Homepage: http://www.gnu.org/software/libgcrypt/
+Maintainer: Werner Koch <wk@gnupg.org>
+Bug reports: <bug-libgcrypt@gnupg.org> or http://bugs.gnupg.org
+Security related bug reports: <security@gnupg.org>
+License (library): LGPLv2.1+
+License (manual and tools): GPLv2+
+
+Libgcrypt used to be part of GnuPG but has been taken out into its own
+package on 2000-12-21.
+
+
+Authors of Libgcrypt
+====================
+
+GNUPG Werner Koch 1998-02-23
+Assigns GNU Privacy Guard and future changes.
+wk@gnupg.org
+Designed and implemented GnuPG.
+
+GNUPG Matthew Skala 1998-08-10
+Disclaims changes.
+mskala@ansuz.sooke.bc.ca
+Wrote cipher/twofish.c.
+
+GNUPG Natural Resources Canada 1998-08-11
+Disclaims changes by Matthew Skala.
+
+GNUPG Michael Roth Germany 1998-09-17
+Assigns changes.
+mroth@nessie.de
+Wrote cipher/des.c.
+Changes and bug fixes all over the place.
+
+GNUPG Niklas Hernaeus 1998-09-18
+Disclaims changes.
+nh@df.lth.se
+Weak key patches.
+
+GNUPG Rémi Guyomarch 1999-05-25
+Assigns past and future changes. (g10/compress.c, g10/encr-data.c,
+g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
+rguyom@mail.dotcom.fr
+
+ANY g10 Code GmbH 2001-06-07
+Code marked with ChangeLog entries of g10 Code employees.
+
+LIBGCRYPT Timo Schulz 2001-08-31
+Assigns past and future changes.
+twoaday@freakmail.de
+
+LIBGCRYPT Simon Josefsson 2002-10-25
+Assigns past and future changes to FSF (cipher/{md4,crc}.c, CTR mode,
+CTS/MAC flags, self test improvements)
+simon@josefsson.org
+
+LIBGCRYPT Moritz Schulte 2003-04-17
+Assigns past and future changes.
+moritz@g10code.com
+
+GNUTLS Nikolaos Mavrogiannopoulos 2003-11-22
+nmav@gnutls.org
+Original code for cipher/rfc2268.c.
+
+LIBGCRYPT The Written Word 2005-04-15
+Assigns past and future changes. (new: src/libgcrypt.pc.in,
+src/Makefile.am, src/secmem.c, mpi/hppa1.1/mpih-mul3.S,
+mpi/hppa1.1/udiv-qrnnd.S, mpi/hppa1.1/mpih-mul2.S,
+mpi/hppa1.1/mpih-mul1.S, mpi/Makefile.am, tests/prime.c,
+tests/register.c, tests/ac.c, tests/basic.c, tests/tsexp.c,
+tests/keygen.c, tests/pubkey.c, configure.ac, acinclude.m4)
+
+LIBGCRYPT Brad Hards 2006-02-09
+Assigns Past and Future Changes
+bradh@frogmouth.net
+(Added OFB mode. Changed cipher/cipher.c, test/basic.c doc/gcrypt.tex.
+ added SHA-224, changed cipher/sha256.c, added HMAC tests.)
+
+LIBGCRYPT Hye-Shik Chang 2006-09-07
+Assigns Past and Future Changes
+perky@freebsd.org
+(SEED cipher)
+
+LIBGCRYPT Werner Dittmann 2009-05-20
+Assigns Past and Future Changes
+werner.dittmann@t-online.de
+(mpi/amd64, tests/mpitests.c)
+
+GNUPG David Shaw
+Assigns past and future changes.
+dshaw@jabberwocky.com
+(cipher/camellia-glue.c and related stuff)
+
+LIBGCRYPT Andrey Jivsov 2010-12-09
+Assigns Past and Future Changes
+openpgp@brainhub.org
+(cipher/ecc.c and related files)
+
+
+More credits
+============
+The ATH implementation (src/ath*) has been taken from GPGME and
+relicensed to the LGPL by the copyright holder of GPGME (g10 Code
+GmbH); it is now considered to be a part of Libgcrypt.
+
+Most of the stuff in mpi has been taken from an old GMP library
+version by Torbjorn Granlund <tege@noisy.tmg.se>.
+
+The files cipher/rndunix.c and cipher/rndw32.c are based on those
+files from Cryptlib. Copyright Peter Gutmann, Paul Kendall, and Chris
+Wedgwood 1996-1999.
+
+The ECC code cipher/ecc.c was based on code by Sergi Blanch i Torne,
+sergi at calcurco dot org.
+
+The implementation of the Camellia cipher has been been taken from the
+original NTT provided GPL source.
+
+The CAVS testing program tests/cavs_driver.pl is not to be considered
+a part of libgcrypt proper. We distribute it merely for convenience.
+It has a permissive license and is copyrighted by atsec information
+security corporation. See the file for details.
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2006,
+ 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 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.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, 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 software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+\f
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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 Program or any portion
+of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+\f
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) 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; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, 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 executable. 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+\f
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 5. 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 Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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.
+
+ 7. 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 Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+\f
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; 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.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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 Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ 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 Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+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 other code 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.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must
+be allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ 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, whereas the latter must
+be combined with the library in order to run.
+^L
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser 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.
+\f
+ 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.
+^L
+ 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.
+^L
+ 6. As an exception to the Sections above, you may also combine 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) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) 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.
+
+ d) 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.
+
+ e) 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 materials to be 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.
+^L
+ 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 with
+this License.
+^L
+ 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 Lesser 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.
+^L
+ 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
+^L
+ 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser 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!
+
+
--- /dev/null
+2011-06-29 Werner Koch <wk@g10code.com>
+
+ Release 1.5.0.
+
+ * configure.ac: Keep LT version at C18/A7/R0 because it has
+ already been bumped up at 2010-07-09.
+
+ * config.guess, config.sub: Update to 2011-06-03.
+
+2011-04-06 Werner Koch <wk@g10code.com>
+
+ * configure.ac (emacs_local_vars_begin): Move more to the top to
+ avoid Emacs warnings.
+
+2011-03-30 Werner Koch <wk@g10code.com>
+
+ * compat/compat.c (_gcry_compat_identification): Add version string.
+
+2011-03-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac (BUILD_REVISION): Use new git_brevis macro.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * configure.ac (LIBGCRYPT_CONFIG_HOST): New.
+
+ * acinclude.m4 (AM_PATH_GPG_ERROR): Remove.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ Release 1.5.0-beta1.
+
+2011-02-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac [GCC]: Remove the use of -fno-strict-aliasing.
+
+2011-02-11 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disbale-aesni-support.
+ (ENABLE_AESNI_SUPPORT): New macro.
+
+2011-02-04 Werner Koch <wk@g10code.com>
+
+ * autogen.sh: Install the git pre-commit if not yet done.
+
+2010-12-23 Werner Koch <wk@g10code.com>
+
+ * configure.ac (BUILD_REVISION): Use git_revision.
+
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Define GPG_ERR_ENABLE_ERRNO_MACROS. Remove
+ definition of _GNU_SOURCE.
+ (AC_GNU_SOURCE): New.
+
+2010-08-16 Werner Koch <wk@g10code.com>
+
+ * configure.ac (INSERT_SYS_SELECT_H): New.
+
+2010-07-09 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C18/A7/R0 to prepare a backport
+ of a new API to the 1.4 series.
+
+2010-04-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Check for -fno-strict-aliasing.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * configure.ac: Print more verbose info at the end.
+
+2010-03-24 Werner Koch <wk@g10code.com>
+
+ * configure.ac (USE_RNDW32CE): New.
+
+2010-03-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac (emacs_local_vars_begin)
+ (emacs_local_vars_read_only, emacs_local_vars_end): New.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * compat/Makefile.am: New.
+ * compat/compat.c: New.
+ * compat/libcompat.h: New.
+ * compat/getpid.c, compat/clock.c: New.
+
+ * configure.ac: Require libgpg-error 1.8.
+ (HAVE_W32CE_SYSTEM): New am_defines and am_conditionals.
+ (getpid): Check for replacement function.
+ (AC_CONFIG_LIBOBJ_DIR): New.
+ (AC_TYPE_PID_T): New.
+ (AM_INIT_AUTOMAKE): Use modern variant.
+ (AC_CONFIG_FILES): Add compat/Makfile.
+ * autogen.sh: Support W32CE.
+ * ltmain.sh: Update to 2.2.6b
+ (wrappers_required): Don't set for mingw32ce.
+ * Makefile.am (DIST_SUBDIRS, SUBDIRS): Add compat.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disable-O-flag-munging.
+
+2009-12-08 Marcus Brinkmann <marcus@g10code.de>
+
+ Update to libtool 2.2.6a.
+ * configure.ac: Invoke AC_CONFIG_MACRO_DIR.
+ (AC_LIBTOOL_WIN32_DLL, AC_LIBTOOL_RC): Replace by ...
+ (LT_PREREQ, LT_INIT, LT_LANG): ... these.
+ * config.guess, config.sub, install-sh, ltmain.sh, m4/libtool.m4:
+ Updated to libtool 2.2.6a.
+ * m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4,
+ m4/lt~obsolete.m4: New files from libtool 2.2.6a.
+
+2009-08-05 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Test for sys/msg.h.
+
+2009-04-23 Werner Koch <wk@g10code.com>
+
+ * README: Add a section on build problems.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C17/A6/R0 to mark the start of
+ a new development series.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ Release 1.4.4.
+
+ * configure.ac: Bump LT version to C16/A5/R2.
+
+2008-10-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Remove option --enable-gcc-warnings. Autodetect
+ useful gcc warnings in maintainer mode.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ Release 1.4.3.
+
+ * configure.ac: Bump LT version to C16/A5/R1.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Cehck for syslog.
+
+2008-09-08 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2rc2.
+
+ * configure.ac: Update svn_revision macro.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --enable-hmac-binary-check.
+ (DL_LIBS): Check whether -ldl is required.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ Release 1.4.2rc1.
+
+ * configure.ac: Bump LT version to C16/A5/R0.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Remove the unused BUGS file.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AH_BOTTOM): Define GCRY_GPG_ERR_NOT_OPERATIONAL.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random/: New.
+ * Makefile.am (DIST_SUBDIRS): Add random.
+ * configure.ac (AC_CONFIG_FILES): Add random/Makefile.
+
+2008-04-25 Werner Koch <wk@g10code.com>
+
+ Release 1.4.1.
+
+ * configure.ac: Bump LT version to C15/A4/R4.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Set version to 1.4.1rc1.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AH_BOTTOM): Add CAMELLIA_EXT_SYM_PREFIX.
+ (NAME_OF_DEV_RANDOM): Remove special cases for Solaris etc. This
+ matches the gnupg 1.4.9 version.
+
+2008-04-01 Werner Koch <wk@g10code.com>
+
+ * configure.ac (AC_INIT): Fix quoting.
+
+2008-03-19 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Fix the tests for USE_<algo> to either define or
+ undef the macros. Suggested by Dirk Stoecker.
+
+2008-03-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Test for uintptr_t.
+
+2008-02-18 Werner Koch <wk@g10code.com>
+
+ * configure.ac (IS_DEVELOPMENT_VERSION): Set depending on the my_svn.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * configure.ac: We actually require libgpg-error 1.4. Reported by
+ Tim Mooney.
+
+2007-12-10 Werner Koch <wk@g10code.com>
+
+ Released 1.4.0.
+
+ * configure.ac: Set LT to C15/A4/R3.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add option --disable-padlock-support.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ Released 1.3.2.
+
+ * configure.ac: Set LT to C15/A4/R2.
+
+ * config.sub, config.guess: Update to version 2007-11-19.
+
+2007-10-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Protect config.h against double inclusion.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ Released 1.3.1.
+
+ * configure.ac: Set LT to C15/A4/R1.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * README: Rewrite the license description.
+ * configure.ac (USE_RNDW32, USE_RNDUNIX): Unmark as GPL modules.
+
+2007-08-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Use $host and not $target.
+
+2007-07-26 Werner Koch <wk@g10code.com>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fix a syntax error
+ in the test program which lurked there for 4 years. Adjusted name
+ of libtools global_system_pipe variable and add extra cut stage.
+ Reported by Gregor Riepl.
+
+2007-06-15 Werner Koch <wk@g10code.com>
+
+ * autogen.sh (FORCE): Use = and not == in test to be POSIXly correct.
+
+2007-05-30 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Camellia is no longer GPL.
+
+2007-05-24 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Try to use -Wpointer-arith.
+
+2007-05-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Fix test for optional UDIV and UDIV_QRNND MPI
+ modules.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (ac_cv_mpi_config_done): Unused variable removed.
+ (ac_cv_mpi_mod_list, MPI_MOD_LIST_LO, MPI_MOD_LIST_O): Removed.
+ (MPI_MOD_ASM_MPIH_ADD1, MPI_MOD_ASM_MPIH_SUB1,
+ MPI_MOD_ASM_MPIH_MUL1, MPI_MOD_ASM_MPIH_MUL2,
+ MPI_MOD_ASM_MPIH_MUL3, MPI_MOD_ASM_MPIH_LSHIFT,
+ MPI_MOD_ASM_MPIH_RSHIFT, MPI_MOD_ASM_MPIH_UDIV,
+ MPI_MOD_ASM_MPIH_UDIV_QRNND, MPI_MOD_C_MPIH_ADD1,
+ MPI_MOD_C_MPIH_SUB1, MPI_MOD_C_MPIH_MUL1, MPI_MOD_C_MPIH_MUL2,
+ MPI_MOD_C_MPIH_MUL3, MPI_MOD_C_MPIH_LSHIFT, MPI_MOD_C_MPIH_RSHIFT,
+ MPI_MOD_C_MPIH_UDIV, MPI_MOD_C_MPIH_UDIV_QRNND): New automake
+ variables.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ Released 1.3.0.
+
+ * configure.ac: Set LT to C15/A4/R0.
+
+ * configure.ac: Require automake 1.10
+ (AM_PROG_CC_C_O): New.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Fix detection of GPLed random modules.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * configure.ac (LIBGCRYPT_DIGESTS, LIBGCRYPT_CIPHERS)
+ (LIBGCRYPT_PUBKEY_CIPHERS): Ac_define lists of algorithms.
+ (default_ciphers): Don't make camellia a default.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * NEWS, configure.ac: Add Camellia.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * README.apichanges: Move to doc/.
+ * Makefile.am (EXTRA_DIST): Removed that file.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Allow to specify additional search directories
+ with --enable-mpi-path.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Check for sysconf.
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
+ page size and use getpagesize only then if available.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Add support for ECC.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Use
+ --enable-random-daemon.
+
+ * configure.ac: New option --enable-random-daemon.
+ Create versioninfo.rc and provide the build information.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * Makefile.am, configure.ac: Ignore w32-dll/.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Bump LT version to C14/A3/R0 in preparation for a
+ release.
+
+ * autogen.sh: Add option --force.
+ * configure.ac: New option --disable-endian-check. Use a real
+ noexecstack test instead of requiring an option. Add SVN version
+ magic.
+
+2007-02-02 Werner Koch <wk@g10code.com>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Special case for mingw32.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * autogen.sh: Add convenience option --build-amd64.
+
+2006-10-20 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (stowinstall): New convenience target.
+
+2006-10-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Third time is a charm.
+ Define gcry_socklen_t, to avoid conflicts with socklen_t
+ definitions by autoconf.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (FALLBACK_SOCKLEN_T): Rewrite in terms of
+ socklen.m4.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Removed.
+ * configure.ac: Do not call GNUPG_FIX_HDR_VERSION.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Invoke AC_CHECK_SOCKLEN_TYPE.
+ (AC_CONFIG_FILES): Add src/gcrypt.h.
+ (AC_CONFIG_SRCDIR): Change to src/libgcrypt.vers.
+
+2006-10-02 Werner Koch <wk@g10code.com>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Test on HOST and not
+ TARGET. Hardwire for mingw32. Allow setting via command line when
+ cross compiling.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * configure.ac (USE_SEED): New.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * configure.ac: New options --enable-noexecstack and
+ --disable-optimization.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac: Call AC_LIBTOO_WIN32_DLL and AC_LIBTOOL_RC.
+
+ * configure.ac: Call gl_TYPE_SOCKLEN_T instead of the other
+ socklen_t checks.
+
+2006-06-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (PTH_LIBS): Add --all to pth-config invocation.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Check for fctnl and ftruncate.
+ (HAVE_PTH): Check for GNU Pth.
+ (HAVE_W32_SYSTEM): Define it.
+ * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. Taken from GnuPG 1.4.
+
+2005-12-08 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Changed the random device names for netbsd. From
+ Christian Biere.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Documented minor API changes.
+
+2005-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Depend on README.SVN, not on README.CVS.
+
+2005-06-25 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Removed src/libgcrypt.pc from AC_CONFIG_FILES.
+
+2005-06-10 Werner Koch <wk@g10code.com>
+
+ * configure.ac: Move detection of basic stuff to the top. For
+ example we need to know whether gcc is used before testing for it.
+ Reported by Ralf Fassel.
+
+2005-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * acinclude.m4 (TYPE_SOCKLEN_T): New type definition test;
+ provided by Albert Chin.
+ * configure.ac: Don't use $(CMD) as it's not portable; use CMD in
+ backticks instead. Simpler -lnsl/-lsocket test. Use
+ TYPE_SOCKLEN_T test. Don't forget to set `random_modules'
+ correctly.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Added support for pkgconfig; provided by Albert
+ Chin.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Integrate Whirlpool.
+
+2005-01-04 Werner Koch <wk@g10code.com>
+
+ Updated to automake 1.9.
+
+ * acinclude.m4: Updated for use with automake 1.9.
+
+ * configure.ac: Require libgpg-error 1.0; not really needed but
+ that is the first stable version.
+
+ * Makefile.am (ACLOCAL_AMFLAGS): New for -I m4.
+ (AUTOMAKE_OPTIONS): New to create a bzip archive.
+
+2005-02-03 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-08-09 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * THANKS: Updated.
+
+2004-04-21 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Don't print a warning if GNU make was not found.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * THANKS: Updated.
+
+2004-04-02 Thomas Schwinge <schwinge@nic-nac-project.de>
+
+ * autogen.sh: Added ACLOCAL_FLAGS.
+
+2004-04-15 Werner Koch <wk@gnupg.org>
+
+ Released 1.2.0.
+
+ * configure.ac: Set LT to C12/A1/R1.
+
+2004-04-06 Werner Koch <wk@gnupg.org>
+
+ * config.guess, config.sub, ltmain.sh: Updated to those from
+ libtools 1.5.4.
+
+2004-03-29 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.94.
+
+ * configure.ac: Set LT to C12/A1/R0.
+
+2004-03-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * configure.ac (LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+ LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+ LIBGCRYPT_CONFIG_CFLAGS_PTH, have_pth, have_pthread, AC_CHECK_PTH,
+ AC_CHECK_LIB(pthread), HAVE_PTH, HAVE_PTHREAD): Removed.
+
+2004-03-06 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.93.
+
+ * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): Replaced by
+ LIBGCRYPT_CONPIG_API_VERSION. Set it to 1. Set LT to C11/A0/R1.
+
+2004-03-05 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): New.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.92.
+
+ * configure.ac: Set LT to C11/A0/R0.
+
+2004-02-11 Werner Koch <wk@gnupg.org>
+
+ * autogen.sh (check_version): Removed bashism and simplified.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Add rfc2268 cipher algorithm.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * THANKS: Updated.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.91.
+
+ * configure.ac: Bumbed LT version to C10/A3/R1.
+
+2003-12-08 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (dist-hook): Don't distribute stuff from the now
+ obsolete scripts dir.
+ (EXTRA_DIST): Remove README_alpha
+ * README-alpha: Removed.
+ * configure.ac (AM_CONFIG_AUX_DIR): Removed.
+
+ * COPYING.DOC: Removed.
+ * Makefile.am (EXTRA_DIST): Added README.CVS and
+ autogen.sh. Removed COPYING.DOC.
+
+2003-11-14 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.90.
+
+ * configure.ac: Bumbed LT version to C10/A3/R0.
+
+ * configure.ac (have_ld_version_script): Set the default in
+ a separate test.
+ (PRINTABLE_OS_NAME): Don't handle the Hurd extra, this leads to
+ conflicts with BSD based GNU systems. The Hurd has now a working
+ uname.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (USE_SHA1): Make sure it is always included.
+ (USE_RMD160): Removed this AM conditional.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Bumbed version number to 1.1.90-cvs for futher
+ development
+
+ Released 1.1.44.
+
+ * acinclude.m4 (AC_CHECK_PTH): Added.
+ * configure.ac: Use it here instead of the generic lib test.
+ Bumbed LT vesion to C9/A2/R0.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Give a hint on where libgpg-error is available.
+ Reformatted long lines. Don't include gcrypt-defs.h.
+ (--enable-gcc-warnings): New option.
+
+2003-10-24 Moritz Schulte <mo@g10code.com>
+
+ * configure.ac: Check for socklen_t.
+
+2003-10-11 Moritz Schulte <mo@g10code.com>
+
+ * acinclude.m4: Update AM_PATH_GPG_ERROR macro.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.43.
+
+ * configure.ac: Require libgpg-error 0.4 due to the prime interface.
+
+2003-08-29 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Re-implemented.
+ * configure.ac: Use it here.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * configure.ac: Substitute: LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+ LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+ LIBGCRYPT_CONFIG_CFLAGS_PTH, LIBGCRYPT_THREAD_MODULES.
+
+2003-08-07 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Fail, if libgpg-error could not be found.
+
+2003-07-31 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.42.
+
+ * configure.ac: Set LT version to 7/0/0.
+
+2003-07-30 Werner Koch <wk@gnupg.org>
+
+ * AUTHORS (Maintainer): Assigned Moritz as Maintainer.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Include much more complete list of `Interface changes
+ relative to the 1.1.12 release'.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Bumbed version number up to 1.1.42-cvs.
+
+2003-07-09 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Reintroduce --disable-asm, since it is needed by
+ mpi/config.links.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * README: Few changes, mention libgpg-error.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (available_ciphers): Removed Serpent, hrrm.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * acinclude.m4: Removed macro definitions: GNUPG_CHECK_FAQPROG,
+ GNUPG_CHECK_ENDIAN, GNUPG_CHECK_CACHE, GNUPG_CHECK_PIC,
+ GNUPG_CHECK_EXPORTDYNAMIC, GNUPG_CHECK_IPC, GNUPG_PROG_NM,
+ GNUPG_SYS_SYMBOL_UNDERSCORE, GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
+ GPH_PROG_DB2ANY.
+ Added macro definitions: AM_PATH_GPG_ERROR.
+
+ * configure.ac: Use alternative approach for building based on
+ conditional sources, which does not make automake eat all your
+ memory, etc.
+ Removed unused tests.
+ Renamed --enable-static-rnd to --enable-random.
+ Use Autoconf's AC_C_BIGENDIAN macro instead of our own.
+ Re-organized the whole file.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (AC_CONFIG_FILES): Removed doc/version.sgml.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Remove --enable-libgpg-error flag.
+ Ue AC_PATH_GPG_ERROR.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Mention API changes and libgpg-error.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (USE_LIBGPG_ERROR): Implementation of the
+ --enable-libgpg-error switch.
+ Define USE_LIBGPG_ERROR in LIBGCRYPT_CONFIG_FLAGS, in case
+ libgpg-error is used.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac (AC_CHECK_HEADERS): Removed unused headers:
+ termio.h, langinfo.h.
+ (AC_CHECK_FUNCS): Removed unused functions: strsep, strlwr,
+ tcgetattr, setrlimit, strftime, nl_langinfo, sigaction,
+ sigprocmask, fopen64, fstat64.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * README: Documented new configure switches.
+ Mention the --enable-maintainer-switch.
+
+ * configure.ac: Merged some code from GnuPG's configure.ac for
+ disabling sha512/tiger in case no 64 data types are available.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Include support for sha512.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * AUTHORS: Updated.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Implement command line switches: --enable-ciphers,
+ --enable-pubkey-ciphers and --enable-digests.
+ Set Automake conditionals and config.h symbols depending on the
+ selected ciphers, pubkey-ciphers, digests and random-modules.
+
+ * acinclude.m4 (LIST_MEMBER): New macro.
+
+ * configure.ac: Simplified, removed code for parsing
+ EXTRA_PROGRAMS from Makefile.am.
+
+2003-04-08 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Merged random-module selection code from GnuPG's
+ configure.ac.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * configure.ac: Removed code for generating contruct.c.
+ Remove digest modules from the static_modules list, only handle
+ random module selection.
+
+
+2003-03-24 Moritz Schulte <moritz@g10code.com>
+
+ * NEWS: Mention new CBC_MAC flag.
+
+ * AUTHORS (Maintainer): Update entry for Simon Josefsson.
+
+2003-03-04 Moritz Schulte <moritz@g10code.com>
+
+ * TODO: Remove item about resetting handles, since
+ gcry_cipher_reset is implemented by now.
+
+ * NEWS: Mentioned gcry_cipher_reset.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * README (Configure options): New.
+ * configure.ac (have_ld_version_script): New option
+ --enable-ld-version-script.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * configure.ac (MODULES_IN_CIPHER): Add crc.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.12.
+
+ * configure.ac (LIBGCRYPT_LT_REVISION): Bumbed up.
+
+2002-12-21 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.11.
+
+ * configure.ac (LIBGCRYPT_LT_CURRENT: Bumbed to 6/5/0 due to a new
+ interface
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (have_pthread): Check for pthreads in libc.
+ (have_ld_version_script): New.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (MODULES_IN_CIPHER): Add md4.c. By Simon Josefsson.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.10.
+
+ * configure.ac (HAVE_DEV_RANDOM_IOCTL): Don't check for it; it is
+ not used.
+ (AS_CHECK_HEADERS): Check for sys/select.h.
+ * Makefile.am (DIST_SUBDIRS): New to include the w32-dll directory
+
+2002-09-18 Timo Schulz <ts@winpt.org>
+
+ * configure.ac: Added makefile for the W32 DLL.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Check for Pth and Pthreads.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.9.
+
+ * configure.ac (LIBGCRYPT_CONFIG_CFLAGS): Renamed from
+ LIBGCRYPT_CFLAGS and removed the libpath because it is set by the
+ config script.
+ (LIBGCRYPT_LT_REVISION): Set LT version to 5/4/1.
+
+2002-06-25 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.8.
+
+ * configure.ac: Set LT version to 5/4/0.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.7.
+
+ * configure.ac: Set LT version to 4/3/0.
+
+2002-05-17 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Removed all the dynamic loading stuff.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Reordered the C_CHECK_FUNCS.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Adjusted for new MPI module stuff.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * jnlib/: Removed.
+ * Makefile.am (SUBDIRS): Removed jnlib.
+ * configure.ac (jnlib/Makefile): Removed.
+
+ * configure.ac: Define _REENTRANT.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * configure.ac (MPI_EXTRA_ASM_OBJS): Use .lo suffix.
+ (AC_CANONICAL_TARGET): Added.
+
+2002-02-07 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.6.
+
+2002-01-24 Werner Koch <wk@gnupg.org>
+
+ * jnlib/: Replaced by a fresh copy from GnuPG (actually the NewPG
+ development branch). Adjusted Makefile.am and jnlib-config.h
+ accordingly.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.5.
+
+ * Makefile.am (dist-hook): Only look in mpi and scripts for
+ distfiles; this way we don't include those of a stale "make dist"
+ directory.
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Make it work with the new
+ automake.
+ * configure.ac: Don't chmod db2any.
+
+2001-08-06 Werner Koch <wk@gnupg.org>
+
+ * configure.ac: Removed cross compiling hacks.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.4.
+
+ * acinclude.m4 (GNUPG_CHECK_TYPEDEF): Define GNU Source.
+
+ Migrated to autoconf 2.52.
+ * acinclude.m4: Removed GNUPG_LINK_FILES and converted.
+ * acconfig.h: Removed
+ * configure.in: Replaced by...
+ * configure.ac: and modified for use with autoconf 2.52. Replaced
+ GNUPG_LINK_FILES with AC_CONFIG_LINKS and moved some informational
+ messages to the end. Removed --enable-m-debug
+
+ * tests/: New.
+ * Makefile.am: Included tests directory
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Use -shared with dec-osf.
+ Reported by Chris Adams. Merged some cases.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ Released 1.1.3.
+
+ * configure.in: Use _gcry_ prefix when creating the cipher constructor.
+
+ * acconfig.h (_GCRYPT_IN_LIBGCRYPT): Define it here.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GPH_PROG_DOCBOOK): Removed.
+ (GPH_PROG_DB2ANY): New. Taken from GPH.
+ * configure.in: Use it here.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt. The directory gcrypt has been renamed to src.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ Version 1.1.2 released.
+
+2000-11-13 Werner Koch <wk@gnupg.org>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): VPATH build fix.
+
+2000-10-10 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (dist-hook): Create the version file.
+ * configure.in: Set the libtool version here, removed the need
+ for the version file.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Removed that silly mkdir().
+
+ * configure.in: Changes to allow for Solaris random device.
+ By Nils Ellmenreich.
+ (--with-egd-socket): New.
+
+ * configure.in (GNUPG_HOMEDIR): New.
+
+ * configure.in: Check for fstat64 and fopen64
+
+ * acinclude.m4 (GNUPG_CHECK_FAQPROG): New.
+ * configure.in: Test for this.
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Fix by David Champion.
+
+Tue Aug 22 14:31:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ Version 1.1.1
+
+Fri Aug 18 14:27:14 CEST 2000 Werner Koch <wk@openit.de>
+
+ * agent/: New.
+ * Makefile.am, configure.in: Support for the new directory.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * configure.in (mingw32): Changes to allow for mingw32msvc
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ The big merge between this one and the stable branch 1.0. Still need
+ to merge TNANKS, AUTHORS and such. It probaly does not compile yet.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
+
+ * configure.in: Add check for termio.h, wait unctiosn and sigaction.
+
+ * acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
+
+ * acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gaël Quéri.
+
+ * configure.in (AM_INIT_AUTOMAKE): Use this now. By Gaël.
+
+ * acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
+ GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
+ Contributed by Dave Dykstra.
+ * configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
+
+ * configure.in: Add a test for unisgned long long.
+
+ * configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
+
+ * configure.in: Add check for clock_gettime
+
+ * configure.in (ALL_LINGUAS): Add nl.
+ * configure.in (ALL_LINGUAS): Add Esperanto.
+ * configure.in (ALL_LINGUAS): Add sv and ja.
+
+ * configure.in: Use /usr/local for CFLAGS and LDFLAGS when
+ target is freebsd. By Rémi.
+
+ * configure.in: Do not set development version when the version has
+ a dash in it. Suggested by Dave Dykstra.
+
+ * configure.in: Removed substitution for doc/gph/Makefile.
+ Do all the gcc warning only in maintainer mode.
+
+ * configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
+ Suggested by Alexandre Oliva.
+ (-Wall): Moved the settting of gcc warning options near to the end
+ so that tests don't get confused. Suggested by Paul D. Smith.
+
+ * acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
+ (GNUPG_CHECK_RDYNAMIC): Ditto.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
+ librt. Test suggested by Jeff Long.
+
+ * acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
+ we can't link a test program. This way GNU systems don't need
+ to link against linrt.
+ (GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro. From Tim Mooney.
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
+ DJGPP.
+ (GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
+
+ * acconfig.h (HAVE_MLOCK): Added
+
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
+
+ * configure.in: Now uses the Docbook M4s from GPH.
+
+Mon Jan 31 17:46:35 CET 2000 Werner Koch <wk@>
+
+ * Makefile.am: Re-added tools. By Rémi.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * configure.in: Create a symlink for types.h in gcrypt/.
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * configure.in (g10defs.h): Replaced by gnupg-defs.h
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * jnlib/ : New.
+
+ * configure.in: Do set development version when the version has
+ a dash in it. Suggested by Dave Dykstra.
+
+Thu Dec 9 17:22:27 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * acinclude.m4 (GNUPG_FIX_HDR_VERSION): New.
+ * configure.in: Check and fix the version number of gcrypt/gcrypt.h
+ so that it is always the save as VERSION.
+
+Thu Oct 28 16:17:46 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * Started with development series 1.1 on 1999-10-26
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * README-alpha: New
+
+ * configure.in: Fixed quoting in test for development version.
+
+ * THANKS: Add entries for Michael, Brenno and J Horacio who did
+ very nice Howto documents - I apoligize for forgetting to mention them
+ earlier.
+
+Fri Sep 17 12:56:42 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in: Add "-lcap" when capabilities are requested.
+ Add the conditional CROSS_COMPILING.
+ * Makefile.am: Don't use checks when CROSS_COMPILING.
+
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in (ALL_LINGUAS): Add pt_PT.
+
+ * configure.in: Some tweaks for cross compiling under MingW32
+ * acconfig.h (USE_STATIC_RNDW32): New.
+
+Tue Sep 7 17:08:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * VERSION: Set to 1.0.0.
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * configure.in: Create makefile in doc/gph
+
+ * acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New
+ * configure.in: use the above.
+
+Thu Sep 2 16:40:55 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * VERSION: Set to 0.9.11.
+
+Tue Aug 31 17:20:44 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Minor changes to the OS/2 and Mingw32 system labels.
+ Add a printable name for Hurd.
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Some support for DJGPP (Mark Elbrecht)
+
+Wed Aug 4 10:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.9.10.
+
+Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): remove init of ac_cv_...
+
+ * Makefile.am (DISCLEANFILES): New
+
+Fri Jul 23 13:53:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.9.9.
+
+ * configure.in: Print a notice when rndunix is used.
+
+Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fixed last modification.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Support for libtool.
+ * configure.in: Ditto.
+
+Tue Jun 29 21:44:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (use_local_zlib): The lost dollar is back.
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add EMX case.
+ * configure.in: Another variant of the MX vendor string
+
+ * configure.in (--with-capabilities): Some test code (Remi).
+
+Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Support for HPUX and IRIX.
+ * configure.in (HAVE_DL_SHL_LOAD): New for HPUX (Dave Dykstra).
+
+ * VERSION: Now 0.9.8
+
+Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add test for docbook-to-man
+
+Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_NM_PARSE): Support for {net,free}bsd,
+
+Thu Jun 10 14:18:23 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (ZLIB,GDBM): Check both, header and lib.
+
+Sat Jun 5 15:30:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * pkclist.c (key_present_in_pk_list): New (Michael).
+
+Tue May 25 19:50:32 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (IS_DEVELOPMENT_VERSION): Fixed detection.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): assume yes when
+ cross-compiling.
+
+Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (socket): Fix for Unisys by Katsuhiro Kondou.
+
+Sat May 8 19:28:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * NEWS: Add a marker line which I forgot to do for 0.9.6.
+
+Thu May 6 14:18:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * README: Minor updates
+
+ * VERSION: Now 0.9.6
+
+Thu Apr 8 09:35:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for
+ amiga-openbsd (Peter Reich)
+ (GNUPG_PROG_NM): Ditto
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am (g10defs.h): Removed.
+ * configure.in (AC_OUTPUT_COMMANDS): Create g10defs.h
+
+Sat Mar 20 12:55:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Now 0.9.5
+
+Sun Mar 14 19:34:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (AM_SYS_SYMBOL_UNDERSCORE): Removed because it is
+ now in the latest libtool.
+
+Thu Mar 11 16:39:46 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Removed the need for libtool
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (DLSYM_NEEDS_UNDERSCORE): Replaced.
+ * acinclude.in (AM_SYS_SYMBOL_UNDERSCORE): New.
+
+ * VERSION: Now 0.9.4
+
+Sun Feb 28 19:11:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (dld): Test disabled.
+
+Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * encode.c (encode_simple): temporary fix.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: New option --enable-static-rnd.
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * BUGS: Now we assign bug numbers.
+ * OBUGS: New to keep rack o fixed bugs (CVS only)
+
+Fri Feb 19 18:01:54 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Released 0.9.3
+
+Fri Feb 19 15:49:15 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4: Removed gettext macros.
+
+Tue Feb 16 14:10:02 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in (socket): Check for -lsocket and -lnsl.
+ (osf4): Disable all warnings for DEC's cc.
+ (-Wall): Add more warning options for gcc
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Changed detection of compiler flags.
+ * intl/ : Removed directory
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for freebsd 2.2
+
+ * configure.in: a lot of changes to allow selection of modules.
+ Add support for OS/2.
+
+ * acinclude.m4: add some more caching
+
+ * README: Spelling and grammar corrections (John A. Martin)
+ * INSTALL: Ditto.
+
+Wed Jan 20 21:40:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: --enable-m-guard is now default
+
+Wed Jan 13 12:49:36 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * INSTALL: Applied new information how to build rpms by Fabio Coatti
+ * Makefile.in (gnupg.spec): Changed the names.
+
+Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (m68k-atari-mint): New
+
+Tue Jan 12 09:17:19 CET 1999 Gaël Quéri <gqueri@mail.dotcom.fr>
+
+ * all: Fixed typos all over the place
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add a way to statically link rndunix
+
+Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): New.
+ * configure.in (DYNLOAD_CFLAGS): Use result from CHECK_RDYNAMIC
+
+Wed Dec 23 13:18:14 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * README: Replaced the command overview with a short intro.
+
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * configure.in: Add check for dlopen in libc (Greg Troxel)
+ and a new define
+ * acconfig.h (DLSYM_NEEDS_UNDERSCORE): New.
+
+Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * acinclude.m (GNUPG_CHECK_PIC): New
+ * configure.in, acinclude.m4: Renamed all WK_ to GNUPG_
+
+Tue Dec 8 15:09:29 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * VERSION: Set to 0.4.5
+
+Wed Nov 25 12:38:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (USE_RNDLINUX): New.
+
+Fri Nov 20 19:34:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * VERSION: Released 0.4.4
+
+ * configure.in (try_asm_modules): For option --disable-asm
+
+Tue Nov 10 19:32:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (MPI_SFLAGS): New.
+
+Tue Nov 10 13:44:53 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * ABOUT-NLS: New
+ * configure.in (AC_REVISION): New.
+
+Sun Nov 8 18:20:35 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * VERSION: Set to 0.4.3
+
+Sun Oct 25 19:49:37 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (g10defs.h): New macro GNUPG_DATADIR.
+
+Wed Oct 21 17:24:24 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Removed gettext kludge
+ * acinclude.m4: Add patched AM_WITH_NKS macro
+
+Tue Oct 20 19:03:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Kludge to make AM_GNU_GETTEXT work,
+ changed some macors to more modern versions. Also
+ changeg the all makefiles to remove duplicate ../intl.
+ * acinclude.m4: Removed the gettext stuff, as this
+ already comes with automake now.
+
+Wed Oct 14 12:11:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (NAME_OF_DEV_RANDOM): New.
+ (DYNLINK_MOD_CFLAGS): New.
+
+Thu Oct 8 10:55:15 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (g10defs.h): creates include file
+ * acconfig.h: now includes g10defs.h
+ * configure.in: Removed G10_LOCALEDIR and GNUPG_LIB
+
+Thu Sep 17 18:49:40 1998 Werner Koch (wk@(none))
+
+ * Makefile.am (dist-hook): Now creates RPM file.
+ * scripts/gnupg.spec: New template file for RPMs
+
+Thu Jul 30 19:17:07 1998 Werner Koch (wk@(none))
+
+ * acinclude.h (WK_CHECK_IPC): New
+ * configure.in : Add checks for SysV IPC
+
+Thu Jun 25 11:18:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (--disable-dynload): New.
+
+Wed Jun 10 07:48:59 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * configure.in (GNUPG_LIBDIR): New.
+
+Mon May 25 19:10:59 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (fast_random_poll): fixed syntax bug.
+
+Mon May 11 10:21:31 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (PRINTABLE_OS_NAME): Linux is now GNU/Linux
+
+Tue Apr 14 19:08:05 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * [all files]: Applied Matthew Skala's typo and grammar fixes.
+
+Wed Mar 4 10:32:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (getrusage,gettimeofday): New tests.
+
+Fri Feb 27 13:14:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (--disable-m-guard): New.
+
+Thu Feb 26 17:09:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in, acinclude.m4, intl/, po/: New macros taken
+ from GNOME, switched to automake 1.2f
+
+Thu Feb 26 09:05:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (doc/Makefile): New
+
+Thu Feb 26 07:40:47 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Changed gettext stuff
+
+Wed Feb 25 11:44:10 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * checks/*test : restructured the directory.
+
+Tue Feb 24 15:59:12 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in: Changed the name of the package to GNUPG and
+ chnaged several other names too.
+
+Wed Feb 18 17:36:45 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (checks): New.
+
+Sat Feb 14 15:37:55 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (mpi_config_done): Removed asm links caching.
+
+Sat Feb 14 14:02:20 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in (PRINTABLE_OS_NAME): New.
+ * acconfig.h: Likewise.
+
+Fri Feb 13 19:43:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * configure.in : Fixed zlib stuff
+ * Makefile.am: Likewise
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
+ 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about. Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+ Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
--- /dev/null
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = dist-bzip2
+DISTCHECK_CONFIGURE_FLAGS = --enable-random-daemon \
+ --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
+
+DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
+SUBDIRS = compat mpi cipher random src doc tests
+EXTRA_DIST = autogen.sh README.SVN
+DISTCLEANFILES =
+
+
+# Add all the files listed in "distfiles" files to the distribution,
+# apply version number s to some files and create a VERSION file which
+# we need for the Prereq: patch file trick.
+dist-hook:
+ @set -e; \
+ for file in `cd $(top_srcdir); \
+ find mpi -type f -name distfiles`; do \
+ dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \
+ for i in distfiles `cat $(top_srcdir)/$$file` ; do \
+ ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \
+ || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
+ done ; \
+ done
+ @set -e; \
+ echo "$(VERSION)" > $(distdir)/VERSION
+
+stowinstall:
+ $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/config.h.in \
+ $(top_srcdir)/configure AUTHORS COPYING COPYING.LIB ChangeLog \
+ INSTALL NEWS THANKS TODO compile config.guess config.rpath \
+ config.sub depcomp install-sh ltmain.sh missing mkinstalldirs
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+ { test ! -d "$(distdir)" \
+ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+ && rm -fr "$(distdir)"; }; }
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ACLOCAL_AMFLAGS = -I m4
+AUTOMAKE_OPTIONS = dist-bzip2
+DISTCHECK_CONFIGURE_FLAGS = --enable-random-daemon \
+ --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
+
+DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
+SUBDIRS = compat mpi cipher random src doc tests
+EXTRA_DIST = autogen.sh README.SVN
+DISTCLEANFILES =
+all: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+ @if test ! -f $@; then \
+ rm -f stamp-h1; \
+ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+ else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+ @rm -f stamp-h1
+ cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ ($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+ rm -f stamp-h1
+ touch $@
+
+distclean-hdr:
+ -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ $(am__remove_distdir)
+ test -d "$(distdir)" || mkdir "$(distdir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+ -test -n "$(am__skip_mode_fix)" \
+ || find "$(distdir)" -type d ! -perm -755 \
+ -exec chmod u+rwx,go+rx {} \; -o \
+ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+ || chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ $(am__remove_distdir)
+dist-bzip2: distdir
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+dist-lzma: distdir
+ tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+ $(am__remove_distdir)
+
+dist-xz: distdir
+ tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+ $(am__remove_distdir)
+
+dist-tarZ: distdir
+ tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+ $(am__remove_distdir)
+
+dist-shar: distdir
+ shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+ $(am__remove_distdir)
+
+dist-zip: distdir
+ -rm -f $(distdir).zip
+ zip -rq $(distdir).zip $(distdir)
+ $(am__remove_distdir)
+
+dist dist-all: distdir
+ tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+ tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+ $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ case '$(DIST_ARCHIVES)' in \
+ *.tar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+ *.tar.bz2*) \
+ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+ *.tar.lzma*) \
+ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+ *.tar.xz*) \
+ xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+ *.tar.Z*) \
+ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+ *.shar.gz*) \
+ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+ *.zip*) \
+ unzip $(distdir).zip ;;\
+ esac
+ chmod -R a-w $(distdir); chmod a+w $(distdir)
+ mkdir $(distdir)/_build
+ mkdir $(distdir)/_inst
+ chmod a-w $(distdir)
+ test -d $(distdir)/_build || exit 0; \
+ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+ && am__cwd=`pwd` \
+ && $(am__cd) $(distdir)/_build \
+ && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+ $(DISTCHECK_CONFIGURE_FLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+ distuninstallcheck \
+ && chmod -R a-w "$$dc_install_base" \
+ && ({ \
+ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+ } || { rm -rf "$$dc_destdir"; exit 1; }) \
+ && rm -rf "$$dc_destdir" \
+ && $(MAKE) $(AM_MAKEFLAGS) dist \
+ && rm -rf $(DIST_ARCHIVES) \
+ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+ && cd "$$am__cwd" \
+ || exit 1
+ $(am__remove_distdir)
+ @(echo "$(distdir) archives ready for distribution: "; \
+ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+ @$(am__cd) '$(distuninstallcheck_dir)' \
+ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+ || { echo "ERROR: files left after uninstall:" ; \
+ if test -n "$(DESTDIR)"; then \
+ echo " (check DESTDIR support)"; \
+ fi ; \
+ $(distuninstallcheck_listfiles) ; \
+ exit 1; } >&2
+distcleancheck: distclean
+ @if test '$(srcdir)' = . ; then \
+ echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+ exit 1 ; \
+ fi
+ @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+ || { echo "ERROR: files left in build directory after distclean:" ; \
+ $(distcleancheck_listfiles) ; \
+ exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \
+ ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am am--refresh check check-am clean clean-generic \
+ clean-libtool ctags ctags-recursive dist dist-all dist-bzip2 \
+ dist-gzip dist-hook dist-lzma dist-shar dist-tarZ dist-xz \
+ dist-zip distcheck distclean distclean-generic distclean-hdr \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-recursive uninstall uninstall-am
+
+
+# Add all the files listed in "distfiles" files to the distribution,
+# apply version number s to some files and create a VERSION file which
+# we need for the Prereq: patch file trick.
+dist-hook:
+ @set -e; \
+ for file in `cd $(top_srcdir); \
+ find mpi -type f -name distfiles`; do \
+ dir=`dirname $$file` ; $(mkinstalldirs) $(distdir)/$$dir ; \
+ for i in distfiles `cat $(top_srcdir)/$$file` ; do \
+ ln $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i 2> /dev/null \
+ || cp -p $(top_srcdir)/$$dir/$$i $(distdir)/$$dir/$$i; \
+ done ; \
+ done
+ @set -e; \
+ echo "$(VERSION)" > $(distdir)/VERSION
+
+stowinstall:
+ $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Noteworthy changes in version 1.5.0 (2011-06-29)
+------------------------------------------------
+
+ * New function gcry_kdf_derive implementing OpenPGP S2K algorithms
+ and PBKDF2.
+
+ * Support for WindowsCE.
+
+ * Support for ECDH.
+
+ * Support for OAEP and PSS methods as described by RFC-3447.
+
+ * Fixed PKCS v1.5 code to always return the leading zero.
+
+ * New format specifiers "%M" and "%u" for gcry_sexp_build.
+
+ * Support opaque MPIs with "%m" and "%M" in gcry_sexp_build.
+
+ * New functions gcry_pk_get_curve and gcry_pk_get_param to map ECC
+ parameters to a curve name and to retrieve parameter values.
+
+ * gcry_mpi_cmp applied to opaque values has a defined semantic now.
+
+ * Uses the Intel AES-NI instructions if available.
+
+ * The use of the deprecated Alternative Public Key Interface
+ (gcry_ac_*) will now print compile time warnings.
+
+ * The module register subsystem has been deprecated. This subsystem
+ is not flexible enough and would always require ABI changes to
+ extend the internal interfaces. It will eventually be removed.
+ Please contact us on the gcrypt-devel mailing list to discuss
+ whether you really need this feature or how it can be replaced by
+ an internal plugin mechanism.
+
+ * CTR mode may now be used with data chunks of arbitrary length.
+
+ * Changes also done in 1.4.6 (2010-07-13):
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ * New variants of the TIGER algorithm.
+
+ * New cipher algorithm mode for AES-WRAP.
+
+ * Changes also done in 1.4.5 (2009-12-11):
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ * Fixed minor memory leak in DSA key generation.
+
+ * No more switching to FIPS mode if /proc/version is not readable.
+
+ * Fixed sigill during Padlock detection on old CPUs.
+
+ * Fixed a hang on some W2000 machines.
+
+ * Boosted SHA-512 performance by 30% on ia32 boxes and gcc 4.3;
+ SHA-256 went up by 25%.
+
+ * Interface changes relative to the 1.4.6 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRY_PK_ECDH NEW.
+ gcry_pk_get_curve NEW.
+ gcry_pk_get_param NEW.
+ GCRYCTL_DISABLE_HWF NEW.
+ gcry_kdf_derive NEW.
+ gcry_pk_encrypt EXTENDED: Support OAEP.
+ gcry_pk_decrypt EXTENDED: Support OAEP.
+ gcry_pk_sign EXTENDED: Support PSS.
+ gcry_pk_verify EXTENDED: Support PSS.
+ gcry_sexp_build EXTENDED: Add format specifiers M and u.
+
+ * Interface changes relative to the 1.4.2 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRY_CIPHER_MODE_AESWRAP NEW.
+ GCRY_MD_TIGER1 NEW.
+ GCRY_MD_TIGER2 NEW.
+
+
+Noteworthy changes in version 1.4.4 (2009-01-22)
+------------------------------------------------
+
+ * Publish GCRY_MODULE_ID_USER and GCRY_MODULE_ID_USER_LAST constants.
+ This functionality has been in Libgcrypt since 1.3.0.
+
+ * MD5 may now be used in non-enforced fips mode.
+
+ * Fixed HMAC for SHA-384 and SHA-512 with keys longer than 64 bytes.
+
+ * In fips mode, RSA keys are now generated using the X9.31 algorithm
+ and DSA keys using the FIPS 186-2 algorithm.
+
+ * The transient-key flag is now also supported for DSA key
+ generation. DSA domain parameters may be given as well.
+
+
+Noteworthy changes in version 1.4.3 (2008-09-18)
+------------------------------------------------
+
+ * Try to auto-initialize Libgcrypt to minimize the effect of
+ applications not doing that correctly. This is not a perfect
+ solution but given that many applicationion would totally fail
+ without such a hack, we try to help at least with the most common
+ cases. Folks, please read the manual to learn how to properly
+ initialize Libgcrypt!
+
+ * Auto-initialize the secure memory to 32k instead of aborting the
+ process.
+
+ * Log fatal errors via syslog.
+
+ * Changed the name and the semantics of the fips mode config file.
+
+ * Add convenience macro gcry_fips_mode_active.
+
+ * More self-tests.
+
+ * Documentation cleanups.
+
+
+Noteworthy changes in version 1.4.2 (2008-09-08)
+------------------------------------------------
+
+ * The long missing gcry_mpi_lshift function has been added.
+
+ * RSA key generation now supports a "transient-key" flag.
+
+ * The keygrip computation for ECDSA has been implemented thus ECDSA
+ is now fully supported.
+
+ * A few macros have been replaced by functions for better type
+ checking.
+
+ * The thread initialization structure now carries version
+ information.
+
+ * The manual describes more clearly how to initialize Libgcrypt.
+
+ * The library may now be switched into a FIPS mode.
+
+ * Interface changes relative to the 1.3.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ GCRYCTL_OPERATIONAL_P NEW.
+ GCRYCTL_FIPS_MODE_P NEW.
+ GCRYCTL_FORCE_FIPS_MODE NEW.
+ gcry_cipher_setkey NEW: Replaces macro.
+ gcry_cipher_setiv NEW: Replaces macro.
+ gcry_cipher_setctr NEW: Replaces macro.
+ gcry_mpi_lshift NEW.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.4.1 (2008-04-25)
+------------------------------------------------
+
+ * Fixed a bug introduced by 1.3.1 which led to the comsumption of far
+ too much entropy for the intial seeding.
+
+ * Improved AES performance for CFB and CBC modes.
+
+ * Removed build problems for the Padlock support.
+
+
+Noteworthy changes in version 1.4.0 (2007-12-10)
+------------------------------------------------
+
+ * New configure option --disable-padlock-support which is mostly
+ useful in case of build problems.
+
+
+Noteworthy changes in version 1.3.2 (2007-12-03)
+------------------------------------------------
+
+ * The visibility attribute is now used if supported by the toolchain.
+
+ * The ACE engine of VIA processors is now used for AES-128.
+
+ * The ASN.1 DER template for SHA-224 has been fixed.
+
+
+Noteworthy changes in version 1.3.1 (2007-10-26)
+------------------------------------------------
+
+ * The entire library is now under the LGPL. The helper programs and
+ the manual are under the GPL. Kudos to Peter Gutmann for giving
+ permissions to relicense the rndw32 and rndunix modules.
+
+ * The Camellia cipher is now under the LGPL and included by default.
+
+ * Fixed a bug in the detection of symbol prefixes which inhibited the
+ build of optimzied assembler code on certain systems.
+
+ * Updated the entropy gatherer for W32.
+
+
+Noteworthy changes in version 1.3.0 (2007-05-04)
+------------------------------------------------
+
+ * Changed the way the RNG gets initialized. This allows to keep it
+ uninitialized as long as no random numbers are used. To override
+ this, the new macro gcry_fast_random_poll may be used. It is in
+ general a good idea to spread this macro into the application code
+ to make sure that these polls happen often enough.
+
+ * Made the RNG immune against fork without exec.
+
+ * Reading and writing the random seed file is now protected by a
+ fcntl style file lock on systems that provide this function.
+
+ * Support for SHA-224 and HMAC using SHA-384 and SHA-512.
+
+ * Support for the SEED cipher.
+
+ * Support for the Camellia cipher. Note that Camellia is disabled by
+ default, and that enabling it changes the license of libgcrypt from
+ LGPL to GPL.
+
+ * Support for OFB encryption mode.
+
+ * gcry_mpi_rshift does not anymore truncate the shift count.
+
+ * Reserved algorithm ranges for use by applications.
+
+ * Support for DSA2.
+
+ * The new function gcry_md_debug should be used instead of the
+ gcry_md_start_debug and gcry_md_stop_debug macros.
+
+ * New configure option --enable-random-daemon to support a system
+ wide random daemon. The daemon code is experimental and not yet
+ very well working. It will eventually allow to keep a global
+ random pool for the sake of short living processes.
+
+ * Non executable stack support is now used by default on systems
+ supporting it.
+
+ * Support for Microsoft Windows.
+
+ * Assembler support for the AMD64 architecture.
+
+ * New configure option --enable-mpi-path for optimized builds.
+
+ * Experimental support for ECDSA; should only be used for testing.
+
+ * New control code GCRYCTL_PRINT_CONFIG to print the build
+ configuration.
+
+ * Minor changes to some function declarations. Buffer arguments are
+ now typed as void pointer. This should not affect any compilation.
+ Fixed two bugs in return values and clarified documentation.
+
+ * Interface changes relative to the 1.2.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_fast_random_poll NEW
+ gcry_md_debug NEW
+ gcry_sexp_nth_string NEW
+ GCRY_MD_SHA224 NEW
+ GCRY_PK_USAGE_CERT NEW
+ GCRY_PK_USAGE_AUTH NEW
+ GCRY_PK_USAGE_UNKN NEW
+ GCRY_PK_ECDSA NEW
+ GCRY_CIPHER_SEED NEW
+ GCRY_CIPHER_CAMELLIA128 NEW
+ GCRY_CIPHER_CAMELLIA192 NEW
+ GCRY_CIPHER_CAMELLIA256 NEW
+ GCRYCTL_FAKED_RANDOM_P NEW
+ GCRYCTL_PRINT_CONFIG NEW
+ GCRYCTL_SET_RNDEGD_SOCKET NEW.
+ gcry_mpi_scan CHANGED: Argument BUFFER is now void*.
+ gcry_pk_algo_name CHANGED: Returns "?" instead of NULL.
+ gcry_cipher_algo_name CHANGED: Returns "?" instead of "".
+ gcry_pk_spec_t CHANGED: Element ALIASES is now const ptr.
+ gcry_md_write_t CHANGED: Argument BUF is now a const void*.
+ gcry_md_ctl CHANGED: Argument BUFFER is now void*.
+ gcry_cipher_encrypt CHANGED: Arguments IN and OUT are now void*.
+ gcry_cipher_decrypt CHANGED: Arguments IN and OUT are now void*.
+ gcry_sexp_sprint CHANGED: Argument BUFFER is now void*.
+ gcry_create_nonce CHANGED: Argument BUFFER is now void*.
+ gcry_randomize CHANGED: Argument BUFFER is now void*.
+ gcry_cipher_register CHANGED: Argument ALGORITHM_ID is now int*.
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.2.0 (2004-04-15)
+------------------------------------------------
+
+ * First stable release.
+
+
+Noteworthy changes in version 1.1.94 (2004-03-29)
+-------------------------------------------------
+
+ * The support for multi-threaded users goes into its third
+ incarnation. We removed compile time support for thread libraries.
+ To support the thread library of your choice, you have to set up
+ callback handlers at initialization time. New data structures, a
+ new control command, and default initializers are provided for this
+ purpose.
+
+ * Interface changes relative to the 1.1.93 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+libgcrypt-config --thread OBSOLETE
+libgcrypt-pth.la REMOVED
+libgcrypt-pthread.la REMOVED
+GCRYCTL_SET_THREAD_CBS NEW
+struct gcrypt_thread_cbs NEW
+enum gcry_thread_option NEW
+GCRY_THREAD_OPTION_PTH_IMPL NEW
+GCRY_THREAD_OPTION_PTHREAD_IMPL NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.93 (2004-03-06)
+-------------------------------------------------
+
+ * The automatic thread library detection has finally been removed.
+ From now on, only linking explicitely to libgcrypt, libgcrypt-pth
+ or libgcrypt-pthread is supported.
+
+Noteworthy changes in version 1.1.92 (2004-02-20)
+-------------------------------------------------
+
+ * Minor bug fixes.
+
+ * Included a limited implementation of RFC2268.
+
+ * Changed API of the gcry_ac_ functions. Only a very few programs
+ should be affected by this.
+
+ * Interface changes relative to the 1.1.91 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRY_CIPHER_RFC2268_40 NEW.
+gcry_ac_data_set CHANGED: New argument FLAGS.
+gcry_ac_data_get_name CHANGED: New argument FLAGS.
+gcry_ac_data_get_index CHANGED: New argument FLAGS.
+gcry_ac_key_pair_generate CHANGED: New and reordered arguments.
+gcry_ac_key_test CHANGED: New argument HANDLE.
+gcry_ac_key_get_nbits CHANGED: New argument HANDLE.
+gcry_ac_key_get_grip CHANGED: New argument HANDLE.
+gcry_ac_data_search REMOVED.
+gcry_ac_data_add REMOVED.
+GCRY_AC_DATA_FLAG_NO_BLINDING REMOVED.
+GCRY_AC_FLAG_NO_BLINDING NEW: Replaces above.
+
+
+Noteworthy changes in version 1.1.91 (2003-12-19)
+-------------------------------------------------
+
+ * Code cleanups and minor bug fixes.
+
+
+Noteworthy changes in version 1.1.90 (2003-11-14)
+-------------------------------------------------
+
+ * The use of the GCRY_WEAK_RANDOM level is now deprecated in favor of
+ the new gcry_create_nonce function.
+
+ * gcry_sexp_build now supports a "%b" format to include a memory buffer.
+
+ * Minor configuration fixes.
+
+ * Interface changes relative to the 1.1.44 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_create_nonce NEW
+gcry_sexp_build ENHANCED
+
+
+Noteworthy changes in version 1.1.44 (2003-10-31)
+-------------------------------------------------
+
+ * Bug fixes and more code cleanups.
+
+ * Enhanced the prime API.
+
+ * Interface changes relative to the 1.1.43 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_prime_group_generator NEW
+gcry_prime_release_factors NEW
+
+
+Noteworthy changes in version 1.1.43 (2003-09-04)
+-------------------------------------------------
+
+ * Bug fixes and internal code cleanups.
+
+ * Support for the Serpent cipher algorithm.
+
+ * Interface changes relative to the 1.1.42 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_prime_generate NEW
+gcry_prime_check NEW
+
+
+Noteworthy changes in version 1.1.42 (2003-07-31)
+-------------------------------------------------
+
+ * Major API cleanup. Applications need to be converted to the new
+ API. See README.apichanges for hints on how to do that. Backward
+ compatibility is provided where it was possible without too much
+ effort and did not collide with the overall sanitization effort.
+ However, this is only for ease of transition. NO DEPRECATED
+ FUNCTION OR DATA TYPE IS CONSIDERED A PART OF THE API OR ABI AND
+ WILL BE DROPPED IN THE FUTURE WITHOUT CHANGING THE SONAME OF THE
+ LIBRARY.
+
+ * If gcrypt.h is included in sources compiled by GCC 3.1 or later,
+ deprecated attributes will warn about use of obsolete functions and
+ type definitions. You can suppress these warnings by passing
+ -Wno-deprecated-declarations to the gcc command.
+
+ * gcry_check_version must be called from now on to initialize the
+ library, it is not longer optional.
+
+ * Removed `libgcrypt errno' concept.
+
+ * Libgcrypt depends on libgpg-error, a library that provides error
+ codes and according functions for all GnuPG components. Functions
+ that used to return error codes asa `int' have been changed to
+ return a code of type `gcry_error_t'. All GCRYERR_* error symbols
+ have been removed, since they are now contained in libgpg-error
+ (GPG_ERR_*). All functions and types in libgpg-error have also been
+ wrapped in Libgcrypt. The new types are gcry_err_code_t and
+ gcry_err_source_t. The new functions are gcry_err_code,
+ gcry_err_source, gcry_error, gcry_err_make, gcry_error_from_errno,
+ gcry_err_make_from_errno, gcry_err_code_from_errno,
+ gcry_err_code_to_errno, gcry_strsource.
+
+ * New function gcry_mpi_dump to help in debugging.
+
+ * Added alternative interface for asymmetric cryptography.
+
+ * CRC-32, CRC-32 a'la RFC 1510, CRC-24 a'la RFC 2440 are now
+ supported.
+
+ * SHA-256, SHA-384 and SHA-512 are now supported.
+
+ * 128 bit Twofish is now supported.
+
+ * The random module won't print the "not enough random bytes
+ available" anymore. A new progress status is issued instead.
+
+ * CBC-MAC for block ciphers is now supported, by using a
+ GCRY_CIPHER_CBC_MAC cipher flag.
+
+ * CTR mode for block ciphers is now supported.
+
+ * The public RSA exponent can now be specified in key generation.
+
+ * RSA blinding is now supported and is used automatically for RSA
+ decryption. It can be explicitely disabled by using the
+ `no-blinding' symbol in the `flags' S-Expression or by using the
+ GCRY_AC_FLAG_DATA_NO_BLINDING flag when using the ac interface.
+
+ * gcry_sexp_canon_len does not use a `historically encoded' error
+ code anymore.
+
+
+ * Interface changes relative to the 1.1.12 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRY_MPI DEPRECATED; Use: gcry_mpi_t
+GcryMPI DEPRECATED; Use: gcry_mpi_t
+GCRY_SEXP DEPRECATED; Use: gcry_sexp_t
+GcrySexp DEPRECATED; Use: gcry_sexp_t
+GCRY_CIPHER_HD DEPRECATED; Use: gcry_cipher_hd_t
+GcryCipherHd DEPRECATED; Use: gcry_cipher_hd_t
+GCRY_MD_HD DEPRECATED; Use: gcry_md_hd_t
+GcryMDHd DEPRECATED; Use: gcry_md_hd_t
+gcry_error_t NEW
+gcry_err_code_t NEW
+gcry_err_source_t NEW
+gcry_err_make NEW
+gcry_error NEW
+gcry_err_code NEW
+gcry_err_source NEW
+gcry_err_code_from_errno NEW
+gcry_err_code_to_errno NEW
+gcry_err_make_from_errno NEW
+gcry_error_from_errno NEW
+gcry_strsource NEW
+GCRYERR_{some error code} REMOVED; Use GPG_ERR_*
+ from libgpg-error instead.
+gcry_errno REMOVED
+gcry_sexp_canon_len CHANGED
+gcry_sexp_build_array NEW
+gcry_mpi_scan CHANGED: New argument to separate in/out args.
+gcry_mpi_print CHANGED: Ditto.
+gcry_mpi_dump NEW
+gcry_cipher_open CHANGED
+gcry_cipher_reset NEW
+gcry_cipher_register NEW
+gcry_cipher_unregister NEW
+gcry_cipher_list NEW
+gcry_cipher_algo_keylen REPLACED macro with function.
+gcry_cipher_algo_blklen REPLACED macro with function.
+gcry_pk_register NEW
+gcry_pk_unregister NEW
+gcry_pk_list NEW
+gcry_pk_decrypt ENHANCED: Allows flag to return
+ complete S-expression.
+gcry_md_open CHANGED
+gcry_md_copy CHANGED
+gcry_md_is_enabled NEW
+gcry_md_is_secure NEW
+gcry_md_register NEW
+gcry_md_unregister NEW
+gcry_md_list NEW
+gcry_ac_data_t NEW
+gcry_ac_key_t NEW
+gcry_ac_key_pair_t NEW
+gcry_ac_handle_t NEW
+gcry_ac_key_spec_rsa_t NEW
+gcry_ac_data_new NEW
+gcry_ac_data_destroy NEW
+gcry_ac_data_set NEW
+gcry_ac_data_copy NEW
+gcry_ac_data_length NEW
+gcry_ac_data_get_name NEW
+gcry_ac_data_get_index NEW
+gcry_ac_data_clear NEW
+gcry_ac_open NEW
+gcry_ac_close NEW
+gcry_ac_key_init NEW
+gcry_ac_key_pair_generate NEW
+gcry_ac_key_pair_extract NEW
+gcry_ac_key_data_get NEW
+gcry_ac_key_test NEW
+gcry_ac_key_get_nbits NEW
+gcry_ac_key_get_grip NEW
+gcry_ac_key_destroy NEW
+gcry_ac_key_pair_destroy NEW
+gcry_ac_data_encrypt NEW
+gcry_ac_data_decrypt NEW
+gcry_ac_data_sign NEW
+gcry_ac_data_verify NEW
+gcry_ac_id_to_name NEW
+gcry_ac_name_to_id NEW
+gcry_handler_progress_t NEW
+gcry_handler_alloc_t NEW
+gcry_handler_secure_check_t NEW
+gcry_handle_realloc_t NEW
+gcry_handler_free_t NEW
+gcry_handler_no_mem_t NEW
+gcry_handler_error_t NEW
+gcry_handler_log_t NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.12 (2003-01-20)
+-------------------------------------------------
+
+ * gcry_pk_sign, gcry_pk_verify and gcry_pk_encrypt can now handle an
+ optional pkcs1 flags parameter in the S-expression. A similar flag
+ may be passed to gcry_pk_decrypt but it is only syntactically
+ implemented.
+
+ * New convenience macro gcry_md_get_asnoid.
+
+ * There is now some real stuff in the manual.
+
+
+Noteworthy changes in version 1.1.11 (2002-12-21)
+-------------------------------------------------
+
+ * Don't export internal symbols anymore (currently only for GNU systems)
+
+ * New algorithm: MD4
+
+ * Implemented ciphertext stealing.
+
+ * Smaller bugs fixes and a few new OIDs.
+
+ * Interface changes relative to the 1.1.8 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_cipher_cts NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+Noteworthy changes in version 1.1.10 (2002-09-20)
+-------------------------------------------------
+
+ * Fixed shared library builds for i386, PPC and Sparc.
+
+ * Added simple benchmark tool.
+
+ * Replaced the internal mutexes by code which automatically adapts to
+ the used threading library. Currently Pth and Pthread are
+ supported. For non-ELF systems the GNU toolchain is now required..
+
+ * Added untested support to build Windows DLLs.
+
+Noteworthy changes in version 1.1.9 (2002-08-23)
+------------------------------------------------
+
+ * Support for plain old DES.
+
+
+Noteworthy changes in version 1.1.8 (2002-06-25)
+------------------------------------------------
+
+ * Minor cleanups and exported a few new functions.
+
+ * Interface changes relative to the 1.1.7 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gcry_mpi_div NEW
+gcry_mpi_mod NEW
+gcry_mpi_invm NEW
+gcry_mpi_swap NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.7 (2002-05-21)
+------------------------------------------------
+
+* Libgcrypt is now distributed under the terms of the GNU Lesser
+ General Public License; see the README file for details.
+
+* It is possible to use libgcrypt w/o intialized secure memory.
+
+* Libgcrypt should now be thread safe after the initialization.
+ gcry_control (GCRYCRL_INITIALIZATION_FINISHED,NULL,0) should have
+ been called before creating additional threads.
+
+ * Interface changes relative to the 1.1.6 release:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+GCRYCTL_DISABLE_INTERNAL_LOCKING NEW
+GCRYCTL_DISABLE_SECMEM NEW
+GCRYCTL_INITIALIZATION_FINISHED NEW
+GCRYCTL_INITIALIZATION_FINISHED_P NEW
+GCRYCTL_ANY_INITIALIZATION_P NEW
+gcry_strdup NEW
+gcry_sexp_create NEW
+gcry_sexp_new NEW
+gcry_set_progress_handler NEW
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Noteworthy changes in version 1.1.6 (2002-02-07)
+------------------------------------------------
+
+ * Enhanced the S-expression conversion functions.
+
+Noteworthy changes in version 1.1.5 (2001-12-18)
+------------------------------------------------
+
+ * gcry_{cipher,md}_map_name are now able to map stringified object IDs.
+
+ * New functions gcry_sexp_canon_len and gcry_cipher_mode_from_oid.
+
+ * Closed some memory leaks.
+
+
+Noteworthy changes in version 1.1.4 (2001-08-03)
+------------------------------------------------
+
+ * Arcfour does now work.
+
+ * Some minor fixes.
+
+ * Added a first test program
+
+ * Migrated to autoconf 2.52.
+
+
+Noteworthy changes in version 1.1.3 (2001-05-31)
+------------------------------------------------
+
+ * First release of Libgcrypt which is a result of splitting GnuPG
+ into into libgcrypt and GnuPG.
+
+
+Copyright 2001, 2002, 2003, 2004, 2007, 2008,
+ 2009, 2011 Free Software Foundation, Inc.
+
+This file is free software; as a special exception the author gives
+unlimited permission to copy and/or distribute it, with or without
+modifications, as long as this notice is preserved.
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+ Libgcrypt - The GNU Crypto Library
+ ------------------------------------
+ Version 1.5
+
+ Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,
+ 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+ Overview
+ --------
+
+ Libgcrypt is a general purpose crypto library based on the code
+ used in GnuPG. Libgcrypt depends on the library `libgpg-error',
+ which must be installed correctly before Libgcrypt is to be built.
+ Libgcrypt is distributed under the LGPL, see the section "License"
+ below for details.
+
+
+ Build Instructions
+ ------------------
+
+ The download canonical location for libgcrypt is:
+
+ ftp://ftp.gnupg.org/gcrypt/libgcrypt/
+
+ To build libgcrypt you need libgpg-error:
+
+ ftp://ftp.gnupg.org/gcrypt/libgpg-error/
+
+ You should get the latest versions of course.
+
+ After building and installing the libgpg-error package, you may
+ continue with Libgcrypt installation As with allmost all GNU
+ packages, you just have to do
+
+ ./configure
+ make
+ make check
+ make install
+
+ The "make check" is not required but a good idea to see whether
+ the library works as expected. The check takes some while and
+ prints some benchmarking results. Before doing "make install" you
+ probably need to become root.
+
+ To build libgcrypt for Microsoft Windows, you need to have the
+ mingw32 cross-building toolchain installed. Instead of running a
+ plain configure you use
+
+ ./autogen.sh --build-w32
+ make
+ make install
+
+ By default this command sequences expectsd a libgpg-error
+ installed below $HOME/w32root and installs libgcrypt to that
+ directory too. See the autogen.sh code for details.
+
+ The documentation is available as an Info file (gcrypt.info). To
+ build documentation in PDF, run this:
+
+ cd doc
+ make pdf
+
+
+
+ Mailing List
+ ------------
+
+ You may want to join the developer's mailing list
+ gcrypt-devel@gnupg.org by sending mail with a subject of
+ "subscribe" to gcrypt-devel-request@gnupg.org. An archive of this
+ list is available at http://lists.gnupg.org .
+
+
+ Configure options
+ -----------------
+ Here is a list of configure options which are sometimes useful
+ for installation.
+
+ --enable-m-guard
+ Enable the integrated malloc checking code. Please
+ note that this feature does not work on all CPUs
+ (e.g. SunOS 5.7 on UltraSparc-2) and might give
+ you a bus error.
+
+ --disable-asm
+ Do not use assembler modules. It is not possible
+ to use this on some CPU types.
+
+ --enable-ld-version-script
+ Libgcrypt tries to build a library where internal
+ symbols are not exported. This requires support
+ from ld and is currently enabled for a few OSes.
+ If you know that your ld supports the so called
+ ELF version scripts, you can use this option to
+ force its use. OTOH, if you get error message
+ from the linker, you probably want to use this
+ option to disable the use of version scripts.
+ Note, that you should never ever use an
+ undocumented symbol or one which is prefixed with
+ an underscore.
+
+ --enable-ciphers=list
+ --enable-pubkey-ciphers=list
+ --enable-digests=list
+ If not otherwise specified, all algorithms
+ included in the libgcrypt source tree are built.
+ An exception are algorithms, which depend on
+ features not provided by the system, like 64bit
+ data types. With these switches it is possible
+ to select exactly those algorithm modules, which
+ should be built. The algorithms are to be
+ separated by spaces, commas or colons. To view
+ the list used with the current build the program
+ tests/version may be used.
+
+ --disable-endian-check
+ Don't let configure test for the endianness but
+ try to use the OS provided macros at compile
+ time. This is helpful to create OS X fat binaries.
+
+ --enable-random-daemon
+ Include support for a global random daemon and
+ build the daemon. This is an experimental feature.
+
+ --enable-mpi-path=EXTRA_PATH
+ Prepend EXTRA_PATH to list of CPU specific
+ optimizations. For example, if you want to add
+ optimizations forn a Intel Pentium 4 compatible
+ CPU, you may use
+ --enable-mpi-path=pentium4/sse2:pentium4/mmx
+ Take care: The generated library may crash on
+ non-compatible CPUs.
+
+ --enable-random=NAME
+ Force the use of the random gathering module
+ NAME. Default is either to use /dev/random or
+ the auto mode. Possible values for NAME are:
+ egd - Use the module which accesses the
+ Entropy Gathering Daemon. See the webpages
+ for more information about it.
+ unix - Use the standard Unix module which does not
+ have a very good performance.
+ linux - Use the module which accesses /dev/random.
+ This is the first choice and the default one
+ for GNU/Linux or *BSD.
+ auto - Compile linux, egd and unix in and
+ automagically select at runtime.
+
+ --enable-hmac-binary-check
+ Include support to check the binary at runtime
+ against a HMAC checksum. This works only in FIPS
+ mode and on systems providing the dladdr function.
+
+ --disable-padlock-support
+ Disable support for the PadLock engine of VIA
+ processors. The default is to use PadLock if
+ available. Try this if you get problems with
+ assembler code.
+
+ --disable-aesni-support
+ Disable support for the AES-NI instructions of
+ newer Intel CPUs. The default is to use AES-NI
+ if available. Try this if you get problems with
+ assembler code.
+
+ --disable-O-flag-munging
+ Some code is too complex for some compilers while
+ in higher optimization modes, thus the compiler
+ invocation is modified to use a lower
+ optimization level. Usually this works very well
+ but on some platforms these rules break the
+ invocation. This option may be used to disable
+ the feature under the assumption that either good
+ CFLAGS are given or the compiler can grok the code.
+
+
+
+
+ Build Problems
+ --------------
+
+ We can't check all assembler files, so if you have problems
+ assembling them (or the program crashes) use --disable-asm with
+ ./configure. If you opt to delete individual replacement files in
+ hopes of using the remaining ones, be aware that the configure
+ scripts may consider several subdirectories to get all available
+ assembler files; be sure to delete the correct ones. Never delete
+ udiv-qrnnd.S in any CPU directory, because there may be no C
+ substitute (in mpi/genereic). Don't forget to delete
+ "config.cache" and run "./config.status --recheck". We got a few
+ reports about problems using versions of gcc earlier than 2.96
+ along with a non-GNU assembler (as). If this applies to your
+ platform, you can either upgrade gcc to a more recent version, or
+ use the GNU assembler.
+
+ Some make tools are broken - the best solution is to use GNU's
+ make. Try gmake or grab the sources from a GNU archive and
+ install them.
+
+ Specific problems on some machines:
+
+ * IBM RS/6000 running AIX
+
+ Due to a change in gcc (since version 2.8) the MPI stuff may
+ not build. In this case try to run configure using:
+ CFLAGS="-g -O2 -mcpu=powerpc" ./configure
+
+ * SVR4.2 (ESIX V4.2 cc)
+
+ Due to problems with the ESIX as(1), you probably want to do:
+ CFLAGS="-O -K pentium" ./configure --disable-asm
+
+ * SunOS 4.1.4
+
+ ./configure ac_cv_sys_symbol_underscore=yes
+
+ * Sparc64 CPUs
+
+ We have reports about failures in the AES module when
+ compiling using gcc (e.g. version 4.1.2) and the option -O3;
+ using -O2 solves the problem.
+
+
+ License
+ -------
+
+ The library is distributed under the terms of the GNU Lesser
+ General Public License (LGPL); see the file COPYING.LIB for the
+ actual terms. The helper programs (e.g. gcryptrnd and getrandom)
+ as well as the documentation are distributed under the terms of
+ the GNU General Public License (GPL); see the file COPYING for the
+ actual terms.
+
+ This library used to be available under the GPL - this was changed
+ with version 1.1.7 with the rationale that there are now many free
+ crypto libraries available and many of them come with capabilities
+ similar to Libcrypt. We decided that to foster the use of
+ cryptography in Free Software an LGPLed library would make more
+ sense because it avoids problems due to license incompatibilities
+ between some Free Software licenses and the GPL.
+
+ Please note that in many cases it is better for a library to be
+ licensed under the GPL, so that it provides an advantage for free
+ software projects. The Lesser GPL is so named because it does
+ less to protect the freedom of the users of the code that it
+ covers. See http://www.gnu.org/philosophy/why-not-lgpl.html for
+ more explanation.
+
+
+ Contact
+ -------
+
+ See the file AUTHORS.
+
+ Commercial grade support for Libgcrypt is available; please see
+ http://www.gnupg.org/service.html .
+
+
+ This file is Free Software; as a special exception the authors gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved. For conditions
+ of the whole package, please see the file COPYING. This file is
+ distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY, to the extent permitted by law; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+If you are building from CVS, run the script
+
+./autogen.sh
+
+first, to make sure that you have all the necessary maintainer tools
+are installed and to build the actual configuration files. Then run
+
+./configure --enable-maintainer-mode
+
+followed by the usual make.
+
+If autogen.sh complains about insufficient versions of the required
+tools, or the tools are not installed, you may use environment
+variables to override the default tool names:
+
+ AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake
+ package. For example
+ AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
+ uses "automake-1.7" and "aclocal-1.7.
+ AUTOMAKE_PREFIX is used as a prefix for all tools from the automake
+ page and may be combined with AUTOMAKE_SUFFIX. e.g.:
+ AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh
+ uses "automake" and "aclocal" in the /usr/foo/bin
+ directory.
+ AUTOCONF_SUFFIX is used as a suffix for all tools from the automake
+ package
+ AUTOCONF_PREFIX is used as a prefix for all tools from the automake
+ package
+ GETTEXT_SUFFIX is used as a suffix for all tools from the gettext
+ package
+ GETTEXT_PREFIX is used as a prefix for all tools from the gettext
+ package
+
+It is also possible to use the variable name AUTOMAKE, AUTOCONF,
+ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name
+of the programs to run. It is however better to use the suffix and
+prefix forms as described above because that does not require
+knowledge about the actual tools used by autgen.sh.
+
+
+Please don't use autopoint, libtoolize or autoreconf unless you are
+the current maintainer and want to update the standard configuration
+files. All those files should be in the CVS and only updated manually
+if the maintainer decides that newer versions are required. The
+maintainer should also make sure that the required version of automake
+et al. are properly indicated at the top of configure.ac and take care
+to copy the files and not merely use symlinks.
+
+
+
+
--- /dev/null
+Libgcrypt is based on the GnuPG code. Here is a list of people, who
+helped in GnuPG and Libgcrypt development. Please help us to keep it
+complete and free of errors.
+
+Albert Chin china at thewrittenword com
+Allan Clark allanc@sco.com
+Anand Kumria wildfire@progsoc.uts.edu.au
+Andreas Metzler ametzler at downhill.at.eu.org
+Ariel T Glenn ariel@columbia.edu
+Aurelien Jarno aurel32 at debian.org
+Ben Hutchings ben decadent org uk
+Bodo Moeller Bodo_Moeller@public.uni-hamburg.de
+Brenno de Winter brenno@dewinter.com
+Brian Moore bem@cmc.net
+Brian Warner warner@lothar.com
+Brieuc Jeunhomme bbp@via.ecp.fr
+Bryan Fullerton bryanf@samurai.com
+Caskey L. Dickson caskey@technocage.com
+Cees van de Griend cees-list@griend.xs4all.nl
+Charles Levert charles@comm.polymtl.ca
+Christian Biere christianbiere@gmx.de
+Christian Grothoff christian at grothoff org
+Christian von Roques roques@pond.sub.org
+Christopher Oliver oliver@fritz.traverse.net
+Christian Recktenwald chris@citecs.de
+Daiki Ueno ueno at unixuser org
+Dan Fandrich dan at coneharvesters com
+Daniel Eisenbud eisenbud@cs.swarthmore.edu
+Daniel Koening dan@mail.isis.de
+David Ellement ellement@sdd.hp.com
+Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de
+Dirk Lattermann dlatt@t-online.de
+Dirk Stoecker gcrypt@dstoecker.de
+Ed Boraas ecxjo@esperanto.org
+Elie De Brauwer elie@de-brauwer.be
+Enzo Michelangeli em@MailAndNews.com
+Ernst Molitor ernst.molitor@uni-bonn.de
+Fabian Keil fk at fabiankeil de
+Fabio Coatti cova@felix.unife.it
+Felix von Leitner leitner@amdiv.de
+Frank Heckenbach heckenb@mi.uni-erlangen.de
+Frank Stajano frank.stajano@cl.cam.ac.uk
+Gabriele Monti psicus78 gmail com
+Gaël Quéri gqueri@mail.dotcom.fr
+Gregor Riepl seto-kun@freesurf.ch
+Gerlinde Klaes gk@u64.de
+Greg Louis glouis@dynamicro.on.ca
+Greg Troxel gdt@ir.bbn.com
+Gregory Steuck steuck@iname.com
+Geoff Keating geoffk@ozemail.com.au
+Harald Denker harry@hal.westfalen.de
+Hendrik Buschkamp buschkamp@rheumanet.org
+Holger Schurig holger@d.om.org
+Hugh Daniel hugh@toad.com
+Ian McKellar imckellar@harvestroad.com.au
+Ian Peters itp@ximian.com
+Janusz A. Urbanowicz alex@bofh.torun.pl
+James Troup james@nocrew.org
+Jean-loup Gailly gzip@prep.ai.mit.edu
+Jeff Johnson jbj@redhat.com
+Jens Bachem bachem@rrz.uni-koeln.de
+J Horacio MG homega@ciberia.es
+Joachim Backes backes@rhrk.uni-kl.de
+Jordi Mallach jordi@sindominio.net
+John A. Martin jam@jamux.com
+Johnny Teveßen j.tevessen@gmx.de
+Jörg Schilling schilling@fokus.gmd.de
+Jun Kuriyama kuriyama@sky.rim.or.jp
+Karl Fogel kfogel@guanabana.onshore.com
+Karsten Thygesen karthy@kom.auc.dk
+Katsuhiro Kondou kondou@nec.co.jp
+Kazu Yamamoto kazu@iijlab.net
+Lars Kellogg-Stedman lars@bu.edu
+Lee Fisher blibbet at gmail dot com
+Marco d'Itri md@linux.it
+Mark Adler madler@alumni.caltech.edu
+Mark Elbrecht snowball3@bigfoot.com
+Markus Friedl Markus.Friedl@informatik.uni-erlangen.de
+Matthias Urlichs smurf@smurf.noris.de
+Martin Kahlert martin.kahlert@provi.de
+Martin Hamilton
+Martin Schulte schulte@thp.uni-koeln.de
+Matthew Skala mskala@ansuz.sooke.bc.ca
+Max Kellermann max@duempel.org
+Max Valianskiy maxcom@maxcom.ml.org
+Michael Fischer v. Mollard mfvm@gmx.de
+Michael Roth mroth@nessie.de
+Michael Sobolev mss@despair.transas.com
+Michele Baldessari michele@pupazzo.org
+Modestas Vainius geromanas@mailas.com
+Neil Dunbar neil.dunbar at pobox.com
+Neil Spring nspring@cs.washington.edu
+Newton Hammet newton@hammet.net
+Nicolas Graner Nicolas.Graner@cri.u-psud.fr
+NIIBE Yutaka gniibe@chroot.org
+Niklas Hernaeus
+Nikolay Sturm sturm@sec.informatik.tu-darmstadt.de
+Nikos Mavroyanopoulos nmav@hellug.gr
+Nimrod Zimerman zimerman@forfree.at
+N J Doye nic@niss.ac.uk
+Oliver Haakert haakert@hsp.de
+Oskari Jääskeläinen f33003a@cc.hut.fi
+Paul D. Smith psmith@baynetworks.com
+Philippe Laliberte arsphl@oeil.qc.ca
+Peter Gutmann pgut001@cs.auckland.ac.nz
+QingLong qinglong@bolizm.ihep.su
+Rafael Ávila de Espíndola rafael.espindola@gmail.com
+Rafaël Carré funman@videolan.org
+Ralf Fassel ralf@akutech.de
+Ralf Hildebrandt Ralf.Hildebrandt@innominate.com
+Ralf Schneider ralf@tapfere-schneiderleins.de
+Ralph Gillen gillen@theochem.uni-duesseldorf.de
+Rami Lehti Rami.Lehti@finland.sun.com
+Randolph Chung tausq@debian.org
+Randy mcclellr@oit.edu
+Rat ratinox@peorth.gweep.net
+Reinhard Wobst R.Wobst@ifw-dresden.de
+Rémi Guyomarch rguyom@mail.dotcom.fr
+Reuben Sumner rasumner@wisdom.weizmann.ac.il
+Richard Outerbridge outer@interlog.com
+Roddy Strachan roddy@satlink.com.au
+Roland Rosenfeld roland@spinnaker.rhein.de
+Ross Golder rossigee@bigfoot.com
+Serge Munhoven munhoven@mema.ucl.ac.be
+Sergi Blanch i Torné sergi at calcurco cat
+Simon Josefsson jas@extundo.com
+SL Baur steve@xemacs.org
+Stephan Austermuehle au@hcsd.de
+Stephan Müller smueller at atsec com
+Stephane Corthesy stephane@sente.ch
+Stefan Karrmann S.Karrmann@gmx.net
+Stefan Keller dres@cs.tu-berlin.de
+Steffen Ullrich ccrlphr@xensei.com
+Steffen Zahn zahn@berlin.snafu.de
+Steven Bakker steven@icoe.att.com
+Susanne Schultz schultz@hsp.de
+Szakats Istvan szaki.ms@gmail.com
+Thiago Jung Bauermann jungmann@cwb.matrix.com.br
+Thomas Roessler roessler@guug.de
+Tom Holroyd tomh@po.crl.go.jp
+Tom Spindler dogcow@home.merit.edu
+Tom Zerucha tzeruch@ceddec.com
+Tomas Fasth tomas.fasth@twinspot.net
+Tommi Komulainen Tommi.Komulainen@iki.fi
+Thomas Mikkelsen tbm@image.dk
+Ulf Möller 3umoelle@informatik.uni-hamburg.de
+Umberto Salsi salsi@icosaedro.it
+Uoti Urpala
+Urko Lusa ulusa@euskalnet.net
+Victor Stinner haypo@inl.fr
+Walter Koch koch@u32.de
+Werner Koch wk@gnupg.org
+Wim Vandeputte wim@kd85.com
+ nbecker@hns.com
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003,
+ 2009, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+# What's left to do -*- org -*-
+
+* Next API break:
+** gcry_ac_io_t
+ Remove use of anonymous union.
+** gcry_ac
+ Consider to remove it.
+
+* udiv-qrnbd.o should get build as *.lo [HPUX]
+
+* Allow operation using RSA keys consisting of the OpenSSL keys.
+ This requires the introduction of a parameter names (say) U which
+ is calculated according to OpenSSL/PKCS#1 rules.
+
+* linker script test
+ Write an autoconf test to check whether the linker supports a
+ version script.
+
+* Add attributes to the MPI functions.
+
+* cipher/pubkey.c and pubkey implementaions.
+ Don't rely on the secure memory based wiping function but add an
+ extra wiping.
+
+* Use builtin bit functions of gcc 3.4
+
+* Consider using a daemon to maintain the random pool
+ [Partly done] The down side of this is that we can't assume that the
+ random has has always been stored in "secure memory". And we rely
+ on that sniffing of Unix domain sockets is not possible. We can
+ implement this simply by detecting a special prefixed random seed
+ name and divert in this case to the daemon. There are several
+ benefits with such an approach: We keep the state of the RNG over
+ invocations of libgcrypt based applications, don't need time
+ consuming initialization of the pool and in case the entropy
+ collectros need to run that bunch of Unix utilities we don't waste
+ their precious results.
+
+* gcryptrnd.c
+ Requires a test for pth [done] as well as some other tests.
+
+* secmem.c
+ Check whether the memory block is valid before releasing it and
+ print a diagnosic, like glibc does.
+
+* threads
+** We need to document fork problems
+ In particular that reinitialization is required in random.c
+ However, there is no code yet to do it.
+
+* Tests
+ We need a lot more tests. Lets keep an ever growing list here.
+** Write tests for the progress function
+** mpitests does no real checks yet.
+** pthreads
+ To catch simple errors like the one fixed on 2007-03-16.
+** C++ tests
+ We have some code to allow using libgcrypt from C++, so we also
+ should have a test case.
--- /dev/null
+dnl macros to configure Libgcrypt
+dnl Copyright (C) 1998, 1999, 2000, 2001, 2002,
+dnl 2003 Free Software Foundation, Inc.
+dnl
+dnl This file is part of Libgcrypt.
+dnl
+dnl Libgcrypt is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU Lesser General Public License as
+dnl published by the Free Software Foundation; either version 2.1 of
+dnl the License, or (at your option) any later version.
+dnl
+dnl Libgcrypt is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+dnl GNUPG_MSG_PRINT(STRING)
+dnl print a message
+dnl
+define([GNUPG_MSG_PRINT],
+ [ echo $ac_n "$1"" $ac_c" 1>&AS_MESSAGE_FD([])
+ ])
+
+dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME)
+dnl Check whether a typedef exists and create a #define $2 if it exists
+dnl
+AC_DEFUN([GNUPG_CHECK_TYPEDEF],
+ [ AC_MSG_CHECKING(for $1 typedef)
+ AC_CACHE_VAL(gnupg_cv_typedef_$1,
+ [AC_TRY_COMPILE([#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>], [
+ #undef $1
+ int a = sizeof($1);
+ ], gnupg_cv_typedef_$1=yes, gnupg_cv_typedef_$1=no )])
+ AC_MSG_RESULT($gnupg_cv_typedef_$1)
+ if test "$gnupg_cv_typedef_$1" = yes; then
+ AC_DEFINE($2,1,[Defined if a `]$1[' is typedef'd])
+ fi
+ ])
+
+
+dnl GNUPG_CHECK_GNUMAKE
+dnl
+AC_DEFUN([GNUPG_CHECK_GNUMAKE],
+ [
+ if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then
+ :
+ else
+ AC_MSG_WARN([[
+***
+*** It seems that you are not using GNU make. Some make tools have serious
+*** flaws and you may not be able to build this software at all. Before you
+*** complain, please try GNU make: GNU make is easy to build and available
+*** at all GNU archives. It is always available from ftp.gnu.org:/gnu/make.
+***]])
+ fi
+ ])
+
+
+#
+# GNUPG_SYS_SYMBOL_UNDERSCORE
+# Does the compiler prefix global symbols with an underscore?
+#
+# Taken from GnuPG 1.2 and modified to use the libtool macros.
+AC_DEFUN([GNUPG_SYS_SYMBOL_UNDERSCORE],
+[tmp_do_check="no"
+case "${host}" in
+ *-mingw32msvc*)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ *)
+ if test "$cross_compiling" = yes; then
+ if test "x$ac_cv_sys_symbol_underscore" = x ; then
+ ac_cv_sys_symbol_underscore=yes
+ fi
+ else
+ tmp_do_check="yes"
+ fi
+ ;;
+esac
+if test "$tmp_do_check" = "yes"; then
+ AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])
+ AC_MSG_CHECKING([for _ prefix in compiled symbols])
+ AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+ [ac_cv_sys_symbol_underscore=no
+ cat > conftest.$ac_ext <<EOF
+ void nm_test_func(){}
+ int main(){nm_test_func;return 0;}
+EOF
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest*
+ ])
+ else
+ AC_MSG_CHECKING([for _ prefix in compiled symbols])
+ fi
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+ AC_DEFINE(WITH_SYMBOL_UNDERSCORE,1,
+ [Defined if compiled symbols have a leading underscore])
+fi
+])
+
+
+######################################################################
+# Check whether mlock is broken (hpux 10.20 raises a SIGBUS if mlock
+# is not called from uid 0 (not tested whether uid 0 works)
+# For DECs Tru64 we have also to check whether mlock is in librt
+# mlock is there a macro using memlk()
+######################################################################
+dnl GNUPG_CHECK_MLOCK
+dnl
+define(GNUPG_CHECK_MLOCK,
+ [ AC_CHECK_FUNCS(mlock)
+ if test "$ac_cv_func_mlock" = "no"; then
+ AC_CHECK_HEADERS(sys/mman.h)
+ if test "$ac_cv_header_sys_mman_h" = "yes"; then
+ # Add librt to LIBS:
+ AC_CHECK_LIB(rt, memlk)
+ AC_CACHE_CHECK([whether mlock is in sys/mman.h],
+ gnupg_cv_mlock_is_in_sys_mman,
+ [AC_TRY_LINK([
+ #include <assert.h>
+ #ifdef HAVE_SYS_MMAN_H
+ #include <sys/mman.h>
+ #endif
+ ], [
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS. Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias. */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
+ ],
+ gnupg_cv_mlock_is_in_sys_mman=yes,
+ gnupg_cv_mlock_is_in_sys_mman=no)])
+ if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
+ AC_DEFINE(HAVE_MLOCK,1,
+ [Defined if the system supports an mlock() call])
+ fi
+ fi
+ fi
+ if test "$ac_cv_func_mlock" = "yes"; then
+ AC_CHECK_FUNCS(sysconf getpagesize)
+ AC_MSG_CHECKING(whether mlock is broken)
+ AC_CACHE_VAL(gnupg_cv_have_broken_mlock,
+ AC_TRY_RUN([
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+int main()
+{
+ char *pool;
+ int err;
+ long int pgsize;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize = sysconf (_SC_PAGESIZE);
+#elif defined (HAVE_GETPAGESIZE)
+ pgsize = getpagesize();
+#else
+ pgsize = -1;
+#endif
+
+ if (pgsize == -1)
+ pgsize = 4096;
+
+ pool = malloc( 4096 + pgsize );
+ if( !pool )
+ return 2;
+ pool += (pgsize - ((long int)pool % pgsize));
+
+ err = mlock( pool, 4096 );
+ if( !err || errno == EPERM )
+ return 0; /* okay */
+
+ return 1; /* hmmm */
+}
+
+ ],
+ gnupg_cv_have_broken_mlock="no",
+ gnupg_cv_have_broken_mlock="yes",
+ gnupg_cv_have_broken_mlock="assume-no"
+ )
+ )
+ if test "$gnupg_cv_have_broken_mlock" = "yes"; then
+ AC_DEFINE(HAVE_BROKEN_MLOCK,1,
+ [Defined if the mlock() call does not work])
+ AC_MSG_RESULT(yes)
+ else
+ if test "$gnupg_cv_have_broken_mlock" = "no"; then
+ AC_MSG_RESULT(no)
+ else
+ AC_MSG_RESULT(assuming no)
+ fi
+ fi
+ fi
+ ])
+
+# GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32
+AC_DEFUN([GNUPG_SYS_LIBTOOL_CYGWIN32],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+AC_CHECK_TOOL(AS, as, false)
+])
+
+dnl LIST_MEMBER()
+dnl Check wether an element ist contained in a list. Set `found' to
+dnl `1' if the element is found in the list, to `0' otherwise.
+AC_DEFUN([LIST_MEMBER],
+[
+name=$1
+list=$2
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+])
+
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+AC_DEFUN([TYPE_SOCKLEN_T],
+[
+ AC_CHECK_TYPE([socklen_t], ,[
+ AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([socklen_t_equiv],
+ [
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t unsigned long "unsigned long"; do
+ AC_TRY_COMPILE([
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int getpeername (int, $arg2 *, $t *);
+ ],[
+ $t len;
+ getpeername(0,0,&len);
+ ],[
+ socklen_t_equiv="$t"
+ break
+ ])
+ done
+ done
+
+ if test "x$socklen_t_equiv" = x; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ ])
+ AC_MSG_RESULT($socklen_t_equiv)
+ AC_DEFINE_UNQUOTED(socklen_t, $socklen_t_equiv,
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+#include <sys/socket.h>])
+])
+
+
+# GNUPG_PTH_VERSION_CHECK(REQUIRED)
+#
+# If the version is sufficient, HAVE_PTH will be set to yes.
+#
+# Taken form the m4 macros which come with Pth
+AC_DEFUN([GNUPG_PTH_VERSION_CHECK],
+ [
+ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'`
+ _req_version="ifelse([$1],,1.2.0,$1)"
+
+ AC_MSG_CHECKING(for PTH - version >= $_req_version)
+ for _var in _pth_version _req_version; do
+ eval "_val=\"\$${_var}\""
+ _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'`
+ _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'`
+ _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'`
+ _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'`
+ case $_rtype in
+ "a" ) _rtype=0 ;;
+ "b" ) _rtype=1 ;;
+ "." ) _rtype=2 ;;
+ esac
+ _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
+ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
+ eval "${_var}_hex=\"\$_hex\""
+ done
+ have_pth=no
+ if test ".$_pth_version_hex" != .; then
+ if test ".$_req_version_hex" != .; then
+ if test $_pth_version_hex -ge $_req_version_hex; then
+ have_pth=yes
+ fi
+ fi
+ fi
+ if test $have_pth = yes; then
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING([whether PTH installation is sane])
+ AC_CACHE_VAL(gnupg_cv_pth_is_sane,[
+ _gnupg_pth_save_cflags=$CFLAGS
+ _gnupg_pth_save_ldflags=$LDFLAGS
+ _gnupg_pth_save_libs=$LIBS
+ CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`"
+ LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`"
+ LIBS="$LIBS `$PTH_CONFIG --libs`"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pth.h>
+ ],
+ [[ pth_init ();]])],
+ gnupg_cv_pth_is_sane=yes,
+ gnupg_cv_pth_is_sane=no)
+ CFLAGS=$_gnupg_pth_save_cflags
+ LDFLAGS=$_gnupg_pth_save_ldflags
+ LIBS=$_gnupg_pth_save_libs
+ ])
+ if test $gnupg_cv_pth_is_sane != yes; then
+ have_pth=no
+ fi
+ AC_MSG_RESULT($gnupg_cv_pth_is_sane)
+ else
+ AC_MSG_RESULT(no)
+ fi
+ ])
--- /dev/null
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
+[m4_warning([this file was generated for autoconf 2.64.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Figure out how to run the assembler. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_AS
+# ----------
+AC_DEFUN([AM_PROG_AS],
+[# By default we simply use the C compiler to build assembly code.
+AC_REQUIRE([AC_PROG_CC])
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+AC_ARG_VAR([CCAS], [assembler compiler command (defaults to CC)])
+AC_ARG_VAR([CCASFLAGS], [assembler compiler flags (defaults to CFLAGS)])
+_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
+])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_$1_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+ fi
+ am__universal=false
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac])
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot. For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([m4/gpg-error.m4])
+m4_include([m4/libtool.m4])
+m4_include([m4/ltoptions.m4])
+m4_include([m4/ltsugar.m4])
+m4_include([m4/ltversion.m4])
+m4_include([m4/lt~obsolete.m4])
+m4_include([m4/noexecstack.m4])
+m4_include([m4/onceonly.m4])
+m4_include([m4/socklen.m4])
+m4_include([m4/sys_socket_h.m4])
+m4_include([acinclude.m4])
--- /dev/null
+#! /bin/sh
+# Run this to generate all the initial makefiles, etc.
+#
+# Copyright (C) 2003 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+configure_ac="configure.ac"
+
+cvtver () {
+ awk 'NR==1 {split($NF,A,".");X=1000000*A[1]+1000*A[2]+A[3];print X;exit 0}'
+}
+
+check_version () {
+ if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
+ return 0
+ fi
+ echo "**Error**: "\`$1\'" not installed or too old." >&2
+ echo ' Version '$3' or newer is required.' >&2
+ [ -n "$4" ] && echo ' Note that this is part of '\`$4\''.' >&2
+ DIE="yes"
+ return 1
+}
+
+
+DIE=no
+FORCE=
+if test x"$1" = x"--force"; then
+ FORCE=" --force"
+ shift
+fi
+
+# Begin list of optional variables sourced from ~/.gnupg-autogen.rc
+w32_toolprefixes=
+w32_extraoptions=
+w32ce_toolprefixes=
+w32ce_extraoptions=
+amd64_toolprefixes=
+# End list of optional variables sourced from ~/.gnupg-autogen.rc
+# What follows are variables which are sourced but default to
+# environment variables or lacking them hardcoded values.
+#w32root=
+#w32ce_root=
+#amd64root=
+
+if [ -f "$HOME/.gnupg-autogen.rc" ]; then
+ echo "sourcing extra definitions from $HOME/.gnupg-autogen.rc"
+ . "$HOME/.gnupg-autogen.rc"
+fi
+
+# Convenience option to use certain configure options for some hosts.
+myhost=""
+myhostsub=""
+case "$1" in
+ --build-w32)
+ myhost="w32"
+ ;;
+ --build-w32ce)
+ myhost="w32"
+ myhostsub="ce"
+ ;;
+ --build-amd64)
+ myhost="amd64"
+ ;;
+ --build*)
+ echo "**Error**: invalid build option $1" >&2
+ exit 1
+ ;;
+ *)
+ ;;
+esac
+
+
+# ***** W32 build script *******
+# Used to cross-compile for Windows.
+if [ "$myhost" = "w32" ]; then
+ tmp=`dirname $0`
+ tsdir=`cd "$tmp"; pwd`
+ shift
+ if [ ! -f $tsdir/config.guess ]; then
+ echo "$tsdir/config.guess not found" >&2
+ exit 1
+ fi
+ build=`$tsdir/config.guess`
+
+ case $myhostsub in
+ ce)
+ w32root="$w32ce_root"
+ [ -z "$w32root" ] && w32root="$HOME/w32ce_root"
+ toolprefixes="arm-mingw32ce"
+ ;;
+ *)
+ [ -z "$w32root" ] && w32root="$HOME/w32root"
+ toolprefixes="i586-mingw32msvc i386-mingw32msvc"
+ ;;
+ esac
+ echo "Using $w32root as standard install directory" >&2
+
+ # Locate the cross compiler
+ crossbindir=
+ for host in $toolprefixes; do
+ if ${host}-gcc --version >/dev/null 2>&1 ; then
+ crossbindir=/usr/${host}/bin
+ conf_CC="CC=${host}-gcc"
+ break;
+ fi
+ done
+ if [ -z "$crossbindir" ]; then
+ echo "Cross compiler kit not installed" >&2
+ if [ -z "$sub" ]; then
+ echo "Under Debian GNU/Linux, you may install it using" >&2
+ echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2
+ fi
+ echo "Stop." >&2
+ exit 1
+ fi
+
+ if [ -f "$tsdir/config.log" ]; then
+ if ! head $tsdir/config.log | grep "$host" >/dev/null; then
+ echo "Pease run a 'make distclean' first" >&2
+ exit 1
+ fi
+ fi
+
+ $tsdir/configure --enable-maintainer-mode --prefix=${w32root} \
+ --host=${host} --build=${build} \
+ --with-gpg-error-prefix=${w32root}
+ exit $?
+fi
+# ***** end W32 build script *******
+
+
+# ***** AMD64 cross build script *******
+# Used to cross-compile for AMD64 (for testing)
+if [ "$myhost" = "amd64" ]; then
+ tmp=`dirname $0`
+ tsdir=`cd "$tmp"; pwd`
+ shift
+ if [ ! -f $tsdir/config.guess ]; then
+ echo "$tsdir/config.guess not found" >&2
+ exit 1
+ fi
+ build=`$tsdir/config.guess`
+
+ [ -z "$amd64root" ] && amd64root="$HOME/amd64root"
+ echo "Using $amd64root as standard install directory" >&2
+
+ # Locate the cross compiler
+ crossbindir=
+ for host in x86_64-linux-gnu amd64-linux-gnu; do
+ if ${host}-gcc --version >/dev/null 2>&1 ; then
+ crossbindir=/usr/${host}/bin
+ conf_CC="CC=${host}-gcc"
+ break;
+ fi
+ done
+ if [ -z "$crossbindir" ]; then
+ echo "Cross compiler kit not installed" >&2
+ echo "Stop." >&2
+ exit 1
+ fi
+
+ if [ -f "$tsdir/config.log" ]; then
+ if ! head $tsdir/config.log | grep "$host" >/dev/null; then
+ echo "Please run a 'make distclean' first" >&2
+ exit 1
+ fi
+ fi
+
+ $tsdir/configure --enable-maintainer-mode --prefix=${amd64root} \
+ --host=${host} --build=${build} \
+ --with-gpg-error-prefix=${amd64root}
+
+ rc=$?
+ exit $rc
+fi
+# ***** end AMD64 cross build script *******
+
+# Grep the required versions from configure.ac
+autoconf_vers=`sed -n '/^AC_PREREQ(/ {
+s/^.*(\(.*\))/\1/p
+q
+}' ${configure_ac}`
+autoconf_vers_num=`echo "$autoconf_vers" | cvtver`
+
+automake_vers=`sed -n '/^min_automake_version=/ {
+s/^.*="\(.*\)"/\1/p
+q
+}' ${configure_ac}`
+automake_vers_num=`echo "$automake_vers" | cvtver`
+
+#gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
+#s/^.*(\(.*\))/\1/p
+#q
+#}' ${configure_ac}`
+#gettext_vers_num=`echo "$gettext_vers" | cvtver`
+
+
+if [ -z "$autoconf_vers" -o -z "$automake_vers" ]
+then
+ echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2
+ exit 1
+fi
+
+# Allow to override the default tool names
+AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
+AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
+
+AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
+ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
+
+#GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
+#MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
+
+
+if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
+ check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
+fi
+if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
+ check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
+fi
+#if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
+# check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
+#fi
+
+if test "$DIE" = "yes"; then
+ cat <<EOF
+
+Note that you may use alternative versions of the tools by setting
+the corresponding environment variables; see README.SVN for details.
+
+EOF
+ exit 1
+fi
+
+# Check the git setup.
+if [ -d .git ]; then
+ if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
+ cat <<EOF >&2
+*** Activating trailing whitespace git pre-commit hook. ***
+ For more information see this thread:
+ http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084html
+ To deactivate this pre-commit hook again move .git/hooks/pre-commit
+ and .git/hooks/pre-commit.sample out of the way.
+EOF
+ cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit
+ chmod -c +x .git/hooks/pre-commit
+ fi
+fi
+
+
+echo "Running aclocal -I m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..."
+$ACLOCAL -I m4 $ACLOCAL_FLAGS
+echo "Running autoheader..."
+$AUTOHEADER
+echo "Running automake --gnu ..."
+$AUTOMAKE --gnu;
+echo "Running autoconf${FORCE} ..."
+$AUTOCONF${FORCE}
+
+echo "You may now run:
+ ./configure --enable-maintainer-mode && make
+"
--- /dev/null
+2011-06-13 Werner Koch <wk@g10code.com>
+
+ * dsa.c (selftest_sign_1024): Use the raw and not the pkcs1 flag.
+
+ * pubkey.c (gcry_pk_sign): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Parse "random-override" for pkcs1 encryption.
+ (pkcs1_encode_for_encryption): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (gcry_pk_encrypt): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for raw encoding.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Use format specifier '%M' to avoid
+ leading zeroes. Special case output generation for PSS.
+ (gcry_pk_encrypt): Special case output generation for OAEP.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for PSS verify.
+
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Make use of octet_string_from_mpi.
+ (sexp_to_enc): Skip "random-override".
+
+ * pubkey.c (oaep_encode, pss_encode): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (sexp_data_to_mpi): Extract new random-override parameter.
+
+ * pubkey.c (pss_encode, pss_verify): Use VALUE verbatim for MHASH.
+ (octet_string_from_mpi): Add arg SPACE.
+
+2011-06-08 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pss_encode, pss_verify): Restructure and comment code
+ to match rfc-3447. Replace secure allocs by plain allocs and
+ wipememory. Use gcry_md_hash_buffer.
+ (octet_string_from_mpi): New.
+
+2011-06-03 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Add more comments and restructure to
+ match the description in RFC-3447.
+ (oaep_encode): Check for mgf1 error. s/dlen/hlen/.
+
+2011-05-31 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (mgf1): Optimize by using gcry_md_reset. Re-implement
+ for easier readability.
+ (oaep_encode): Add more comments and restructure to match the
+ description in RFC-3447.
+
+ * pubkey.c (pkcs1_encode_for_signature, oaep_decode): Change
+ return value from one MPI to a buffer.
+ (gcry_pk_decrypt): Adjust for this change.
+
+2011-05-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pkcs1_decode_for_encryption): Change handling of
+ leading zero byte.
+
+2011-05-27 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (gcry_pk_decrypt): Fix double-free when un-padding
+ invalid data. Thanks to Tom Ritter.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * rsa.c (rsa_verify): Use CMP if given, to check the decrypted
+ sig.
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Factor out
+ CTX initialization to ...
+ (init_encoding_ctx): .. new.
+ (gcry_pk_verify): Pass verify func and the arg to pubkey_verify.
+ (pss_encode, pss_verify, pss_verify_cmp): New.
+
+2011-05-23 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (pkcs1_decode_for_encryption, oaep_decode): Fix memleak
+ when gcry_mpi_print fails.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (pkcs1_encode_for_encryption): .. new,
+ (pkcs1_encode_for_signature): .. new.
+ (pkcs1_decode_for_encryption): New.
+ (gcry_pk_decrypt): Do un-padding for PKCS#1 as well as OAEP.
+ (sexp_to_enc): Abolish "unpad" flag, which is not necessary since
+ we can do un-padding implicitly when "pkcs1" or "oaep" is given.
+
+2011-05-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Set LABEL to NULL
+ after free.
+ (sexp_to_enc, sexp_data_to_mpi): Do not allow multiple encoding
+ flags.
+ (oaep_encode, oaep_decode, sexp_to_key, sexp_to_sig)
+ (sexp_to_enc, sexp_data_to_mpi, gcry_pk_encrypt, gcry_pk_sign)
+ (gcry_pk_genkey, _gcry_pk_get_elements): Replace access to ERRNO
+ by gpg_err_code_from_syserror.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (get_hash_algo): .. new.
+ (mgf1, oaep_encode, oaep_decode): New.
+ (sexp_to_enc): Add arg CTX. Remove arg RET_WANT_PKCS1. Support
+ OAEP.
+ (sexp_data_to_mpi): Add arg CTX. Support OAEP.
+ (gcry_pk_encrypt): Pass a CTX to sexp_data_to_mpi.
+ (gcry_pk_decrypt): Pass a CTX tp sexp_to_enc and replace
+ WANT_PKCS1. Implement unpadding for OAEP.
+ (gcry_pk_sign): Pass NULL for CTX arg of sexp_data_to_mpi.
+ (gcry_pk_verify): Ditto.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Replace gpg_err_code_from_errno by
+ gpg_err_code_from_syserror.
+
+2011-04-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Avoid double free of L2.
+
+ * cipher.c (_gcry_cipher_setctr): Clear unused lastiv info.
+ (gcry_cipher_ctl) <GCRYCTL_SET_CTR>: Implement by calling
+ _gcry_cipher_setctr.
+ (do_ctr_encrypt): Save last counter and reuse it.
+
+ * cipher.c (do_ctr_encrypt): Allow arbitrary length inputs to
+ match the 1.4 behaviour.
+
+2011-04-04 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Release L1 while parsing "curve".
+
+ * pubkey.c (gcry_pk_get_keygrip): Always release NAME and L2.
+ Reported by Ben Kibbey.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_elg_prime): Make sure that PRIME is
+ NULL if the called func ever returns an error.
+
+ * pubkey.c (gcry_pk_decrypt): Remove unused var PUBKEY.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * kdf.c: New.
+
+2011-02-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (aesni_cleanup_2_4): New.
+ (aesenc_xmm1_xmm0, do_aesni_ctr_4): New.
+ (_gcry_aes_ctr_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add CTR_ENC. Move field
+ CTR into an u_ctr union and adjust all users.
+ (gcry_cipher_open): Use _gcry_aes_ctr_enc.
+ (do_ctr_encrypt): Use bulk mode.
+
+2011-02-18 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (u32_a_t): New.
+ (do_encrypt_aligned, do_encrypt_aligned): Use the new type to
+ avoid problems with strict aliasing rules.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_cfb) [USE_AESNI]: New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec) [USE_AESNI]: Use new fucntion.
+
+2011-02-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_enc_aligned, do_aesni_dec_aligned): Use
+ movdqa for the key but keep using movdqu for the data.
+ (do_aesni): Remove alignment detection. Don't burn the stack.
+ (aesni_prepare, aesni_cleanup): New macros.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use
+ these macros. Don't burn the stack in the USE_AESNI case.
+ (do_setkey): Add disabled code to use aeskeygenassist.
+
+2011-02-14 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (ATTR_ALIGNED_16): New
+ (do_aesni): Do not copy if already aligned.
+ (do_encrypt, do_decrypt): Ditto.
+ (rijndael_decrypt, rijndael_encrypt): Increase stack burning amount.
+
+ * rijndael.c (RIJNDAEL_context): Reorder fields. Change fieldname
+ ROUNDS to rounds. Move padlock_key into u1.
+ (keySched, keySched2): Rename macros to keyscherr and keyschdec
+ and change all users.
+ (padlockkey): New macro. Change all users of padlock_key.
+ * cipher.c (NEED_16BYTE_ALIGNED_CONTEXT): Always define if using gcc.
+ (struct gcry_cipher_handle): Align U_IV to at least 16 byte.
+
+2011-02-13 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_AESNI): New. Define for ia32 and gcc >= 4.
+ (m128i_t) [USE_AESNI]: New.
+ (RIJNDAEL_context) [USE_AESNI]: Add field use_aesni.
+ (do_setkey): Set USE_AESNI for all key lengths.
+ (prepare_decryption) [USE_AESNI]: Use aesimc instn if requested.
+ (do_aesni_enc_aligned, do_aesni_dec_aligned)
+ (do_aesni) [USE_AESNI]: New.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec)
+ (_gcry_aes_cbc_dec) [USE_AESNI]: Use do_aesni.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_curve): New.
+ (sexp_to_key): Add arg OVERRIDE_ELEMS.
+ (sexp_elements_extract_ecc): Allow for params only.
+ (gcry_pk_get_param): New.
+ * ecc.c (ecc_get_curve): New.
+ (ecc_get_param_sexp): New.
+
+2011-01-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Hack to insert the used curve name.
+
+2011-01-27 Werner Koch <wk@g10code.com>
+
+ * ecc.c (fill_in_curve): Remove.
+ (generate_curve): Rename to ..
+ (fill_in_curve): this. Remove setting of NAME_OID.
+ (ecc_encrypt_raw): Change name of arg DATA to K for better
+ readability. Use ECC_public_key instead of ECC_secret_key.
+ Require a caller to pass a complete pkey array.
+ (ecc_decrypt_raw): Require a caller to pass a complete skey array.
+ (elliptic_curve_t): Add field NAME.
+ (fill_in_curve): Set field.
+ (generate_key): Add arg R_USED_CURVE.
+ (ecc_generate_ext): Return used curve name.
+
+2011-01-13 Andrey Jivsov <openpgp@brainhub.org> (wk)
+
+ * ecc.c (ec2os): Do not free passed parameters X and Y. Adjust
+ callers.
+ (ecc_encrypt_raw, ecc_decrypt_raw): New.
+ (ecdh_names, _gcry_pubkey_spec_ecdh): New.
+ * pubkey.c (pubkey_table): Support ECDH.
+
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Remove double release of the module.
+ Fixes bug#1263.
+
+2010-06-10 Jeff Johnson <n3npq@mac.com> (wk)
+
+ * ecc.c (ecc_generate_ext): Parse transient-key flag.
+ (generate_key): Add arg TRANSIENT_KEY and use it to set the random
+ level.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * tiger.c (asn): Unfetter the old TIGER from an OID.
+ (TIGER_CONTEXT): Add field VARIANT.
+ (tiger_init): Factor code out to ...
+ (do_init): New.
+ (tiger1_init, tiger2_init): New.
+ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New.
+ * md.c (digest_table): Add TIGER1 and TIGER2 variants.
+
+2009-12-11 Werner Koch <wk@g10code.com>
+
+ * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables
+
+ * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables.
+ Suggested by Christian Grothoff.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (o_flag_munging): New.
+ (tiger.o, tiger.lo): Use it.
+
+ * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Add check for valid inputlen. Wipe temporary
+ memory.
+ (do_ctr_decrypt): Likewise.
+ (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Move check for valid inputlen to here; change
+ returned error from INV_ARG to INV_LENGTH.
+ (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+ (do_cfb_encrypt, do_cfb_decrypt): Ditto.
+ (do_ofb_encrypt, do_ofb_decrypt): Ditto.
+ (cipher_encrypt, cipher_encrypt): Adjust for above changes.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP.
+ (cipher_encrypt, cipher_decrypt): Ditto.
+ (do_aeswrap_encrypt, do_aeswrap_decrypt): New.
+ (struct gcry_cipher_handle): Add field marks.
+ (cipher_setkey, cipher_setiv): Update marks flags.
+ (cipher_reset): Reset marks.
+ (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to
+ cipher_encrypt. Replace GPG_ERR_TOO_SHORT by
+ GPG_ERR_BUFFER_TOO_SHORT.
+
+2009-08-21 Werner Koch <wk@g10code.com>
+
+ * dsa.c (dsa_generate_ext): Release retfactors array before
+ setting it to NULL. Reported by Daiko Ueno.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * md.c (md_read): Fix incomplete check for NULL.
+ Reported by Fabian Kail.
+
+2009-03-31 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not
+ GPG_ERR_PUBKEY_ALGO.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * rsa.c (generate_x931): Do not initialize TBL with automatic
+ variables.
+ * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c
+ * md4.c, crc.c: Remove memory.h. This is garbage from gnupg.
+ Reported by Dan Fandrich.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Remove superfluous const.
+
+2009-01-06 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg DOMAIN and use it if specified.
+ (generate_fips186): Ditto.
+ (dsa_generate_ext): Parse and check the optional "domain"
+ parameter and pass them to the generate functions.
+
+ * rijndael.c (rijndael_names): Add "AES128" and "AES-128".
+ (rijndael192_names): Add "AES-192".
+ (rijndael256_names): Add "AES-256".
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine
+ the RNG quality needed.
+ (dsa_generate_ext): Parse the transient-key flag und pass it to
+ generate.
+
+2008-11-28 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed
+ value if available.
+
+ * primegen.c (_gcry_generate_fips186_2_prime): Fix inner p loop.
+
+2008-11-26 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_fips186_3_prime): New.
+ * dsa.c (generate_fips186): Add arg USE_FIPS186_2.
+ (dsa_generate_ext): Parse new flag use-fips183-2.
+
+2008-11-25 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): New.
+ (dsa_generate_ext): Use new function if derive-parms are given or
+ if in FIPS mode.
+ * primegen.c (_gcry_generate_fips186_2_prime): New.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
+ (pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
+ key generation function.
+ * rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
+ (generate_x931): Generate params if not given.
+ (rsa_generate_ext): Parse use-x931 flag. Return p-q-swapped
+ indicator.
+ * dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
+ possible.
+
+ * pubkey.c (gcry_pk_genkey): Remove parsing of almost all
+ parameters and pass the parameter S-expression to pubkey_generate.
+ (pubkey_generate): Simplify by requitring modules to parse the
+ parameters. Remove the special cases for Elgamal and ECC.
+ (sexp_elements_extract_ecc): Add arg EXTRASPEC and use it. Fix
+ small memory leak.
+ (sexp_to_key): Pass EXTRASPEC to sexp_elements_extract_ecc.
+ (pubkey_table) [USE_ELGAMAL]: Add real extraspec.
+ * rsa.c (rsa_generate_ext): Adjust for new calling convention.
+ * dsa.c (dsa_generate_ext): Ditto.
+ * elgamal.c (_gcry_elg_generate): Ditto. Rename to elg_generate_ext.
+ (elg_generate): New.
+ (_gcry_elg_generate_using_x): Remove after merging code with
+ elg_generate_ext.
+ (_gcry_pubkey_extraspec_elg): New.
+ (_gcry_elg_check_secret_key, _gcry_elg_encrypt, _gcry_elg_sign)
+ (_gcry_elg_verify, _gcry_elg_get_nbits): Make static and remove
+ _gcry_ prefix.
+ * ecc.c (_gcry_ecc_generate): Rename to ecc_generate_ext and
+ adjust for new calling convention.
+ (_gcry_ecc_get_param): Rename to ecc_get_param and make static.
+ (_gcry_pubkey_extraspec_ecdsa): Add ecc_generate_ext and
+ ecc_get_param.
+
+2008-11-20 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg DERIVEPARMS.
+ (gcry_pk_genkey): Parse derive-parms and pass it to above.
+ * rsa.c (generate_x931): New.
+ (rsa_generate_ext): Add arg DERIVEPARMS and call new function in
+ fips mode or if DERIVEPARMS is given.
+ * primegen.c (_gcry_derive_x931_prime, find_x931_prime): New.
+
+2008-11-19 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding.
+ (generate): Rename to generate_std.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * md.c (md_open): Use a switch to set the Bsize.
+ (prepare_macpads): Fix long key case for SHA384 and SHA512.
+
+ * cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
+ (gcry_cipher_open): Set it.
+ (gcry_cipher_ctl): Add private control code to disable weak key
+ detection and to return the current input block.
+ * des.c (_tripledes_ctx): Add field FLAGS.
+ (do_tripledes_set_extra_info): New.
+ (_gcry_cipher_extraspec_tripledes): Add new function.
+ (do_tripledes_setkey): Disable weak key detection.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * md.c (digest_table): Allow MD5 in fips mode.
+ (md_register_default): Take special action for MD5.
+ (md_enable, gcry_md_hash_buffer): Ditto.
+
+2008-09-30 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_setkey): Properly align "t" and "tk".
+ (prepare_decryption): Properly align "w". Fixes bug #936.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Parse domain parameter.
+ (pubkey_generate): Add new arg DOMAIN and remove special case for
+ DSA with qbits.
+ * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and
+ rename to rsa_generate_ext. Change caller.
+ (_gcry_rsa_generate, _gcry_rsa_check_secret_key)
+ (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign)
+ (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove
+ _gcry_ prefix.
+ (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names.
+ * dsa.c (dsa_generate_ext): New.
+ (_gcry_dsa_generate): Replace code by a call to dsa_generate.
+ (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify)
+ (_gcry_dsa_get_nbits): Make static and remove _gcry prefix.
+ (_gcry_dsa_generate2): Remove.
+ (_gcry_pubkey_spec_dsa): Adjust to name changes.
+ (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (run_selftests): Add arg EXTENDED.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * rsa.c (test_keys): Do a bad case signature check.
+ * dsa.c (test_keys): Do a bad case check.
+
+ * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it
+ to the called tests.
+ * md.c (_gcry_md_selftest): Ditto.
+ * pubkey.c (_gcry_pk_selftest): Ditto.
+ * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftest_fips_128): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftest_fips_192): Add dummy arg EXTENDED.
+ (selftest_fips_256): Ditto.
+ * hmac-tests.c (_gcry_hmac_selftest): Ditto.
+ (run_selftests): Ditto.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha224, selftests_sha256): Ditto.
+ (selftests_sha384, selftests_sha512): Ditto.
+ * sha1.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ * sha256.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha224): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha256): Ditto.
+ * sha512.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha384): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha512): Ditto.
+ * des.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftest_fips): Add dummy arg EXTENDED.
+ * rsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * dsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * rsa.c (extract_a_from_sexp): New.
+ (selftest_encr_1024): Check that the ciphertext does not match the
+ plaintext.
+ (test_keys): Improve tests and return an error status.
+ (generate): Return an error if test_keys fails.
+ * dsa.c (test_keys): Add comments and return an error status.
+ (generate): Return an error if test_keys failed.
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling
+ BUG in case of a practically impossible condition.
+ (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024, selftest_encr_1024): New.
+ (selftests_rsa): Implement tests.
+ * dsa.c (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024): New.
+ (selftests_dsa): Implement tests.
+
+2008-09-09 Werner Koch <wk@g10code.com>
+
+ * hmac-tests.c (selftests_sha1): Add tests.
+ (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests.
+
+ * hash-common.c, hash-common.h: New.
+ * sha1.c (selftests_sha1): Add 3 tests.
+ * sha256.c (selftests_sha256, selftests_sha224): Ditto.
+ * sha512.c (selftests_sha512, selftests_sha384): Ditto.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA
+ and check whether a custom computation function has been setup.
+ * rsa.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_rsa): Setup this function.
+ * ecc.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_ecdsa): Setup this function.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * cipher.c (cipher_decrypt, cipher_encrypt): Return an error if
+ mode NONE is used.
+ (gcry_cipher_open): Allow mode NONE only with a debug flag set and
+ if not in FIPS mode.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
+ (gcry_pk_genkey): Implement new parameter "transient-key" and
+ pass it as flags to pubkey_generate.
+ (pubkey_generate): Make use of an ext_generate function.
+ * rsa.c (generate): Add new arg transient_key and pass appropriate
+ args to the prime generator.
+ (_gcry_rsa_generate): Factor all code out to ...
+ (rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
+ (_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Use a constant macro for the random
+ level.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow
+ allow "curve" parameter.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (_gcry_pk_selftest): New.
+ * dsa.c (selftests_dsa, run_selftests): New.
+ * rsa.c (selftests_rsa, run_selftests): New.
+ * ecc.c (selftests_ecdsa, run_selftests): New.
+
+ * md.c (_gcry_md_selftest): New.
+ * sha1.c (run_selftests, selftests_sha1): New.
+ * sha256.c (selftests_sha224, selftests_sha256, run_selftests): New.
+ * sha512.c (selftests_sha384, selftests_sha512, run_selftests): New.
+
+ * des.c (selftest): Remove static variable form selftest.
+ (des_setkey): No on-the-fly self test in fips mode.
+ (tripledes_set3keys): Ditto.
+
+ * cipher.c (_gcry_cipher_setkey, _gcry_cipher_setiv):
+
+ * dsa.c (generate): Bail out in fips mode if NBITS is less than 1024.
+ * rsa.c (generate): Return an error code if the the requested size
+ is less than 1024 and we are in fpis mode.
+ (_gcry_rsa_generate): Take care of that error code.
+
+ * ecc.c (generate_curve): In fips mode enable only NIST curves.
+
+ * cipher.c (_gcry_cipher_selftest): New.
+
+ * sha512.c (_gcry_digest_extraspec_sha384)
+ (_gcry_digest_extraspec_sha512): New.
+ * sha256.c (_gcry_digest_extraspec_sha224)
+ (_gcry_digest_extraspec_sha256): New.
+ * sha1.c (_gcry_digest_extraspec_sha1): New.
+ * ecc.c (_gcry_pubkey_extraspec_ecdsa): New.
+ * dsa.c (_gcry_pubkey_extraspec_dsa): New.
+ * rsa.c (_gcry_pubkey_extraspec_rsa): New.
+ * rijndael.c (_gcry_cipher_extraspec_aes)
+ (_gcry_cipher_extraspec_aes192, _gcry_cipher_extraspec_aes256): New.
+ * des.c (_gcry_cipher_extraspec_tripledes): New.
+
+ * cipher.c (gcry_cipher_register): Rename to _gcry_cipher_register.
+ Add arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (cipher_table_entry): Add extraspec field.
+ * md.c (_gcry_md_register): Rename to _gcry_md_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (digest_table_entry): Add extraspec field.
+ * pubkey.c (gcry_pk_register): Rename to _gcry_pk_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (pubkey_table_entry): Add extraspec field.
+
+ * ac.c: Let most public functions return GPG_ERR_UNSUPPORTED in
+ fips mode.
+
+ * pubkey.c (pubkey_table_entry): Add field FIPS_ALLOWED and mark
+ appropriate algorithms.
+ (dummy_generate, dummy_check_secret_key, dummy_encrypt)
+ (dummy_decrypt, dummy_sign, dummy_verify, dummy_get_nbits): Signal
+ a fips error when used.
+ (gcry_pk_register): In fips mode do not allow to register new
+ algorithms.
+
+ * md.c (digest_table): Add field FIPS_ALLOWED and mark appropriate
+ algorithms.
+ (md_register_default): In fips mode register only fips algorithms.
+ (gcry_md_register): In fips mode do not allow to register new
+ algorithms.
+ (gcry_md_get): Signal a fips error if called.
+ (gcry_md_hash_buffer): Do not allow rmd160 when not in fips mode.
+ (md_start_debug): Disable in fips_mode.
+
+ * md.c (gcry_md_register_default): Rename to ..
+ (md_register_default): .. this.
+ (md_digest): Remove this commented fucntion.
+ * pubkey.c (gcry_pk_register_default): Rename to ..
+ (pk_register_default): .. this.
+
+ * cipher.c (cipher_table_entry): Add field FIPS_ALLOWED.
+ (gcry_cipher_register_default): Register only fips approved
+ algorithms.
+ (gcry_cipher_register): Do not allow to register new ciphers.
+ (cipher_setiv): Signal fips error.
+
+ * cipher (gcry_cipher_register_default): Rename to ..
+ (cipher_register_default): .. this.
+ (REGISTER_DEFAULT_CIPHERS): Adjust for that change.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h
+ * random.c, rndegd.c, rndlinux.c, rndw32.c: Move to ../cipher.
+ * Makefile.am: Remove random stuff.
+
+2008-06-24 Szakats Istvan <szaki.ms@gmail.com> (wk)
+
+ * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase
+ some more memory.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use Padlock if possible.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c (transform_aligned): Remove. That is will obviosuly not
+ work because we need a scratch working area and our internal API
+ does not allow to modify the buffers.
+
+ * rijndael.c: Factor tables out to ..
+ * rijndael-tables.h: .. new.
+
+ * ac.c (ac_data_extract): Make static.
+
+ * camellia.h [HAVE_CONFIG_H]: Include config.h.
+
+ * rndw32.c (registry_poll): Only print the performance data
+ problem warning once. Suggested by Simon Josefsson.
+
+2008-03-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only
+ if requested. Suggested by Dirk Stoecker.
+
+2008-03-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c: Include stdint.h.
+ (transform): Add arg NBLOCKS so that we can work on more than one
+ block and avoid updates of the chaining variables. Changed all
+ callers to use 1.
+ (sha1_write): Replace loop around transform.
+ (transform_aligned) [WORDS_BIGENDIAN]: New.
+ (TRANSFORM): New macro to replace all direct calls of transform.
+
+2008-03-17 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_dec): New.
+ (do_encrypt): Factor code out to ..
+ (do_encrypt_aligned): .. New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec): Use new function.
+ (do_decrypt): Factor code out to ..
+ (do_decrypt_aligned): .. new.
+ (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec): New.
+ * cipher.c (struct gcry_cipher_handle): Put field IV into new
+ union U_IV to enforce proper alignment. Change all users.
+ (do_cfb_decrypt): Optimize.
+ (do_cbc_encrypt, do_cbc_decrypt): Optimize.
+
+2008-03-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add field ALGO and BULK.
+ (gcry_cipher_open): Set ALGO and BULK.
+ (do_cfb_encrypt): Optimize.
+
+2008-02-18 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print
+ intermediate results.
+
+2008-01-08 Werner Koch <wk@g10code.com>
+
+ * random.c (add_randomness): Do not just increment
+ POOL_FILLED_COUNTER but update it by the actual amount of data.
+
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Support SHA-224.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Depend on ENABLE_PADLOCK_SUPPORT.
+ * rndhw.c (USE_PADLOCK): Ditto
+
+ * rsa.c (secret): Fixed condition test for using CRT. Reported by
+ Dean Scarff. Fixes bug#864.
+ (_gcry_rsa_check_secret_key): Return an erro if the optional
+ parameters are missing.
+ * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
+ callers to pass NULL. Add hack to allow for optional RSA
+ parameters.
+ (sexp_to_key): Pass algo name to sexp_elements_extract.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * random.c (gcry_random_add_bytes): Implement it.
+ * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New.
+
+2007-11-30 Werner Koch <wk@g10code.com>
+
+ * rndhw.c: New.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Try to read 50%
+ directly from the hwrng.
+ * random.c (do_fast_random_poll): Also run the hw rng fast poll.
+ (_gcry_random_dump_stats): Tell whether the hw rng failed.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Define new macro used for ia32.
+ (RIJNDAEL_context) [USE_PADLOCK]: Add fields USE_PADLOCK and
+ PADLOCK_KEY.
+ (do_setkey) [USE_PADLOCK]: Enable padlock if available for 128 bit
+ AES.
+ (do_padlock) [USE_PADLOCK]: New.
+ (rijndael_encrypt, rijndael_decrypt) [USE_PADLOCK]: Divert to
+ do_padlock.
+ * cipher.c (cipher_context_alignment_t): New. Use it in this
+ module in place of PROPERLY_ALIGNED_TYPE.
+ (NEED_16BYTE_ALIGNED_CONTEXT): Define macro for ia32.
+ (struct gcry_cipher_handle): Add field HANDLE_OFFSET.
+ (gcry_cipher_open): Take care of increased alignment requirements.
+ (gcry_cipher_close): Ditto.
+
+2007-11-28 Werner Koch <wk@g10code.com>
+
+ * sha256.c (asn224): Fixed wrong template. It happened due to a
+ bug in RFC4880. SHA-224 is not in the stable version of libgcrypt
+ so the consequences are limited to users of this devel version.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * ac.c (gcry_ac_data_new): Remove due to the visibility wrapper.
+ (gcry_ac_data_destroy, gcry_ac_data_copy, gcry_ac_data_length)
+ (gcry_ac_data_set, gcry_ac_data_get_name, gcry_ac_data_get_index)
+ (gcry_ac_data_to_sexp, gcry_ac_data_from_sexp)
+ (gcry_ac_data_clear, gcry_ac_io_init, gcry_ac_open)
+ (gcry_ac_close, gcry_ac_key_init, gcry_ac_key_pair_generate)
+ (gcry_ac_key_pair_extract, gcry_ac_key_destroy)
+ (gcry_ac_key_pair_destroy, gcry_ac_key_data_get)
+ (gcry_ac_key_test, gcry_ac_key_get_nbits, gcry_ac_key_get_grip)
+ (gcry_ac_data_encrypt, gcry_ac_data_decrypt, gcry_ac_data_sign)
+ (gcry_ac_data_verify, gcry_ac_data_encode, gcry_ac_data_decode)
+ (gcry_ac_mpi_to_os, gcry_ac_mpi_to_os_alloc, gcry_ac_os_to_mpi)
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme)
+ (gcry_ac_io_init_va): Ditto.
+ (gcry_ac_id_to_name, gcry_ac_name_to_id): Remove as these
+ deprecated functions are now implemented by visibility.c.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Disable debug flag.
+
+2007-10-25 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Updated from current cryptlib snapshot and modified
+ for our use. Removed support from pre NT systems.
+ (slow_gatherer_windows95): Remove.
+ (_gcry_rndw32_gather_random): Require an NT platform.
+ (init_system_rng, read_system_rng, read_mbm_data): New.
+ (slow_gatherer_windowsNT): Rename to ...
+ (slow_gatherer): .. this. Read system RNG and MBM.
+ (registry_poll): New with code factored out from slow_gatherer.
+
+2007-08-23 Werner Koch <wk@g10code.com>
+
+ * random.c (pool_filled_counter): New.
+ (add_randomness): Use it.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * rndw32.c, rndunix.c: Switched to LGPL.
+
+2007-05-30 Werner Koch <wk@g10code.com>
+
+ * camellia.h, camellia.c: Replace by new LGPL version and adjusted
+ camellia.h.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (_gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read):
+ Adjust users of gcry_ac_io_t because union is not anonymous
+ anymore.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * camellia-glue.c (camellia_setkey, camellia_encrypt)
+ (camellia_decrypt): Recalculated used stack size in called
+ functions.
+ * camellia.h: Redefine external symbols.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am, cipher.c: Add Camellia.
+
+ * camellia-glue.c: New. The necessary glue to interface libgcrypt
+ to the stock NTT Camellia distribution.
+
+ * camellia.h, camellia.c: The stock NTT Camellia distribution
+ (GPL).
+
+2007-04-30 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.c: Use #if instead of #ifdef as configure defines the
+ USE_cipher defines as 0 for disabled.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * rndegd.c (_gcry_rndegd_set_socket_name): New.
+
+2007-04-30 Marcus Brinkmann <marcus@g10code.de>
+
+ * ecc.c (ec2os): Fix relocation of short numbers.
+
+ * ecc.c (generate_key): Do not allocate D, which will be allocated
+ by GEN_K. Remove G. Fix test if g_x, g_y resp. q_x, q_y are
+ requested.
+ (_gcry_ecc_generate): Release unneeded members of SK.
+ * pubkey.c (sexp_to_key): Release NAME.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (gcry_ac_mpi): Remove member NAME_PROVIDED.
+ (ac_data_mpi_copy, _gcry_ac_data_set, _gcry_ac_data_get_name)
+ (_gcry_ac_data_get_index, ac_data_construct): Adjust handling of
+ NAME accordingly.
+
+2007-04-20 Werner Koch <wk@g10code.com>
+
+ * ecc.c (domain_parms): Add standard brainpool curves.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * ecc.c (generate_curve): Implement alias mechanism.
+
+ * pubkey.c (sexp_elements_extract_ecc): New.
+ (sexp_to_key): Add special case for ecc.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_genkey): Replace
+ name_terminated stuff by a call to _gcry_sexp_nth_string.
+ (gcry_pk_get_keygrip): Ditto.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
+
+2007-04-13 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (ac_data_construct): Cast const away to suppress compiler
+ warning.
+
+ * ecc.c (ecc_generate): Avoid compiler warning for unused argument
+ DUMMY.
+ (ecc_verify): Avoid compiler warning for unused arguments CMP and
+ OPAQUEV.
+
+2007-04-06 Werner Koch <wk@g10code.com>
+
+ * sha1.c (oid_spec_sha1): Add another oid from X9.62.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
+ empty.
+ (gcry_pk_genkey): New parameter "curve".
+
+ * ecc.c: Entirely rewritten with only a few traces of the old
+ code left.
+ (_gcry_ecc_generate): New.
+ (generate_key) New arg NAME.
+ (generate_curve): Ditto. Return actual number of NBITS.
+
+2007-03-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a
+ runtime bounds check.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * ecc.c (ecc_ctx_init, ecc_ctx_free, ecc_mod, ecc_mulm): New.
+ (duplicate_point, sum_points, escalar_mult): Don't use a
+ copy of base->p. Replaced all mpi_mulm by ecc_mulm so that we can
+ experiment with different algorithms.
+ (generate_key, check_secret_key, sign, verify): Initialize a
+ computation context for use by ecc_mulm.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_table): Initialize ECC.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc.c.
+ * ecc.c: New. Heavily reformatted and changed for use in libgcrypt.
+ (point_init): New.
+ (escalar_mult): Make arg R the first arg to be similar to the mpi
+ functions.
+ (duplicate_point): Ditto
+ (sum_points): Ditto
+ (sign, verify): Remove unneeded copy operations.
+ (sum_points): Removed memory leaks and optimized some compares.
+ (verify): Simplified input check.
+
+2007-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (MASK_LEVEL): Removed macro as it was used only at one
+ place. Open coded it there.
+ (gcry_randomize, _gcry_update_random_seed_file)
+ (_gcry_fast_random_poll): Factor lock code out to ..
+ (lock_pool, unlock_pool): .. new.
+ (initialize): Look the pool while allocating.
+ (read_random_source, do_fast_random_poll): Moved intialization to ...
+ (initialize): .. here.
+ (_gcry_enable_quick_random_gen): No more need for initialization.
+ (is_initialized): Moved this global flag to ..
+ (initialize): .. here and changed all users to unconditionally call
+ initialize.
+ (add_randomness): Remove initalization here. It simply can't
+ happen.
+
+ * random.c (enum random_origins): Moved to ..
+ * rand-internal.h: .. here.
+ * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
+ for ORIGIN and renamed REQUESTOR to ORIGIN.
+ * rndegd.c (_gcry_rndegd_gather_random): Ditto.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
+ * rndw32.c (_gcry_rndw32_gather_random): Ditto.
+ (_gcry_rndw32_gather_random_fast): Ditto.
+
+2007-03-13 Werner Koch <wk@g10code.com>
+
+ * random.c (enum random_origins): New.
+ (add_randomness): Renamed arg SOURCE to ORIGIN.
+ (read_random_source): Renamed arg REQUESTOR to ORIGIN.
+ (getfnc_gather_random): Removed static variable because this
+ function is only called one and thus we don't need this
+ optimization.
+ (_gcry_quick_random_gen): Removed and replaced by..
+ (_gcry_enable_quick_random_gen): .. this. It is onlyu used to
+ enable it and it does not make sense to disable it later. Changed
+ the only one caller too.
+ (get_random_bytes): Removed.
+ (gcry_random_bytes, gcry_random_bytes_secure): Implement in terms
+ of gcry_randomize.
+ * random-daemon.c (_gcry_daemon_get_random_bytes): Removed.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * elgamal.c (generate): Removed unused variable TEMP.
+ (test_keys): New arg NODIE.
+ (generate_using_x, _gcry_elg_generate_using_x): New.
+ * pubkey.c (pubkey_generate): New arg XVALUE and direct call to
+ the new elgamal generate fucntion.
+ (gcry_pk_genkey): Parse the new "xvalue" tag.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Handle dynamically allocated
+ algorithms. Suggested by Neil Dunbar. Fixes bug#596.
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): Make it return void.
+
+ * cipher.c (gcry_cipher_algo_name): Simplified.
+
+ * random.c: Use the daemon only if compiled with USE_RANDOM_DAEMON.
+
+ * Makefile.am (libcipher_la_SOURCES): Build random-daemon support
+ only if requested.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * random.c (rndpool, keypool): Make unsigned.
+ (mix_pool): Change char* variables to unsigned char*.
+ (gcry_randomize): Make arg BUFFER a void*.
+ (gcry_create_nonce): Ditto.
+
+ * rmd160.c (gcry_rmd160_mixblock): Make BUFFER a void*.
+ (_gcry_rmd160_hash_buffer): Make OUTBUF and BUFFER void*.
+ * sha1.c (_gcry_sha1_hash_buffer): Ditto.
+
+ * cipher.c (gcry_cipher_encrypt, cry_cipher_decrypt): Change
+ buffer args to void*.
+ (gcry_cipher_register): Make ALGORITHM_ID a int *.
+
+ * md.c (md_start_debug): Make SUFFIX a const char*. Use snprintf.
+ (gcry_md_debug): New.
+ (gcry_md_ctl): Changed arg BUFFER from unsigned char*.
+
+ * md.c (md_write): Make INBUF a const void*.
+ (gcry_md_write): Remove needless cast.
+ * crc.c (crc32_write): Make INBUF a const void*
+ (update_crc32, crc24rfc2440_write): Ditto.
+ * sha512.c (sha512_write, transform): Ditto.
+ * sha256.c (sha256_write, transform): Ditto.
+ * rmd160.c (rmd160_write, transform): Ditto.
+ * md5.c (md5_write, transform): Ditto.
+ * md4.c (md4_write, transform): Ditto.
+ * sha1.c (sha1_write, transform): Ditto.
+
+ * tiger.c (tiger_write, transform): Ditto.
+ * whirlpool.c (whirlpool_write, whirlpool_add, transform): Ditto.
+
+ * elgamal.c (elg_names): Change to a const*.
+ * dsa.c (dsa_names): Ditto.
+ * rsa.c (rsa_names): Ditto.
+ * pubkey.c (gcry_pk_lookup_func_name): Make ALIASES a const.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (open_device): Remove unsused arg MINOR.
+
+2007-01-30 Werner Koch <wk@g10code.com>
+
+ * sha256.c (oid_spec_sha256): Add alias from pkcs#1.
+ * sha512.c (oid_spec_sha512): Ditto.
+ (oid_spec_sha384): Ditto.
+
+2006-12-18 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (set_cloexec_flag): New.
+ (open_device): Set close-on-exit flags. Suggested by Max
+ Kellermann. Fixes Debian#403613.
+
+ * Makefile.am (AM_CPPFLAGS, AM_CFLAGS): Splitted and merged
+ Moritz' changes.
+ (INCLUDES): Removed.
+
+2006-11-30 Werner Koch <wk@g10code.com>
+
+ * serpent.c (byte_swap_32): Remove trailing semicolon.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (INCLUDES): Include ../src/
+
+2006-11-03 Werner Koch <wk@g10code.com>
+
+ * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not
+ sys/times.h. Reported by Rafaël Carré.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-25 Werner Koch <wk@g10code.com>
+
+ * primegen.c (prime_generate_internal): Tweaked use of secure
+ memory and entropy use. Safe unused primes from the pool. Allocate
+ at least a pool of 30.
+ (save_pool_prime, get_pool_prime): New.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
+ means. Release sexp_cur if needed. Reported by Dirk Stoecker.
+
+ * pubkey.c (pubkeys_registered_lock): Intialized it. It is not
+ realy needed because this is a mere initialization to 0 anyway.
+ Noted by Victor Stinner.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate2): New.
+ (generate): New arg QBITS. Add sanity checks for reasonable qbits
+ and nbits.
+ * pubkey.c (gcry_pk_genkey): Parse an qbits element.
+ (pubkey_generate): New arg QBITS. Pass it to the DSA generation.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * md.c (gcry_md_algo_info) <get_asnoid>: Check that the algo is
+ available.
+
+2006-10-04 David Shaw <dshaw@jabberwocky.com> (wk)
+
+ * tiger.c (round): Rename to tiger_round as gcc 4 has a built-in
+ round function that this conflicts with.
+
+2006-09-11 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (slow_gatherer_windowsNT): While adding data use the
+ size of the diskPerformance and not its address. Has been fixed in
+ GnuPG more than a year ago. Noted by Lee Fisher.
+
+2006-08-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as
+ this is the canonical name.
+
+2006-08-29 Hye-Shik Chang <perky@FreeBSD.org> (wk)
+
+ * seed.c: New.
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): Don't
+ initialize the socket. Remove arg SOCKETNAME.
+ (connect_to_socket): Make sure that daemon is set to -1 on error.
+ (call_daemon): Initialize the socket on the first call.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): New arg SOCKETNAME.
+ * random.c (initialize): Call new daemon initializator.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket
+ name to daemon call and reset allow_daemon on failure.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call.
+
+ * blowfish.c (selftest): Cast string to usnigned char*.
+
+ * primegen.c (prime_generate_internal): Cast unsigned/char*
+ mismatch in calling m_out_of_n.
+ (is_prime): Changed COUNT to unsigned int *.
+
+ * ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
+
+ * random.c (gcry_create_nonce): Update the pid after a fork.
+ Reported by Uoti Urpala.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * sha512.c: Fix typo in copyright notice.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
+ * pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt)
+ (gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto.
+ * md.c (md_copy): Ditto.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): New argument:
+ SOCKETNAME. Passing on to connect_to_socket() if non-NULL.
+ (connect_to_socket, writen, readn, call_daemon): New functions.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): Call call_daemon().
+ (RANDOM_DAEMON_SOCKET): New symbol.
+ (daemon_socket): New static variable.
+
+ * random.h (_gcry_daemon_initialize_basics): New parameter:
+ SOCKETNAME.
+ (_gcry_set_random_daemon_socket): New declaration.
+
+ * random.c (initialize_basics): Pass DAEMON_SOCKET_NAME to
+ _gcry_daemon_initialize_basics.
+ (_gcry_set_random_daemon_socket): New function, setting
+ DAEMON_SOCKET_NAME.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (eme_pkcs_v1_5_encode): Use KEY_SIZE directly, no need to
+ call gcry_ac_key_get_nbits.
+ (eme_pkcs_v1_5_decode): Likewise.
+ (ac_es_dencode_prepare_pkcs_v1_5): Fill options_em structure with
+ key_size.
+ (_gcry_ac_data_dump, gcry_ac_data_dump): New functions.
+ (_gcry_ac_data_to_sexp, _gcry_ac_data_from_sexp): More or less
+ rewritten; changed S-Expression format so that it matches the one
+ used in pubkey.c.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c: New.
+ * random.c (_gcry_use_random_daemon): New.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Try
+ diverting to the daemon functions.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (lock_seed_file): New.
+ (read_seed_file, _gcry_update_random_seed_file): Use it.
+
+ * random.c (gcry_create_nonce): Detect a fork and re-seed.
+ (read_pool): Fixed the fork detection; it used to work only for
+ multi-threaded processes.
+
+2006-03-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * md.c (md_open): Use new variable macpads_Bsize instead of
+ hardwiring the block size. Changed at all places.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2005-04-22)
+
+ * md.c, sha256.c: Add support for SHA-224.
+ (sha224_init): New.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
+ (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
+ unknown algorithm IDs.
+ * cipher.c (cipher_algo_to_string): Likewise.
+
+2005-11-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
+ case.
+
+2005-09-19 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add preliminary support for 2 and 4 keys.
+ Return an error code if the key size is not supported.
+ (_gcry_dsa_generate): Return an error.
+
+2005-08-22 Werner Koch <wk@g10code.com>
+
+ * primegen.c (check_prime): New arg RM_ROUNDS.
+ (prime_generate_internal): Call it here with 5 rounds as used
+ before.
+ (gcry_prime_check): But here with 64 rounds.
+ (is_prime): Make sure never to use less than 5 rounds.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_init): New function.
+
+2005-04-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
+ make the compiler happy.
+ Always use errno, now that gcry_malloc() is guaranteed to set
+ errno on failure.
+ (_gcry_ac_data_to_sexp): Don't forget to goto out after error in
+ loop.
+ (_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
+ (_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
+ (_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
+ (_gcry_ac_data_from_sexp): Handle special case, which is
+ necessary, since gcry_sexp_nth() does not distinguish between
+ "element does not exist" and "element is the empty list".
+ (_gcry_ac_io_init_va): Use assert to make sure that mode and type
+ are correct.
+ Use gcry_error_t types where gcry_err_code_t types have been used
+ before.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
+ buffer.
+
+ * whirlpool.c: New file.
+ * md.c (digest_table): Add whirlpool.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
+ length of SEXP; do not forget to set SEXP_TMP to NULL after it has
+ been released.
+
+ (struct gcry_ac_mpi): New member: name_provided.
+ (_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
+ remove const qualifier; change code to not cast away const
+ qualifiers; use name_provided member as well.
+ (_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
+ member of named mpi structure.
+
+ (gcry_ac_name_to_id): Do not forget to initialize err.
+ (_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
+ use gcry_free() instead of free(); remove unnecessary cast; rename
+ mpi_return and name_return to mpi_cp and name_cp; adjust code.
+ (ac_data_mpi_copy): Do not cast away const qualifier.
+ (ac_data_values_destroy): Likewise.
+ (ac_data_construct): Likewise.
+
+ (ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
+ (ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
+ GCRY_AC_FLAG_COPY.
+
+ (_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
+ (gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
+ (_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
+ (gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
+ memroy strings directly; adjust encode/decode functions to use io
+ objects.
+ (emsa_pkcs_v1_5_encode_data_cb): New function ...
+ (emsa_pkcs_v1_5_encode): ... use it here.
+ (ac_data_dencode): Use io objects.
+ (_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
+ (gcry_ac_data_decode): Likewise.
+ (_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
+ (_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
+ (_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
+ Likewise.
+
+2005-03-23 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
+ use the size of the object and not the one of its address. Bug
+ reported by Sascha Kiefer.
+
+2005-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
+ which is to be used later on. This happend, in case CTS is
+ enabled and OUTBUF is equal to INBUF.
+
+2005-02-25 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Updated from 1.2 branch:
+
+ s/u32_t/u32/ and s/byte_t/byte/. Too match what we have always
+ used and are using in all other files too
+ (serpent_test): Moved prototype out of a fucntion.
+
+2005-02-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Major parts rewritten.
+ * pubkey.c (_gcry_pk_get_elements): New function.
+
+2004-12-09 Werner Koch <wk@g10code.com>
+
+ * serpent.c (serpent_setkey): Moved prototype of serpent_test to
+ outer scope.
+
+2004-09-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Do not include <assert.h>.
+ * rndegd.c: Likewise.
+ * sha1.c: Likewise.
+ * rndunix.c: Likewise.
+ * rndlinux.c: Likewise.
+ * rmd160.c: Likewise.
+ * md5.c: Likewise.
+ * md4.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * pubkey.c (dummy_generate, dummy_check_secret_key)
+ (dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
+ err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
+ log_bug().
+ (dummy_get_nbits): Return 0 instead of aborting though log_bug().
+
+2004-08-19 Werner Koch <wk@g10code.de>
+
+ * pubkey.c (sexp_data_to_mpi): Changed the zero random byte
+ substituting code to actually do clever things. Thanks to
+ Matthias Urlichs for noting the implementation problem.
+
+2004-08-09 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
+ Modestas Vainius.
+
+2004-07-16 Werner Koch <wk@gnupg.org>
+
+ * rijndael.c (do_encrypt): Fix alignment problem. Bugs found by
+ Matthias Urlichs.
+ (do_decrypt): Ditto.
+ (keySched, keySched2): Use 2 macros along with unions in the key
+ schedule context.
+
+2004-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a". Thanks to
+ Nikos Mavroyanopoulos.
+
+2004-05-09 Werner Koch <wk@gnupg.org>
+
+ * random.c (read_pool): Mix the PID in to better protect after a
+ fork.
+
+2004-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Use "u32_t" instead of "unsigned long", do not
+ declare S-Box variables as "register". Fixes failure on
+ OpenBSD/sparc64, reported by Nikolay Sturm.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Factored out some code to ..
+ (initialize_basics): .. new function.
+ (_gcry_random_initialize): Just call initialize_basics unless the
+ new arg FULL is set to TRUE.
+ (_gcry_fast_random_poll): Don't do anything unless the random
+ system has been really initialized.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * ac.c (gcry_ac_open): Do not dereference NULL pointer. Reported
+ by Umberto Salsi.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
+ at different stages. Pass these arguments through all callers.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * des.c: Add a new OID as used by pkcs#12.
+
+ * rfc2268.c: New. Taken from libgcrypt.
+ * cipher.c: Setup the rfc2268 algorithm.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (prime_generate_internal): Do not forget to free
+ `q_factor'; fixed by Brieuc Jeunhomme.
+ (prime_generate_internal): Do not forget to free `prime'.
+
+2004-01-14 Moritz Schulte <mo@g10code.com>
+
+ * ac.c (gcry_ac_data_set): New argument: flags; slightly
+ rewritten.
+ (gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
+ (gcry_ac_key_pair_generate): New argument: misc_data; modified
+ order of arguments.
+ (gcry_ac_key_test): New argument: handle.
+ (gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
+ Use GCRY_AC_FLAG_NO_BLINDING instead of
+ GCRY_AC_DATA_FLAG_NO_BLINDING.
+ (gcry_ac_mpi): New member: flags.
+ (gcry_ac_data_search, gcry_ac_data_add): Removed functions.
+
+2003-12-22 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (is_prime): Release A2.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * md.c: Moved a couple of functions down below the data structure
+ definitions.
+ (struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
+ (md_open): Set it here.
+ (strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
+ (md_enable): Set it here.
+ (md_close): Wipe the context memory.
+ secure memory.
+ * cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
+ (gcry_cipher_open): Set it here.
+ (gcry_cipher_close): Use it to always wipe out the handle data.
+
+ * ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
+ the function is not successful.
+ (gcry_ac_close): Allow a NULL handle.
+ (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
+ (gcry_ac_key_get_grip): Return INV_OBJ on error.
+
+ * primegen.c (prime_generate_internal): Fixed error code for
+ failed malloc. Replaced the !err if chain by gotos.
+ (gcry_prime_group_generator): Remove the extra sanity check.
+
+ * md.c: Minor code and comment cleanups.
+
+2003-12-16 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Doc fix. Thanks to Newton Hammet.
+
+2003-12-11 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (slow_poll): Don't use #warning but #error.
+
+ * rndegd.c: Changed indentation.
+ (my_make_filename): Removd the var_arg cruft becuase we
+ don't need it here. Changed caller.
+
+ * rndlinux.c: Changed indentation.
+ (open_device): Remove the superfluous stat call and clarify
+ comment.
+
+ * rsa.c: Changed indentation.
+ (secret): Use the standard algorithm if p, q and u are not
+ available.
+ (rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
+ _gcry_rsa_unblind and moved more to the top.
+
+ * md4.c: Changed indentation. Removed unnecessary casts.
+ * md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
+ * rijndael.c, twofish.c: Ditto.
+ * serpent.c: Removed unnecessary casts.
+ * sha256.c, sha512.c: Ditto.
+
+2003-12-09 Werner Koch <wk@gnupg.org>
+
+ * dsa.c: Unified indentation style.
+ * elgamal.c: Ditto.
+ * des.c (des_key_schedule): Code beautifications.
+ * blowfish.c: Changed indentation style.
+ * cast5.c (do_cast_setkey): Ditto.
+
+ * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
+ by straightforward gotos. Other cleanups.
+ (gcry_pk_decrypt): Ditto.
+ (gcry_pk_sign): Ditto.
+ (gcry_pk_verify): Ditto.
+ (gcry_pk_genkey): Ditto. Use strtoul instead of strtol.
+ (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
+
+2003-12-07 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_register_default): Undef the helper macro.
+ (gcry_pk_map_name): Allow NULL for string.
+ (sexp_to_key): Use memcpy and not strncpy. Use gcry_free and not
+ free.
+ (sexp_to_sig): Ditto.
+ (sexp_to_enc): Ditto. Replaced the chain of if(!err) tests by
+ straightforward gotos.
+
+2003-12-05 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Documentation cleanups.
+ (gcry_cipher_mode_from_oid): Allow NULL for STRING.
+
+2003-12-03 Werner Koch <wk@gnupg.org>
+
+ * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
+ only used for encryption.
+
+2003-11-18 Werner Koch <wk@gnupg.org>
+
+ * random.h (rndw32_set_dll_name): Removed unused prototype.
+
+ * Makefile.am (EXTRA_DIST): Added Manifest.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * Manifest: New.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Use shortcut for SHA1
+ * sha1.c (_gcry_sha1_hash_buffer): New.
+
+ * random.c: Reformatted most functions.
+ (mix_pool): Moved the failsafe_digest from global
+ scope to here.
+ (do_fast_random_poll): Use the generic fucntions even if a fast
+ gathering function has been used.
+ (read_pool): Detect a fork and retry.
+ (gcry_randomize, get_random_bytes): Don't distinguish anymore
+ between weak and strong random.
+ (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
+ disk performance values and not the W32 API structure.
+
+ * dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
+ * elgamal.c (verify): Ditto.
+
+ * ac.c (gcry_ac_data_get_index): s/index/idx/
+ (gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
+ (gcry_ac_data_add): Must use gcry_realloc instead of realloc.
+ * pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
+ forehackers.
+ (gcry_pk_encrypt): Removed shadowed definition of I. Reordered
+ arguments to malloc for clarity.
+ (gcry_pk_sign, gcry_pk_genkey): Ditto.
+ * primegen.c (prime_generate_internal): s/random/randomlevel/.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Return if buflen is zero to
+ avoid gcc warning about unsed parameter.
+ (MASK_LEVEL): Simplified; does now work for signed and unsigned
+ w/o warnings.
+
+ * md.c (md_start_debug): Removed the const from SUFFIX, because
+ this function is called from the control fucntion which does not
+ require const.
+
+ Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
+ _gcry_.
+
+ * ac.c (ac_key_identifiers): Made static.
+
+ * random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
+ prototypes to ..
+ * rand-internal.h: .. here
+ * random.c (getfnc_gather_random): Include rndw32 gatherer.
+ * rndunix.c, rndw32.c, rndegd.c: Include them here.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
+ prefix. Changed all callers.
+ * rndegd.c (_gcry_rndegd_gather_random): Likewise.
+ (_gcry_rndegd_connect_socket): Likewise.
+ * rndunix.c (_gcry_rndunix_gather_random): Likewise.
+ (waitpid): Made static.
+ * rndw32.c: Removed the old and unused winseed.dll cruft.
+ (_gcry_rndw32_gather_random_fast): Renamed from
+ gather_random_fast.
+ (_gcry_rndw32_gather_random): Renamed from gather_random. Note,
+ that the changes 2003-04-08 somehow got lost.
+
+ * sha512.c (sha512_init, sha384_init): Made static.
+
+ * cipher.c (do_ctr_decrypt): Removed "return" from this void
+ function.
+
+2003-10-24 Moritz Schulte <mo@g10code.com>
+
+ * serpent.c: Fix an issue on big-endian systems.
+
+ * rndw32.c: Removed IS_MODULE -cruft.
+ * rndlinux.c (rndlinux_gather_random): Likewise.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Bail out if NBITS is less than 16.
+ (prime_generate_internal): Initialize prime variable to suppress
+ compiler warning. Check pbits, initialize qbits when passed as
+ zero.
+
+ * primegen.c (prime_generate_internal): New arg
+ ALL_FACTORS. Changed all callers.
+ (gcry_prime_generate): Make the factors arg optional. Request
+ all_factors. Make sure PRIME is set to NULL even on error.
+ (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-06 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Assert that NBITS is never zero, it
+ would cause a segv.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * ac.c: Include "cipher.h".
+
+2003-09-27 Moritz Schulte <mo@g10code.com>
+
+ * rndegd.c (do_read): Return nread instead of nbytes; thanks to
+ Michael Caerwyn.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (_gcry_pk_aliased_algo_name): New.
+ * ac.c (gcry_ac_open): Use it here.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (gcry_prime_check, gcry_prime_generate): New
+ functions.
+ (prime_generate_internal): New function, based on
+ _gcry_generate_elg_prime.
+ (_gcry_generate_elg_prime): Rewritten as a wrapper for
+ prime_generate_internal.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
+ return value. This does not make sense and breaks any programs
+ parsing the output strictly (e.g. current gpgsm).
+ (gcry_pk_encrypt): If aliases for the algorithm name exists, take
+ the first one instead of the regular name to adhere to SPKI
+ conventions.
+ (gcry_pk_genkey): Ditto.
+ (gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
+
+2003-08-19 Moritz Schulte <mo@g10code.com>
+
+ * cipher.c: Add support for Serpent
+ * serpent.c: New file.
+
+2003-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
+
+2003-08-09 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
+ two times, but also the NAME_OF_DEV_URANDOM device.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
+ fail if no `flags' sub S-Expression is found.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
+
+2003-07-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_construct): New argument: include_flags, only
+ include `flags' S-expression, if include_flags is true. Adjust
+ callers. Thanks for triggering a bug caused by `flags'
+ sub-S-expression where they are not expected to Ralf Schneider.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_lookup_func_name): Use new member name
+ `aliases' instead of `sexp_names'.
+
+ * ac.c (gcry_ac_key_data_get): New function.
+
+ * cipher.c (gcry_cipher_lookup_func_name): Fix return value.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
+ * cast5.c: Likewise.
+ * twofish.c: Likewise.
+ * arcfour.c: Likewise.
+ * rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
+ New variables, adjust for new gcry_cipher_spec_t structure.
+ * des.c (oids_tripledes): New variable, adjust for new
+ gcry_cipher_spec_t structure.
+
+ * md.c (oid_table): Removed.
+
+ * tiger.c (oid_spec_tiger): New variable.
+ (digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha512): New variable.
+ (digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha384): New variable.
+ (digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
+
+ * sha256.c (oid_spec_sha256): New variable.
+ (digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
+
+ * sha1.c (oid_spec_sha1): New variable.
+ (digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
+
+ * rmd160.c (oid_spec_rmd160): New variable.
+ (digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
+
+ * md5.c (oid_spec_md5): New variable.
+ (digest_spec_md5): Adjusted for new gry_md_spec_t structure.
+
+ * md4.c (oid_spec_md4): New variable.
+ (digest_spec_md4): Adjusted for new gry_md_spec_t structure.
+
+ * crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
+ digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
+ structure.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_lookup_func_oid): New function.
+ (search_oid): New function, copied from cipher.c.
+ (gcry_md_map_name): Adjust for new search_oid_interface.
+
+ * cipher.c (oid_table): Removed table.
+ (gcry_cipher_lookup_func_oid): New function.
+ (search_oid): Rewritten to use the module functions.
+ (gcry_cipher_map_name): Adjust for new search_oid interface.
+ (gcry_cipher_mode_from_oid): Likewise.
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
+ gpg_strerror.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
+ name aliases, not just the primary name.
+ (gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
+ AES.
+
+ * arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
+ specification structures.
+
+ * rijndael.c (rijndael_names, rijndael192_names,
+ rijndael256_names): New variables, use them in the cipher
+ specifications.
+
+ * rmd160test.c: Removed file.
+
+ * ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
+ elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
+ Used gcry_err* wrappers for libgpg symbols.
+
+ * primegen.c (gen_prime): Correct the order arguments to
+ extra_check.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Replaced all public occurences of gpg_error_t with
+ gcry_error_t.
+ * cipher.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * random.c: Likewise.
+
+ * cipher.c: Added support for TWOFISH128.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_copy_internal): New function, based on
+ gcry_ac_data_copy.
+ (gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
+ (gcry_ac_key_init): Use gcry_ac_data_copy_internal.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_set): Only release old MPI value if it is
+ different from the new value. Bug reported by Simon Josefsson
+ <jas@extundo.com>.
+
+ * pubkey.c (gcry_pk_list): New function.
+ * md.c (gcry_md_list): New function.
+
+ * ac.c (gcry_ac_key_pair_generate): Fix calculation of format
+ string size.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * md.c: Named struct of digest_table `digest_table_entry'.
+ (digest_table_entry): New member: algorithm; filled in.
+ (digest_table_entry): Removed unused member: flags.
+ (gcry_md_register): New argument: algorithm_id, filled in.
+ (gcry_md_register_default): Used algorithm ID from module
+ structure.
+ (gcry_md_map_name): Likewise.
+ (md_enable): Likewise.
+ (md_read): Likewise.
+ (gcry_md_info): Likewise.
+
+ * pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
+ (pubkey_table_entry): New member: algorithm; filled in.
+ (gcry_pk_register_default): Used algorithm ID from pubkey_table.
+ (gcry_pk_register): New argument: algorithm_id, filled in.
+ (gcry_pk_map_name): Used algorithm ID from module structure.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (sexp_to_key): Removed unused variable: algo.
+ (sexp_to_sig): Likewise.
+
+ * cipher.c: Named struct for cipher_table `cipher_table_entry'.
+ (cipher_table_entry): New member: algorithm; filled in.
+ (gcry_cipher_register_default): Used algorithm ID from
+ cipher_table.
+ (gcry_cipher_register): New argument: algorithm_id, filled in.
+ (gcry_cipher_map_name): Used algorithm ID from module structure.
+
+ * arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+ * cast5.c (cipher_spec_cast5): Likewise.
+ * crc.c (digest_spec_crc32): Likewise.
+ * crc.c (digest_spec_crc32_rfc1510): Likewise.
+ * crc.c (digest_spec_crc32_rfc2440): Likewise.
+ * des.c (cipher_spec_des): Likewise.
+ * des.c (cipher_spec_tripledes): Likewise.
+ * dsa.c (pubkey_spec_dsa): Likewise.
+ * elgamal.c (pubkey_spec_elg): Likewise.
+ * md4.c (digest_spec_md4): Likewise.
+ * md5.c (digest_spec_md5): Likewise.
+ * aes.c (cipher_spec_aes): Likewise.
+ * aes.c (cipher_spec_aes192): Likewise.
+ * aes.c (cipher_spec_aes256): Likewise.
+ * rsa.c (pubkey_spec_rsa): Likewise.
+ * sha1.c (digest_spec_sha1): Likewise.
+ * sha256.c (digest_spec_sha256): Likewise.
+ * sha512.c (digest_spec_sha512): Likewise.
+ * tiger.c (digest_spec_tiger): Likewise.
+ * twofish.c (cipher_spec_twofish): Likewise.
+ * twofish.c (cipher_spec_twofish128): Likewise.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
+ files; reported by Simon Josefsson <jas@extundo.com>.
+
+ * pubkey.c: Replaced all occurences of `id' with `algorithm',
+ since `id' is a keyword in obj-c.
+ * md.c: Likewise.
+ * cipher.c: Likewise.
+
+ * crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
+ Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
+
+ * dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
+ gcry_pubkey_spec_t with gcry_pk_spec_t.
+
+ * md.c: Replaced all occurences of gcry_digest_spec_t with
+ gcry_md_spec_t.
+ (gcry_digest_register_default): Renamed to ...
+ (gcry_md_register_default): ... this; adjusted callers.
+ (gcry_digest_lookup_func_name): Renamed to ...
+ (gcry_md_lookup_func_name): ... this; adjusted callers.
+ (gcry_digest_lookup_name): Renamed to ...
+ (gcry_md_lookup_name): ... this; adjusted callers.
+ (gcry_digest_register): Renamed to ...
+ (gcry_md_register): ... this.
+ (gcry_digest_unregister): Renamed to ...
+ (gcry_md_unregister): ... this.
+
+ * pubkey.c (gcry_pubkey_register): Renamed to ...
+ (gcry_pk_register): ... this.
+ (gcry_pubkey_unregister): Renamed to ...
+ (gcry_pk_unregister): ... this.
+ Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
+ (gcry_pubkey_register_default): Renamed to ...
+ (gcry_pk_register_default): ... this; adjusted callers.
+ (gcry_pubkey_lookup_func_name): Renamed to ...
+ (gcry_pk_lookup_func_name): ... this; adjusted callers.
+ (gcry_pubkey_lookup_name): Renamed to ...
+ (gcry_pk_lookup_name): ... this; adjusted callers.
+
+ * md.c (gcry_md_hash_buffer): Fix error checking. Thanks to Simon
+ Josefsson <jas@extunde.com>.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_list): New function.
+
+2003-07-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
+ consistent with sexp_to_enc.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Added: ac.c.
+
+ * pubkey.c (_gcry_pk_module_lookup): New function.
+ (_gcry_pk_module_release): New function.
+
+2003-06-29 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: New file.
+
+2003-06-26 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
+
+2003-06-19 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_is_enabled): Fixed.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_get_algo_keylen): New.
+ (gcry_cipher_get_algo_blklen): New.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
+ rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
+ Replaced older types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec with newer types: gcry_digest_spec_t,
+ gcry_cipher_spec_t and gcry_pubkey_spec_t.
+
+ * md.c (gcry_digest_id_new): Removed function.
+ (gcry_digest_register): Removed code for generating a new module
+ ID.
+
+ * pubkey.c (gcry_pubkey_id_new): Removed function.
+ (gcry_pubkey_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
+ one: gcry_module_t.
+ (gcry_cipher_id_new): Removed function.
+ (gcry_cipher_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c (gcry_cipher_register): Adjust call to
+ _gcry_module_add.
+ (gcry_cipher_register_default): Likewise.
+ * pubkey.c (gcry_pubkey_register_default): Likewise.
+ (gcry_pubkey_register): Likewise.
+ * md.c (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+
+ * md.c (gcry_digest_lookup_func_id): Removed function.
+ (gcry_digest_lookup_id): Likewise.
+ (gcry_digest_id_new): Use _gcry_module_lookup_id instead of
+ gcry_digest_lookup_id.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+ * pubkey.c (gcry_pubkey_lookup_id): Removed function.
+ (gcry_pubkey_lookup_func_id): Likewise.
+ (gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
+ gcry_pubkey_id_new.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_lookup_func_id): Removed function.
+ (gcry_cipher_lookup_id): Likewise.
+ (cipher_algo_to_string): use _gcry_module_lookup_id instead of
+ gcry_cipher_lookup_id.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (gcry_cipher_id_new): Likewise.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
+ @GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
+ (libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
+ (libcipher_la_LIBADD): Likewise.
+ (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+ (EXTRA_libcipher_la_SOURCES): Added all conditional sources.
+
+ * md.c (md_open): Use _gcry_fast_random_poll instead of
+ fast_random_poll.
+ * cipher.c (gcry_cipher_open): Likewise.
+
+ * random.h (fast_random_poll): Removed macro.
+
+ * blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
+ tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
+ BIG_ENDIAN_HOST.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * random.c (getfnc_gather_random): Do not special-case
+ USE_ALL_RANDOM_MODULES, make it the default.
+
+ * dsa.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * elgamal.c: Likewise.
+ * primegen.c: Likewise.
+ * pubkey.c: Likewise.
+ * rsa.c: Likewise.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * des.c (des_setkey): Add selftest check.
+ (tripledes_set3keys): Likewise.
+ (do_tripledes_setkey): Remove selftest check.
+ (do_des_setkey): Likewise.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (_gcry_md_init): New function.
+ * cipher.c (_gcry_cipher_init): New function.
+ * pubkey.c (_gcry_pk_init): New function.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_secure): New.
+ (gcry_md_is_enabled): New.
+
+2003-06-12 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
+ error.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_open): Make sure H receives either NULL or an
+ valid handle.
+ (gcry_md_copy): Swapped arguments so that it is more in lione with
+ md_open and most other API fucntions like memcpy (destination
+ comes first). Make sure HANDLE is set to NULL on error.
+
+ * rijndael.c (do_encrypt): Hack to force correct alignment. It
+ seems not to be not sufficient, though. We should rework this
+ fucntions and remove all these ugly casts. Let the compiler
+ optimize or have an assembler implementation.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Removed rules serpent, since that is not commited
+ yet.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
+ format string.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
+ rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
+ rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
+ rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
+ preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
+ gcry_sexp_build_array instead of gcry_sexp_build.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_genkey): Likewise.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
+ does indeed belong to DSA.
+ (_gcry_dsa_sign): Likewise.
+ (_gcry_dsa_verify): Likewise.
+ (_gcry_dsa_get_nbits): Likewise.
+
+ * elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
+ algorithm ID does indeed belong to ElGamal.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ (_gcry_elg_get_nbits): Likewise.
+ (_gcry_elg_generate): Likewise.
+
+ * rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
+ does indeed belong to RSA.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ (_gcry_rsa_get_nbits): Likewise.
+
+2003-05-30 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_get_algo): Return zero in case to algorithm is enabled.
+
+ * md.c (gcry_md_info): Adjusted for new no-errno-API.
+ (md_final): Likewise.
+ (gcry_md_get_algo): Likewise.
+ * pubkey.c (gcry_pk_get_keygrip): Likewise.
+ (gcry_pk_ctl): Likewise.
+ (gcry_pk_algo_info): Likewise.
+ * des.c (selftest): Likewise.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Do not forget to release module on error.
+ (gcry_md_open): Adjusted for new no-errno-API.
+ (md_open): Likewise.
+ (md_copy): Likewise.
+ (gcry_md_copy): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
+ also fixed a locking bug.
+ (gcry_cipher_encrypt): Adjusted for new no-errno-API.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+
+2003-05-28 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Adjusted for libgpg-error.
+ (gcry_md_enable): Likewise.
+ (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+ (check_digest_algo): Likewise.
+ (prepare_macpads): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_ctl): Likewise.
+ (gcry_md_get): Likewise.
+ (gcry_md_algo_info): Likewise.
+ (gcry_md_info): Likewise.
+ * dsa.c (_gcry_dsa_generate): Likewise.
+ (_gcry_dsa_check_secret_key): Likewise.
+ (_gcry_dsa_sign): Likewie.
+ (_gcry_dsa_verify): Likewise.
+ * twofish.c (do_twofish_setkey): Likewise.
+ (twofish_setkey): Likewise.
+ * cipher.c (gcry_cipher_register): Likewise.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * rijndael.c (do_setkey): Adjusted for libgpg-error.
+ (rijndael_setkey): Likewise.
+ * random.c (gcry_random_add_bytes): Likewise.
+ * elgamal.c (_gcry_elg_generate): Likewise.
+ (_gcry_elg_check_secret_key): Likewise.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ * rsa.c (_gcry_rsa_generate): Likewise.
+ (_gcry_rsa_check_secret_key): Likewise.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ * pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
+ dummy_decrypt, dummy_sign, dummy_verify): Likewise.
+ (gcry_pubkey_register): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (sexp_elements_extract): Likewise.
+ (sexp_to_key): Likewise.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+ (sexp_data_to_mpi): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_ctl): Likewise.
+ * cipher.c (dummy_setkey): Likewise.
+ (check_cipher_algo): Likewise.
+ (gcry_cipher_open): Likewise.
+ (cipher_setkey): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (do_cast_setkey): Likewise.
+ * arcfour.c (arcfour_setkey): Likewise.
+ (do_arcfour_setkey): Likewise.
+ * blowfish.c (do_bf_setkey): Likewise.
+ (bf_setkey): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_tripledes_setkey): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c: Merged code ussing the U64_C macro from GnuPG.
+
+ * sha512.c: Likewise.
+
+2003-05-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
+ releasing it.
+
+2003-05-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
+ (gcry_pk_ctl): Likewise.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
+ been used.
+
+ * md.c (gcry_md_get_algo_dlen): Simplified, simply call
+ md_digest_length to do the job.
+
+ * des.c (do_des_setkey): Check for selftest failure not only
+ during initialization.
+ (do_tripledes_setkey): Include check for selftest failure.
+
+ * pubkey.c (gcry_pubkey_register_default): New macro
+ `pubkey_use_dummy', use it.
+
+ * elgamal.c (elg_names): New variable.
+ (pubkey_spec_elg): Include elg_names.
+
+ * dsa.c (dsa_names): New variable.
+ (pubkey_spec_dsa): Include dsa_names.
+
+ * rsa.c (rsa_names): New variable.
+ (pubkey_spec_rsa): Include rsa_names.
+
+ * pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
+ the names listed in `sexp_names'.
+
+2003-04-24 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_key): New variables: module, pubkey. Adjusted
+ to new module interface.
+ (sexp_to_key): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers. Removed argument:
+ r_algotblidx.
+ (sexp_to_sig): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers.
+ (sexp_to_enc): Likewise.
+
+ (pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
+ pubkey_get_nenc): Use strlen to find out the number.
+
+ * rsa.c: Adjust pubkey_spec_rsa to new internal interface.
+ * dsa.c: Likewise.
+ * elgamal.c: Likewise.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_elements_extract): New function.
+ * pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
+ sexp_elements_extract.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+
+ * pubkey.c: Terminate list correctly.
+ * md.c: Include sha512/sha384 in digest_table.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Include support for sha512.c.
+
+ * sha512.c: New file, merged from GnuPG, with few modifications
+ for libgcrypt.
+
+ * rand-internal.h: Removed declarations for constructor functions.
+
+ * md.c (md_copy): Call _gcry_module_use for incrementing the usage
+ counter of the digest modules.
+
+ * rsa.c: Do not include "rsa.h".
+ * dsa.c: Do not include "dsa.h".
+ * elgamal.c: Do not include "elgamal.h".
+ * des.c: Do not include "des.h".
+ * cast5.c: Do not include "cast5.h".
+ * blowfish.c: Do not include "blowfish.h".
+ * arcfour.c: Do not include "arcfour.h".
+
+ * Makefile.am (libcipher_la_DEPENDENCIES): Removed.
+ (libcipher_la_LIBADD): Removed.
+ Use Automake conditionals for conditional compilation.
+
+2003-04-13 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
+
+ * md.c (gcry_md_list): New member: module.
+ (md_enable): New variable: module, changed use of module and
+ digest.
+ (md_enable): Initialize member: module.
+ (md_close): Call _gcry_module_release.
+
+ * cipher.c (gcry_cipher_open): New variable: module, changed use of
+ module and cipher.
+ (struct gcry_cipher_handle): New member: module.
+ (gcry_cipher_open): Initialize member: module.
+ (gcry_cipher_close): Call _gcry_module_release.
+
+2003-04-09 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Include "ath.h".
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+
+ * cipher.c (ciphers_registered_lock): New variable.
+ * md.c (digests_registered_lock): New variable.
+ * pubkey.c (pubkeys_registered_lock): New variable.
+
+ * rndlinux.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndlinux_constructor): Removed function.
+
+ * rndegd.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndegd_constructor): Removed function.
+
+ * rndunix.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndunix_constructor): Removed function.
+
+ * rndw32.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndw32_constructor): Removed function.
+
+ * rndegd.c (rndegd_connect_socket): Simplify code for creating the
+ egd socket address.
+ (rndegd_connect_socket): Call log_fatal use instead of
+ g10_log_fatal.
+ (egd_gather_random): Renamed to ...
+ (rndegd_gather_random): ... here.
+
+2003-04-08 Moritz Schulte <moritz@g10code.com>
+
+ * rndlinux.c: Do not include "dynload.h".
+ * rndunix.c: Likewise.
+ * rndw32.c: Likewise.
+
+ * rndegd.c (rndegd_connect_socket): Factored out from ...
+ (egd_gather_random): here; call it.
+ (egd_socket): New variable.
+ (egd_gather_random): Initialize fd with egd_socket, do not declare
+ fd static.
+ (do_read): Merged few changes from GnuPG. FIXME - not finished?
+ Do not include "dynload.h".
+
+ * rndw32.c (gather_random): Renamed to rndw32_gather_random, do
+ not declare static.
+ (gather_random_fast): Renamed to rndw32_gather_random_fast, do not
+ declare static.
+
+ * rndunix.c (gather_random): Renamed to rndunix_gather_random, do
+ not declare static.
+ * rndegd.c (gather_random): Renamed to rndegd_gather_random, do
+ not declare static.
+ * rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
+ do not declare static.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Removed construct.c.
+ (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
+ md5.c, tiger.c and crc.c
+ (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
+ and crc. Removed definitions: EXTRA_md4_SOURCES,
+ EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
+ EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
+ BUILT_SOURCES, DISTCLEANFILES.
+
+ * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
+
+ * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
+ dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
+
+ * rsa.h: Removed file.
+ * elgamal.h: Removed file.
+ * dsa.h: Removed file.
+ * des.h: Removed file.
+ * cast5.h: Removed file.
+ * arcfour.h: Removed file.
+ * blowfish.h: Removed file.
+
+ * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
+ dynload.h.
+
+ * rsa.c (pubkey_spec_rsa): New variable.
+ * dsa.c (pubkey_spec_rsa): New variable.
+ * elgamal.c (pubkey_spec_elg): New variable.
+
+ * rsa.c (_gcry_rsa_get_info): Removed function.
+ * elgamal.c (_gcry_elg_get_info): Removed function.
+ * dsa.c (_gcry_dsa_get_info): Removed function.
+
+ * tiger.c (tiger_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_tiger_constructor): Removed function.
+
+ * sha1.c (sha1_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha1_constructor): Removed function.
+
+ * sha256.c (sha256_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha256_constructor): Removed function.
+
+ * rmd160.c (rmd160_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rmd160_constructor): Removed function.
+
+ * md5.c (md5_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md5_constructor): Removed function.
+
+ * md4.c (md4_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md4_constructor): Removed function.
+
+ * crc.c (crc_get_info): Removed function.
+
+ * arcfour.c (do_arcfour_setkey): Changed type of context argument
+ to `void *', added local variable for cast, adjusted callers.
+ (arcfour_setkey): Likewise.
+ (encrypt_stream): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (encrypt_block): Likewise.
+ * rijndael.c (rijndael_setkey): Likewise.
+ (rijndael_encrypt): Likewise.
+ (rijndael_decrypt): Likewise.
+ * twofish.c (twofish_setkey): Likewise.
+ (twofish_encrypt): Likewise.
+ (twofish_decrypt): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ * blowfish.c (bf_setkey: Likewise.
+ (encrypt_block): Likewise.
+ (decrypt_block): Likewise.
+
+ * arcfour.c (encrypt_stream): Likewise.
+
+ * rijndael.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * twofish.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * cast5.c (CIPHER_ALGO_CAST5): Removed.
+
+ * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+ (CIPHER_ALGO_BLOWFISH): Removed symbol.
+ * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
+ * des.c (selftest_failed): Removed.
+ (initialized): New variable.
+ (do_des_setkey): Run selftest, if not yet done.
+ (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+
+ * arcfour.c (_gcry_arcfour_get_info): Removed function.
+ * blowfish.c (_gcry_blowfish_get_info): Removed function.
+ * cast5.c (_gcry_cast5_get_info): Removed function.
+ * des.c (_gcry_des_get_info): Removed function.
+ * rijndael.c (_gcry_rijndael_get_info): Removed function.
+ * twofish.c (_gcry_twofish_get_info): Removed function.
+
+ * arcfour.c (cipher_spec_arcfour): New variable.
+ * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
+ variables.
+ * rijndael.c (cipher_spec_aes, cipher_spec_aes192,
+ cipher_spec256): New variables.
+ * des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
+ * cast5.c (cipher_spec_cast5): New variable.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+
+ * twofish.c: Do not include "dynload.h".
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * rijndael.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+
+ * arcfour.c: Include "cipher.h".
+ * twofish.c: Likewise.
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * twofish.c (twofish_setkey): Declared argument `key' const.
+ (twofish_encrypt): Declared argument `inbuf' const.
+ (twofish_decrypt): Likewise.
+
+ * rijndael.c (rijndael_setkey): Declared argument `key' const.
+ (rijndael_encrypt): Declared argument `inbuf' const.
+ (rijndael_decrypt): Likewise.
+
+ * des.c (do_des_setkey): Declared argument `key' const.
+ (do_tripledes_setkey): Likewise.
+ (do_des_encrypt): Declared argument `inbuf' const.
+ (do_des_decrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_decrypt): Likewise.
+
+ * cast5.c (encrypt_block): Declared argument `inbuf' const.
+ (decrypt_block): Likewise.
+ (cast_setkey): Declared argument `key' const.
+
+ * blowfish.c (do_bf_setkey): Declared argument `key' const.
+ (encrypt_block): Declared argument `inbuf' const.
+ (encrypt_block): Likewise.
+
+
+
+ * cipher.c: Remove CIPHER_ALGO_DUMMY related code.
+ Removed struct cipher_table_s.
+ Changed definition of cipher_table.
+ Removed definition of disabled_algos.
+ (ciphers_registered, default_ciphers_registered): New variables.
+ (REGISTER_DEFAULT_CIPHERS): New macro.
+ (dummy_setkey): Declared argument `key' const.
+ (dummy_encrypt_block): Declared argument `inbuf' const.
+ (dummy_encrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_setkey): Use `unsigned char' instead of `byte'.
+ (dummy_encrypt_block): Likewise.
+ (dummy_decrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_decrypt_stream): Likewise.
+ (gcry_cipher_register_default): New function.
+ (gcry_cipher_lookup_func_id): New function.
+ (gcry_cipher_lookup_func_name): New function.
+ (gcry_cipher_lookup_id): New function.
+ (gcry_cipher_lookup_name): New function.
+ (gcry_cipher_id_new): New function.
+ (gcry_cipher_register): New function.
+ (gcry_cipher_unregister): New function.
+ (setup_cipher_table): Removed function.
+ (load_cipher_modules): Removed function.
+ (gcry_cipher_map_name): Adjusted to use new module management.
+ (cipher_algo_to_string): Likewise.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_keylen): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (struct gcry_cipher_handle): Replaced members algo, algo_index,
+ blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
+ member: cipher.
+ (gcry_cipher_open): Adjusted code for new handle structure.
+ (cipher_setkey): Likewise.
+ (cipher_setiv): Likewise.
+ (cipher_reset): Likewise.
+ (do_ecb_encrypt): Likewise.
+ (do_ecb_decrypt): Likewise.
+ (do_cbc_encrypt): Likewise.
+ (do_cbc_decrypt): Likewise.
+ (do_cfb_encrypt): Likewise.
+ (do_cfb_decrypt): Likewise.
+ (do_ctr_encrypt): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (cipher_sync): Likewise.
+ (gcry_cipher_ctl): Likewise.
+
+ * pubkey.c: Removed struct pubkey_table_s.
+ Changed definition of pubkey_table.
+ Removed definition of disabled_algos.
+ (pubkeys_registered, default_pubkeys_registered): New variables.
+ (REGISTER_DEFAULT_PUBKEYS): New macro.
+ (setup_pubkey_table): Removed function.
+ (load_pubkey_modules): Removed function.
+ (gcry_pubkey_register_default): New function.
+ (gcry_pubkey_lookup_func_id): New function.
+ (gcry_pubkey_lookup_func_name): New function.
+ (gcry_pubkey_lookup_id): New function.
+ (gcry_pubkey_lookup_name): New function.
+ (gcry_pubkey_id_new): New function.
+ (gcry_pubkey_register): New function.
+ (gcry_pubkey_unregister): New function.
+ (gcry_pk_map_name): Adjusted to use new module management.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * md.c: Removed struct md_digest_list_s.
+ (digest_list): Changed definition.
+ (digests_registered, default_digests_registered): New variables.
+ (REGISTER_DEFAULT_DIGESTS): New macro.
+ (new_list_item): Removed function.
+ (setup_md_table): Removed function.
+ (load_digest_module): Removed function.
+ (gcry_digest_register_default): New function.
+ (gcry_digest_lookup_func_id): New function.
+ (gcry_digest_lookup_func_name): New function.
+ (gcry_digest_lookup_id): New function.
+ (gcry_digest_lookup_name): New function.
+ (gcry_digest_id_new): New function.
+ (gcry_digest_register): New function.
+ (gcry_digest_unregister): New function.
+ (GcryDigestEntry): New type.
+ (struct gcry_md_context): Adjusted type of `list'.
+ (gcry_md_map_name): Adjusted to use new module management.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
+ PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
+ GCRY_PK_ELG.
+
+ * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
+
+2003-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c (tiger_get_info): Do not declare static.
+ * sha256.c (sha256_get_info): Likewise.
+ * sha1.c (sha1_get_info): Likewise.
+ * rmd160.c (rmd160_get_info): Likewise.
+ * md5.c (md5_get_info): Likewise.
+ * md4.c (md4_get_info): Likewise.
+ * crc.c (crc_get_info): Likewise.
+
+ * md.c (load_digest_module): Call setup_md_table during
+ initialization.
+ (new_list_item): Link new element into digest_list.
+
+ * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
+ for do_ctr_encrypt, since these functions are identical.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (struct gcry_cipher_handle): Add counter field.
+ (gcry_cipher_open): Add CTR.
+ (cipher_reset): Clear counter field.
+ (do_ctr_encrypt, do_ctr_decrypt): New functions.
+ (cipher_encrypt, cipher_decrypt): Call CTR functions.
+ (gcry_cipher_ctl): Add SET_CTR to set counter.
+
+2003-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind): New function.
+ (_gcry_rsa_unblind): New function.
+ (_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
+
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
+ `decrypt' function arguments.
+ (_gcry_enum_gnupgext_pubkeys): Likewise.
+ * dynload.h: Likewise.
+
+ * pubkey.c (dummy_decrypt): Add argument: int flags.
+ (dummy_encrypt): Likewise.
+
+ * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
+ (_gcry_elg_decrypt): Likewise.
+
+ * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
+ (_gcry_rsa_decrypt): Likewise.
+
+ * pubkey.c: Add `flags' argument to members `encrypt' and
+ `decrypt' of struct `pubkey_table_s'.
+
+ * rsa.h: Add `flags' argument to function declarations.
+ * elgamal.h: Likewise.
+
+ * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
+ (sexp_data_to_mpi): Set `parsed_flags'.
+ (sexp_data_to_mpi): New argument: int *flags.
+ (gcry_pk_encrypt): New variable: int flags.
+ (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
+ (pubkey_encrypt): New variable: int flags.
+ (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
+ (pubkey_decrypt): Likewise.
+ (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
+ (gcry_pk_encrypt): Include `flags' s-exp in return list.
+ (sexp_to_enc): New argument: int *flags.
+ (gcry_pk_decrypt): New variable: int flags.
+ (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
+ (sexp_to_enc): New variable: int parsed_flags.
+ (sexp_to_enc): Set `parsed_flags'.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open, do_cbc_encrypt)
+ (gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
+ (gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
+ to allow for a user callback. Changed all callers.
+ (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Ditto, pass them to gen_prime.
+ * rsa.c (check_exponent): New.
+ (generate): Use a callback to ensure that a given exponent is
+ actually generated.
+
+2003-03-12 Moritz Schulte <moritz@g10code.com>
+
+ * primegen.c: Initialize `no_of_small_prime_numbers' statically.
+ (gen_prime): Remove calculation of `no_of_small_prime_numbers'.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_ctl): Rewritten to use same style like the other
+ functions dispatchers.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (struct gcry_cipher_handle): New member: algo_index.
+ (gcry_cipher_open): Allocate memory for two cipher contexts.
+ Initialize algo_index.
+ (cipher_setkey): Duplicate context into reserved memory.
+ (cipher_reset): New function, which resets the context and clear
+ the IV.
+ (gcry_cipher_ctl): Call cipher_reset.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Remove (bogus) `digitp' macro definition.
+ * md.c: Likewise.
+
+ * blowfish.c (burn_stack): Removed.
+ * arcfour.c (burn_stack): Likewise.
+ * cast5.c (burn_stack): Likewise.
+ * des.c (burn_stack): Likewise.
+ * md4.c (burn_stack): Likewise.
+ * md5.c (burn_stack): Likewise.
+ * random.c (burn_stack): Likewise.
+ * rijndael.c (burn_stack): Likewise.
+ * rmd160.c (burn_stack): Likewise.
+ * sha1.c (burn_stack): Likewise.
+ * sha256.c (burn_stack): Likewise.
+ * tiger.c (burn_stack): Likewise.
+ * twofish.c (burn_stack): Likewise.
+
+ * blowfish.c: Changed all occurences of burn_stack to
+ _gcry_burn_stack.
+ * arcfour.c: Likewise.
+ * cast5.c: Likewise.
+ * des.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * random.c: Likewise.
+ * rijndael.c: Likewise.
+ * rmd160.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+ * tiger.c: Likewise.
+ * twofish.c: Likewise.
+
+ * arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
+ instead of hard-coded value `301'.
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_register_random_progress): New.
+ (_gcry_random_progress): New.
+
+ * rndlinux.c (gather_random): Call the random progress function.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): New arg USE_E to request a specific public
+ exponent.
+ (_gcry_rsa_generate): Ditto.
+ * elgamal.c (_gcry_elg_generate): Must add an dummy argument
+ instead of USE_E.
+ * dsa.c (_gcry_dsa_generate): Ditto.
+ * pubkey.c (dummy_generate): Ditto.
+ (pubkey_generate): Add USE_E arg and pass it down.
+ (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
+
+ * pubkey.c (sexp_to_enc): New arg RET_MODERN.
+ (gcry_pk_decrypt): Make use of it to return a real S-expression.
+ Return better error codes.
+ (gcry_pk_verify): Return better error codes.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Add QUALITY argument, let
+ function return an error code and disable its core for now.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (gcry_random_add_bytes): New. Function to add external
+ random to the pool.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * crc.c: New.
+ * Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
+ * md.c (gcry_md_get_algo_dlen): Add values for CRC.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * sha256.c: New.
+ * bithelp.h (ror): New.
+ * Makfile.am: Add sha256.c.
+ * md.c (oid_table): Add values for SHA256 et al.
+ (gcry_md_get_algo_dlen): Likewise
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
+ and ElGamal.
+
+2003-01-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_encrypt): Reworked so that the output will
+ never contain the plaintext even if the caller did not checked the
+ return value.
+
+ * md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
+ because we don't have an invalid md algo but no algorithm enabled.
+
+ * pubkey.c (gcry_pk_genkey): Changed error code for bounds check
+ of table parameters to GCRYERR_INTERNAL.
+
+ * md.c (gcry_md_open): Partly reverted Timo's change from
+ 2002-10-10 by removing the check for the algorithm. An algorithm
+ of 0 is allowed and anyway we should not double check it or check
+ it using a different function. Also fixed the flags check.
+
+ * pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
+ on error.
+ (gcry_pk_decrypt): Ditto for R_PLAIN.
+ (gcry_pk_sign): Ditto for R_SIG.
+ (gcry_pk_genkey): Ditto for R_KEY.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_write): Changed 2nd argument type to void*.
+ (gcry_md_hash_buffer): Changed type of boths buffers to void*.
+ (gcry_md_setkey): Changed 2nd argument type to void*.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (sexp_data_to_mpi): New. This handles pkcs1 padding.
+ (gcry_pk_sign, gcry_pk_verify): Use it here.
+ (gcry_pk_encrypt): And here.
+ (pubkey_verify): Add debug code.
+ (sexp_to_enc): Handle flags in the input and return the pkcs1 flag
+ in a new parameter.
+ (gcry_pk_decrypt): Prepare for future pkcs1 handling.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_random_initialize): New.
+
+2002-12-16 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added a Teletrust specific OID for 3DES.
+
+2002-12-12 Werner Koch <wk@gnupg.org>
+
+ * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
+
+2002-11-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (load_digest_module): Enlarged checked_algos bitmap.
+ * md4.c (func_table): Fixed entry for md4.
+ Both by Simon Josephson.
+ (transform): Copy data to get the alignment straight. Tested only
+ on i386.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open): Don't reject CTS flag.
+ (do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt)
+ (gcry_cipher_encrypt, cipher_decrypt)
+ (gcry_cipher_decrypt): Support CTS flag.
+ (gcry_cipher_ctl): Toggle CTS flag.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * md4.c: New. By Simon Josefsson.
+ * Makefile.am (EXTRA_PROGRAMS): Add md4.c.
+ * md.c (oid_table,gcry_md_get_algo_dlen): MD4 support.
+
+2002-10-14 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Don't use increment op when
+ assigning to the same variable.
+
+2002-10-10 Timo Schulz <ts@winpt.org>
+
+ * pubkey.c (gcry_pk_genkey): Check boundaries.
+
+ * md.c (gcry_md_open): Check that algo is available and only
+ valid flag values are used.
+ (gcry_md_get_algo): Add error handling.
+
+2002-09-26 Werner Koch <wk@gnupg.org>
+
+ * md.c: Include an OID for TIGER.
+ * tiger.c (tiger_get_info): Use a regular OID.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * random.c: Replaced mutex.h by the new ath.h. Changed all calls.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Use register modifier and modulo.
+ According to Nikos Mavroyanopoulos this increases perfromace on
+ i386 system noticable. And I always tought gcc is clever enough.
+ * md5.c (transform): Use register modifier.
+ * rmd160.c (transform): Ditto.
+ * sha1.c (transform): Ditto. We hope that there are 6 free registers.
+ * random.c (gcry_randomize): Rewrote to avoid malloc calls.
+
+ * rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
+ * arcfour.c (do_arcfour_setkey): Ditto.
+ * twofish.c (do_twofish_setkey): Ditto.
+ * rndegd.c (gather_random): Ditto.
+ * rijndael.c (do_setkey): Ditto.
+ * random.c (_gcry_random_dump_stats): Ditto.
+ * primegen.c (_gcry_generate_elg_prime): Ditto.
+ * des.c (_gcry_des_get_info): Ditto.
+ * cast5.c (do_cast_setkey): Ditto.
+ * blowfish.c (do_bf_setkey): Ditto.
+
+2002-08-26 Werner Koch <wk@gnupg.org>
+
+ * des.c (weak_keys): Fixed one entry in the table and compared
+ all entries against the literature.
+ (selftest): Checksum the weak key table.
+
+2002-08-21 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Enable keygrip calculation for "openpgp-rsa".
+
+2002-08-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (setup_cipher_table): Don't overwrite the DES entry
+ with the entry for DUMMY.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
+ (_gcry_des_get_info): Support plain old DES.
+ * cipher.c (setup_cipher_table): Put DES into the table.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
+ Noted by Stephan Austermuehle.
+
+2002-07-08 Timo Schulz <ts@winpt.org>
+
+ * rndw32.c: Replaced the m_ memory functions with the real
+ gcry_ functions. Renamed all g10_ prefixed functions to log_.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Use e = 65537 for now.
+
+2002-06-11 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
+
+2002-06-05 Timo Schulz <ts@winpt.org>
+
+ * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
+ Check that the input size is a multiple of the blocksize.
+
+2002-05-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (oid_table): Add an rsadsi OID for MD5.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * primegen.c, elgamal.c, dsa.c (progress): Do not print anything
+ by default. Pass an extra identifying string to the callback and
+ reserved 2 argumenst for current and total counters. Changed the
+ register function prototype.
+
+2002-05-17 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (rndegd_constructor): Fixed name of register function
+ and prefixed the function name with _gcry_.
+ * rndw32.c (rndw32_constructor): Ditto.
+ * tiger.c (tiger_constructor): Ditto.
+
+ * Makefile.am: Removed all dynamic loading stuff.
+ * dynload.c: Ditto. Now only used for the constructor system.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_bytes,gcry_random_bytes_secure)
+ (gcry_randomize): Make sure we are initialized.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of most files to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_fast_random_poll): Initialize the module so the
+ mutex can be used.
+
+ * primegen.c (small_prime_numbers): Moved table from smallprime.c
+ * smallprime.c: File removed.
+
+ * des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
+
+ * cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
+ * rijndael.c (rijndael_get_info): We do only support a 128 bit
+ blocksize so it makes sense to change the algorithm strings to
+ AES.
+
+ * tiger.c (tiger_final): Removed superfluous token pasting operators.
+ * md5.c (md5_final): Ditto.
+
+2002-04-30 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Fixed list of copyright years.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Initialize the new pool lock mutex.
+ (_gcry_fast_random_poll): Add locking and moved main
+ code out to...
+ (do_fast_random_poll): new function.
+ (read_pool): Use the new function here.
+ (get_random_bytes): Add locking.
+ (_gcry_update_random_seed_file): Ditto.
+
+2002-03-11 Werner Koch <wk@gnupg.org>
+
+ * md.c: Add rsaSignatureWithripemd160 to OID table.
+
+2002-02-20 Werner Koch <wk@gnupg.org>
+
+ * sha1.c: Removed a left over comment note. The code has been
+ rewritten from scratch in 1998. Thanks to Niels Möller for
+ reporting this misleading comment.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (rndunix_constructor): Use the the new prefixed
+ function name. Reported by Jordi Mallach.
+
+2002-02-10 Werner Koch <wk@gnupg.org>
+
+ * random.c (mix_pool): Carry an extra failsafe_digest buffer
+ around to make the function more robust.
+
+2002-02-08 Werner Koch <wk@gnupg.org>
+
+ * random.c (add_randomness): Xor new data into the pool and not
+ just copy it. This avoids any choosen input attacks which are not
+ serious in our setting because an outsider won't be able to mix
+ data in and even then we keep going with a PRNG. Thanks to Stefan
+ Keller for pointing this out.
+
+2002-01-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
+
+ * primegen.c (gen_prime): Of course we should use set_bit
+ and not set_highbit to set the second high bit.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Loop until we find the exact modulus size.
+ Changed the exponent to 41.
+ (rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
+ * primegen.c (gen_prime): Set 2 high order bits for secret primes.
+
+ * Makefile.am (DISTCLEANFILES): Include construct.c.
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): New - experimental.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added OIDs for AES.
+ (gcry_cipher_mode_from_oid): New.
+ (gcry_cipher_map_name): Moved OID search code to ..
+ (search_oid): .. new function.
+
+2001-12-10 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
+ and not by number.
+
+ * pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
+ (gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits): Release the arrays. Noted by Nikos
+ Mavroyanopoulos.
+
+2001-12-06 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
+ with "oid." or "OID.".
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa.
+
+2001-11-24 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Added the rsaEncryption OID to the tables.
+ (sexp_to_key): Add an arg to return the index of the algorithm,
+ changed all callers.
+ (gcry_pk_sign): Find the signature algorithm by name and not by
+ number.
+ (gcry_pk_get_nbits): Fixed so that we can now really pass a secret
+ key to get the result.
+
+ * md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
+ or "OID." so that an OID string can be used as an S-Exp token.
+
+2001-11-20 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_map_name): Lookup by OID if the the name begins
+ with a digit.
+ (oid_table): New.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
+
+2001-11-07 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Close the handle which was left open
+ for algorithms other than rmd160.
+
+2001-08-08 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (gather_random): Use toolhelp in addition to the NT
+ gatherer for Windows2000. Suggested by Sami Tolvanen.
+
+ * random.c (read_pool): Fixed length check, this used to be one
+ byte to strict. Made an assert out of it because the caller has
+ already made sure that only poolsize bytes are requested.
+ Reported by Marcus Brinkmann.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
+ errors. We have to change the interface to all ciphers to make
+ this really work but we should do so to prepare for hardware
+ encryption modules.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
+ set lasterr.
+ (gcry_cipher_ctl): Make sure that errors from setkey are returned.
+
+2001-08-02 Werner Koch <wk@gnupg.org>
+
+ * rndlinux.c (gather_random): casted a size_t arg to int so that
+ the format string is correct. Casting is okay here and avoids
+ translation changes.
+
+ * random.c (fast_random_poll): Do not check the return code of
+ getrusage.
+
+ * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
+ and 8.
+
+ * tiger.c (print_abc,print_data): Removed.
+
+ * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
+ (burn_stack): New. Add wrappers for most functions to be able to
+ call burn_stack after the function invocation. This methods seems
+ to be the most portable way to zeroise the stack used. It does
+ only work on stack frame based machines but it is highly portable
+ and has no side effects. Just setting the automatic variables at
+ the end of a function to zero does not work well because the
+ compiler will optimize them away - marking them as volatile would
+ be bad for performance.
+ * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
+ * random.c (burn_stack): New.
+ (mix_pool): Use it here to burn the stack of the mixblock function.
+
+ * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
+ Thanks to Tommi Komulainen.
+
+ * arcfour.c (arcfour_setkey): Check the minimim keylength against
+ bytes and not bits.
+ (selftest): Must reset the key before decryption.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * sha1.c (sha1_init): Made static.
+
+ Changed all g10_ prefixed function names as well as some mpi_
+ function names to cope with the introduced naming changes.
+
+ * md.c (prepare_macpads): Made key const.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (gather_random): Removed the use of tty_printf.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * md5.c (md5_final): Fixed calculation of hashed length. Thanks
+ to disastry@saiknes.lv for pointing out that it was horrible wrong
+ for more than 512MB of input.
+ * sha1.c (sha1_final): Ditto.
+ * rmd160.c (rmd160_final): Ditto.
+ * tiger.c (tiger_final): Ditto.
+
+ * blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
+ avoid name clashes with an encrypt function in stdlib.h of
+ Dynix/PIX. Thanks to Gene Carter.
+ * elgamal.c (encrypt,do_encrypt): Ditto.
+
+ * twofish.c (gnupgext_enum_func): Use only when when compiled as a
+ module.
+ * rijndael.c (gnupgext_enum_func): Ditto.
+
+ * tiger.c (tiger_get_info): Return "TIGER192" and not just
+ "TIGER". By Edwin Woudt.
+
+ * random.c: Always include time.h - standard requirement. Thanks
+ to James Troup.
+
+ * rndw32.c: Fixes to the macros.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
+ not 8.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
+ mpi_free by gcry_mpi_release.
+ * elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
+ * rsa.c (test_keys,generate,rsa_verify): Ditto.
+ * primegen.c (generate_elg_prime): Ditto.
+ (gen_prime): Ditto and removed nlimbs.
+
+ * rsa.c (generate): Allocate 2 more vars in secure memory.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c, arcfour.h: New.
+ * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
+ (setup_cipher_table): Add Arcfour.
+ (gcry_cipher_open): Kludge to allow stream mode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sha1.c (transform): Use rol() macro. Actually this is not needed
+ for a newer gcc but there are still aoter compilers.
+
+ * rsa.c (test_keys): Use new random function.
+
+ * md.c (gcry_md_setkey): New function to overcome problems with
+ const conflics.
+ (gcry_md_ctl): Pass set key to the new functions.
+
+ * rijndael.c: New.
+ * cipher.c: Add Rijndael support.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * rndlinux.c (open_device): Loose random device checking.
+ By Nils Ellmenreich.
+
+ * random.c (fast_random_poll): Check ENOSYS for getrusage.
+ * rndunix.c: Add 2 sources for QNX. By Sam Roberts.
+
+ * pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
+
+ * rsa.c: Changed the comment about the patent.
+ (secret): Speed up by using the CRT. For a 2k keys this
+ is about 3 times faster.
+ (stronger_key_check): New but unused code to check the secret key.
+ * Makefile.am: Included rsa.[ch].
+ * pubkey.c: Enabled RSA support.
+ (pubkey_get_npkey): Removed RSA workaround.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
+ gcry_sexp_nth_{data,mpi} functions.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
+ gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
+ the new S-Exp interface.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2) again.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
+
+ * Makefile.am: Never compile mingw32 as module.
+
+ * Makefile.am: Tweaked module build and removed libtool
+
+ * Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
+
+ * elgamal.c (sign): Removed inactive code.
+
+ * rsa.c, rsa.h: New based on the old module version (only in CVS for now).
+ * pubkey.c (setup_pubkey_table): Added commented support for RSA.
+
+ * rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
+ (my_popen): Do the FD_CLOEXEC only if it is available
+ (start_gatherer): Cope with missing _SC_OPEN_MAX
+
+ * rndunix.c: Add some more headers for QNX. By Sam Roberts.
+
+ * rndegd.c (gather_random): Shortcut level 0.
+ * rndunix.c (gather_random): Ditto.
+ * rndw32.c (gather_random): Ditto.
+
+ * rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
+ * rndw32.c: Add some debuging code enabled by an environment variable.
+
+ * random.c (read_seed_file): Binary open for DOSish system
+ (update_random_seed_file): Ditto.
+ * random.c [MINGW32]: Include process.h for getpid.
+ * random.c (fast_random_poll): Add clock_gettime() as fallback for
+ system which support this POSIX.4 fucntion. By Sam Roberts.
+
+ * random.c (read_seed_file): Removed the S_ISLNK test becuase it
+ is already covered by !S_ISREG and is not defined in Unixware.
+ Reported by Dave Dykstra.
+ (update_random_seed_file): Silently ignore update request when pool
+ is not filled.
+
+ * random.c (read_seed_file): New.
+ (set_random_seed_file): New.
+ (read_pool): Try to read the seeding file.
+ (update_random_seed_file): New.
+
+ (read_pool): Do an initial extra seeding when level 2 quality random
+ is requested the first time. This requestes at least POOLSIZE/2 bytes
+ of entropy. Compined with the seeding file this should make normal
+ random bytes cheaper and increase the quality of the random bytes
+ used for key generation.
+
+ * random.c (read_pool): Print a more friendly error message in
+ cases when too much random is requested in one call.
+
+ * random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
+ this is not the case for some ESIX and Unixware, although they have
+ getrusage().
+
+ * primegen.c (generate_elg_prime): All primes are now generated with
+ the lowest random quality level. Because they are public anyway we
+ don't need stronger random and by this we do not drain the systems
+ entropy so much.
+
+ * primegen.c (register_primegen_progress): New.
+ * dsa.c (register_pk_dsa_progress): New.
+ * elgamal.c (register_pk_elg_progress): New.
+
+ * elgamal.c (wiener_map): New.
+ (gen_k): Use a much smaller k.
+ (generate): Calculate the qbits using the wiener map and
+ choose an x at a size comparable to the one choosen in gen_k
+
+ * rmd160.c (rmd160_get_info): Moved casting to the left side due to a
+ problem with UTS4.3. Suggested by Dave Dykstra.
+ * sha1.c (sha1_get_info): Ditto.
+ * tiger.c (tiger_get_info): Ditto.
+ * md5.c (md5_get_info): Ditto
+ * des.c (des_get_info): Ditto.
+ * blowfish.c (blowfish_get_info): Ditto.
+ * cast5.c (cast5_get_info): Ditto.
+ * twofish.c (twofish_get_info): Ditto.
+
+Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (md_open): Add hmac arg and allocate space for the pads.
+ (md_finalize): Add HMAC support.
+ (md_copy): Ditto.
+ (md_close): Ditto.
+ (gcry_md_reset): Ditto.
+ (gcry_md_ctl): Ditto.
+ (prepare_macpdas): New.
+
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * genprime.c (generate_elg_prime): Fixed returned factors which never
+ worked for non-DSA keys.
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (gcry_pk_decrypt): Implemented.
+ (gcry_pk_encrypt): Implemented.
+ (gcry_pk_testkey): New.
+ (gcry_pk_genkey): New.
+ (pubkey_decrypt): Made static.
+ (pubkey_encrypt): Ditto.
+ (pubkey_check_secret_key): Ditto.
+ (pubkey_generate): Ditto.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (pubkey_nbits): Removed and replaced by ...
+ (gcry_pk_get_nbits): this new one.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dsa.c: s/mpi_powm/gcry_mpi_powm/g
+ * elgamal.c: Ditto.
+ * primegen.c: Ditto.
+
+ * : Replaced g10_opt_verbose by g10_log_verbosity().
+
+ * Makefile.am (INCLUDES): removed intl, add ../gcrypt
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dynload.c (cmp_filenames): New to replaced compare_filename() in
+ module.
+ (register_cipher_extension): Removed the tilde expansion stuff.
+ * rndeg.c (my_make_filename): New.
+
+ * : Replaced header util.h by g10lib.h
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2).
+ Disabled wrning printed with tty_printf.
+ * rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
+ this should be replaced by a callback function.
+
+ * primegen.c (gen_prime): Use gcry_mpi_randomize.
+ (is_prime): Ditto.
+ * elgamal.c (test_keys): Ditto.
+ * dsa.c (test_keys): Ditto.
+
+ * cipher.c (gcry_cipher_close): Die on invalid handle.
+
+Mon Nov 15 21:36:02 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (gen_k): Use the new random API.
+ (generate): Ditto.
+ * dsa.c (gen_k): Ditto.
+ (generate): Ditto.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (disable_pubkey_algo): Made static.
+ (gcry_pk_ctl): New.
+
+ * random.c (get_random_bits): Renamed to ...
+ (get_random_bytes): ... this and made static.
+ (gcry_random_bytes): New.
+ (gcry_random_bytes_secure): New.
+ (randomize_buffer): Renamed to ...
+ (gcry_randomize): ...this.
+
+ * md.c (gcry_md_hash_buffer): New.
+
+ * pubkey.c (gcry_pk_algo_info): 4 new commands.
+ (pubkey_get_npkey): Made static.
+ (pubkey_get_nskey): Made static.
+ (pubkey_get_nsig): Made static.
+ (pubkey_get_nenc): Made static.
+
+ * pubkey.c: Removed all G10ERR_xxx.
+ * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
+ * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
+ * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
+ * blowfish.c: Ditto.
+ * des.c: Ditto.
+ * twofish.c: Ditto.
+ * dsa.c: Ditto.
+ * elgamal.c: Ditto.
+
+ * g10c.c: Removed
+
+ * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
+ if we are out of core.
+ * dynload.c: Replaced all memory allocation functions.
+ * md.c: Ditto.
+ * primegen.c: Ditto.
+ * pubkey.c: Ditto.
+ * random.c: Ditto.
+ * rndw32.c: Ditto.
+ * elgamal.c: Ditto.
+ * dsa.c: Ditto.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
+
+ * cipher.c: Merged with gcrypt/symapi.c.
+
+ * pubkey.c (string_to_pubkey_algo): Renamed function to ...
+ (gcry_pk_map_name): ... this.
+ (pubkey_algo_to_string): Renamed function to ...
+ (gcry_pk_algo_name): ... this.
+ (gcry_pk_algo_info): New.
+ * pubkey.c: Merged with gcrypt/pkapi.c.
+
+ * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
+ fixing this bug.
+
+ * md.c: Merged with gcrypt/mdapi.c
+
+Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de>
+
+ * des.c: Various speed improvements: One bit pre rotation
+ trick after initial permutation (Richard Outerbridge).
+ Finished test of SSLeay Tripple-DES patterns.
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndw32.c: New.
+
+Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * bithelp.h: New.
+ * rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
+
+Tue Sep 7 16:23:36 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (selftest): Add some testpattern
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
+ in place encryption. Pointed out by Frank Stajano.
+
+Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md5.c (md5_final): Fix for a SCO cpp bug.
+
+Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * elgamal.c (elg_check_secret_key,elg_encrypt
+ elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
+ * dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
+
+ * pubkey.c (disable_pubkey_algo): New.
+ (check_pubkey_algo2): Look at disabled algo table.
+ * cipher.c (disable_cipher_algo): New.
+ (check_cipher_algo): Look at disabled algo table.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dsa.c (gen_k): Changed algorithm to consume less random bytes
+ * elgamal.c (gen_k): Ditto.
+
+ * random.c (random_dump_stats): New.
+
+Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
+ fputc with a call to this function.
+
+Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
+
+ * cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
+
+ * dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
+ * Makefile.am (install-exec-hook): Removed.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (setup_cipher_table): Enable Twofish
+
+ * random.c (fast_random_poll): Disable use of times() for mingw32.
+
+Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (register_internal_cipher_extension): Minor init fix.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
+ that we didn't correct for step when passing the prime to the
+ Rabin-Miller test which led to bad performance (Stefan Keller).
+ (check_prime): Add a first Fermat test.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
+
+ * random.c (randomize_buffer): alway use secure memory because
+ we can't use m_is_secure() on a statically allocated buffer.
+
+ * twofish.c: Replaced some macros by a loop to reduce text size.
+ * Makefile.am (twofish): No more need for sed editing.
+
+Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
+
+ * blowfish.c: Dropped the Blowfish 160 mode.
+ * cipher.c (cipher_open): Ditto.
+ (setup_cipher_table): Ditto. And removed support of twofish128
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+ * twofish.c: Applied Matthew Skala's patches for 256 bit key.
+
+Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndlinux.c (tty_printf) [IS_MODULE]: Removed.
+
+ * rndegd.c (gather_random): Some fixes.
+
+Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_read): New.
+ (gather_random): Changed the implementation.
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
+
+Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c: Nearly a total rewrote.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (context): Fixed alignment
+ * md.c: Ditto.
+
+ * rndegd.c: New
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c: New.
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Modules are now figured out by configure
+ * construct.c: New. Generated by configure. Changed all modules
+ to work with that.
+ * sha1.h: Removed.
+ * md5.h: Removed.
+
+ * twofish.c: Changed interface to allow Twofish/256
+
+ * rndunix.c (start_gatherer): Die on SIGPIPE.
+
+Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): Fix to avoid infinite loop.
+
+Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (is_weak_key): Replace system memcmp due to bugs
+ in SunOS's memcmp.
+ (des_get_info): Return error on failed selftest.
+ * twofish.c (twofish_setkey): Return error on failed selftest or
+ invalid keylength.
+ * cast5.c (cast_setkey): Ditto.
+ * blowfish.c (bf_setkey): Return error on failed selftest.
+
+Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (random_is_faked): New.
+
+ * tiger.c: Only compile if we have the u64 type
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): check for setuid.
+
+ * Makefile.am: Add a way to staically link random modules
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_stop_debug): Do a flush first.
+ (md_open): size of buffer now depends on the secure parameter
+
+Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (start_gatherer): Fixed stupid ==/= bug
+
+1998-12-31 Geoff Keating <geoffk@ozemail.com.au>
+
+ * des.c (is_weak_key): Rewrite loop end condition.
+
+Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c: add unistd.h for getpid().
+ (RAND_MAX): Fallback value for Sun.
+
+Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_copy): Reset debug.
+
+Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (read_random_source): Changed the interface to the
+ random gathering function.
+ (gather_faked): Use new interface.
+ * dynload.c (dynload_getfnc_fast_random_poll): Ditto.
+ (dynload_getfnc_gather_random): Ditto.
+ * rndlinux.c (gather_random): Ditto.
+ * rndunix.c (gather_random): Ditto.
+
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (SYMBOL_VERSION): New to cope with system which needs
+ underscores.
+
+ * rndunix.c: Rewrote large parts
+
+Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (load_extension): increased needed verbosity level.
+
+ * random.c (fast_random_poll): Fallback to a default fast random
+ poll function.
+ (read_random_source): Always use the faked entroy gatherer if no
+ gather module is available.
+ * rndlinux.c (fast_poll): Removed.
+ * rndunix.c (fast_poll): Removed.
+
+
+Wed Nov 25 12:33:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-*.c: Removed.
+ * rndlinux.c : New.
+ * rndunix.c : New.
+ * random.c : Restructured the interface to the gather modules.
+ (intialize): Call constructor functions
+ (read_radnom_source): Moved to here.
+ * dynload.c (dynload_getfnc_gather_random): New.
+ (dynload_getfnc_fast_random_poll): New.
+ (register_internal_cipher_extension): New.
+ (register_cipher_extension): Support of internal modules.
+
+Sun Nov 8 17:44:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (read_random_source): Removed the assert.
+
+Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
+
+ * pubkey.c: Hack to allow us to give some info about RSA keys back.
+
+Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c: Support for DLD
+
+Wed Oct 14 12:13:07 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c: Now uses names from configure for /dev/random.
+
+1998-10-10 SL Baur <steve@altair.xemacs.org>
+
+ * Makefile.am: fix sed -O substitutions to catch -O6, etc.
+
+Tue Oct 6 10:06:32 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
+ * rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
+
+Mon Sep 28 13:23:09 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest): New.
+ (md_reset): New.
+
+Wed Sep 23 12:27:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998 Werner Koch (wk@(none))
+
+ * des.c: Some patches from Michael.
+
+Thu Sep 17 19:00:06 1998 Werner Koch (wk@(none))
+
+ * des.c : New file from Michael Roth <mroth@nessie.de>
+
+Mon Sep 14 11:10:55 1998 Werner Koch (wk@(none))
+
+ * blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
+
+Mon Sep 14 09:19:25 1998 Werner Koch (wk@(none))
+
+ * dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
+
+Mon Sep 7 17:04:33 1998 Werner Koch (wk@(none))
+
+ * Makefile.am: Fixes to allow a different build directory
+
+Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * random.c (get_random_byte): Removed and changed all callers
+ to use get_random_bits()
+
+Mon Jul 27 10:30:22 1998 Werner Koch (wk@(none))
+
+ * cipher.c : Support for other blocksizes
+ (cipher_get_blocksize): New.
+ * twofish.c: New.
+ * Makefile.am: Add twofish module.
+
+Mon Jul 13 21:30:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Simple alloc if secure_alloc is not set.
+ (get_random_bits): Ditto.
+
+Thu Jul 9 13:01:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c (load_extension): Function now nbails out if
+ the program is run setuid.
+
+Wed Jul 8 18:58:23 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_hash_buffer): New.
+
+Thu Jul 2 10:50:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_open): algos >=100 use standard CFB
+
+Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am: Support for extensions
+
+Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (mix_pool): simpler handling for level 0
+
+Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c: Removed from dist, will reappear as dynload module
+
+Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * pubkey.c: Major changes to allow extensions. Changed the inteface
+ of all public key ciphers and added the ability to load extensions
+ on demand.
+
+ * misc.c: Removed.
+
+Wed Jun 10 07:52:08 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * dynload.c: New.
+ * cipher.c: Major changes to allow extensions.
+
+Mon Jun 8 22:43:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Major internal chnages to support extensions.
+ * blowfish.c (blowfish_get_info): New and made all internal
+ functions static, changed heder.
+ * cast5.c (cast5_get_info): Likewise.
+
+Mon Jun 8 12:27:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (transform): Fix for big endian
+
+ * cipher.c (do_cfb_decrypt): Big endian fix.
+
+Fri May 22 07:30:39 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_get_oid): Add a new one for TIGER.
+
+Thu May 21 13:24:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Add support for a dummy cipher
+
+Thu May 14 15:40:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): fixed sigbus - I should better
+ add Christian von Roques's new implemenation of rmd160_write.
+
+Fri May 8 18:07:44 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
+ * random.c: Moved system specific functions to rand-****.c
+
+Fri May 8 14:01:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fast_random_poll): add call to gethrtime.
+
+Tue May 5 21:28:55 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): choosing x was not correct, could
+ yield 6 bytes which are not from the random pool, tsss, tsss..
+
+Tue May 5 14:09:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Add arg mode, changed all
+ callers and implemented mode 1.
+
+Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_get_keylen): New.
+
+Sun Apr 26 14:44:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c, tiger.h: New.
+
+Wed Apr 8 14:57:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (check_pubkey_algo2): New.
+
+Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: New
+ * misc.c (check_cipher_algo): Moved to cipher.c
+ * cast5.c: Moved many functions to cipher.c
+ * blowfish.c: Likewise.
+
+Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cast5.c: Implemented and tested.
+
+Wed Apr 1 16:38:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): Faster generation of x in some cases.
+
+Thu Mar 19 13:54:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * blowfish.c (blowfish_decode_cfb): changed XOR operation
+ (blowfish_encode_cfb): Ditto.
+
+Thu Mar 12 14:04:05 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * sha1.c (transform): Rewrote
+
+ * blowfish.c (encrypt): Unrolled for rounds == 16
+ (decrypt): Ditto.
+
+Tue Mar 10 16:32:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): Unrolled the loop.
+
+Tue Mar 10 13:05:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Add pool_balance stuff.
+ (get_random_bits): New.
+
+ * elgamal.c (elg_generate): Now uses get_random_bits to generate x.
+
+
+Tue Mar 10 11:33:51 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest_length): New.
+
+Tue Mar 10 11:27:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c (dsa_verify): Works.
+
+Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c, dsa.h: Removed some unused code.
+
+Wed Mar 4 10:39:22 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_open): Add call to fast_random_poll.
+ blowfish.c (blowfish_setkey): Ditto.
+
+Tue Mar 3 13:32:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_mixblock): New.
+ * random.c: Restructured to start with a new RNG implementation.
+ * random.h: New.
+
+Mon Mar 2 19:21:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * gost.c, gost.h: Removed because they did only contain trash.
+
+Sun Mar 1 16:42:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fill_buffer): removed error message if n == -1.
+
+Fri Feb 27 16:39:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_enable): No init if called twice.
+
+Thu Feb 26 07:57:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Changed the progress printing.
+ (gen_prime): Ditto.
+
+Tue Feb 24 12:28:42 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md5.c, md.5 : Replaced by a modified version of md5.c from
+ GNU textutils 1.22.
+
+Wed Feb 18 14:08:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c, md.h : New debugging support
+
+Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (cipher_algo_to_string): New
+ (pubkey_algo_to_string): New.
+ (digest_algo_to_string): New.
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+# Makefile for cipher modules
+# Copyright (C) 1998, 1999, 2000, 2001, 2002,
+# 2003, 2009 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = Manifest
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+
+noinst_LTLIBRARIES = libcipher.la
+
+GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
+
+libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
+libcipher_la_LIBADD = $(GCRYPT_MODULES)
+
+libcipher_la_SOURCES = \
+cipher.c pubkey.c ac.c md.c kdf.c \
+hmac-tests.c \
+bithelp.h \
+primegen.c \
+hash-common.c hash-common.h \
+rmd.h
+
+EXTRA_libcipher_la_SOURCES = \
+arcfour.c \
+blowfish.c \
+cast5.c \
+crc.c \
+des.c \
+dsa.c \
+elgamal.c \
+ecc.c \
+md4.c \
+md5.c \
+rijndael.c rijndael-tables.h \
+rmd160.c \
+rsa.c \
+seed.c \
+serpent.c \
+sha1.c \
+sha256.c \
+sha512.c \
+tiger.c \
+whirlpool.c \
+twofish.c \
+rfc2268.c \
+camellia.c camellia.h camellia-glue.c
+
+if ENABLE_O_FLAG_MUNGING
+o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+else
+o_flag_munging = cat
+endif
+
+
+# We need to lower the optimization for this module.
+tiger.o: $(srcdir)/tiger.c
+ `echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
+
+tiger.lo: $(srcdir)/tiger.c
+ `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for cipher modules
+# Copyright (C) 1998, 1999, 2000, 2001, 2002,
+# 2003, 2009 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = cipher
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am_libcipher_la_OBJECTS = cipher.lo pubkey.lo ac.lo md.lo kdf.lo \
+ hmac-tests.lo primegen.lo hash-common.lo
+libcipher_la_OBJECTS = $(am_libcipher_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
+DIST_SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = Manifest
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+noinst_LTLIBRARIES = libcipher.la
+GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
+libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
+libcipher_la_LIBADD = $(GCRYPT_MODULES)
+libcipher_la_SOURCES = \
+cipher.c pubkey.c ac.c md.c kdf.c \
+hmac-tests.c \
+bithelp.h \
+primegen.c \
+hash-common.c hash-common.h \
+rmd.h
+
+EXTRA_libcipher_la_SOURCES = \
+arcfour.c \
+blowfish.c \
+cast5.c \
+crc.c \
+des.c \
+dsa.c \
+elgamal.c \
+ecc.c \
+md4.c \
+md5.c \
+rijndael.c rijndael-tables.h \
+rmd160.c \
+rsa.c \
+seed.c \
+serpent.c \
+sha1.c \
+sha256.c \
+sha512.c \
+tiger.c \
+whirlpool.c \
+twofish.c \
+rfc2268.c \
+camellia.c camellia.h camellia-glue.c
+
+@ENABLE_O_FLAG_MUNGING_FALSE@o_flag_munging = cat
+@ENABLE_O_FLAG_MUNGING_TRUE@o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cipher/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu cipher/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libcipher.la: $(libcipher_la_OBJECTS) $(libcipher_la_DEPENDENCIES)
+ $(LINK) $(libcipher_la_OBJECTS) $(libcipher_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/arcfour.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-glue.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cast5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/des.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elgamal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash-common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac-tests.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/primegen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rfc2268.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rmd160.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha256.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiger.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/twofish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/whirlpool.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# We need to lower the optimization for this module.
+tiger.o: $(srcdir)/tiger.c
+ `echo $(COMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
+
+tiger.lo: $(srcdir)/tiger.c
+ `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) `
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# Manifest - checksums of the cipher directory
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# Checksums for all source files in this directory. Format is
+# filename, blanks, base-64 part of an OpenPGP detached signature
+# without the header lines. Blank lines and lines beginning with a
+# hash mark are ignored. A tool to process this file is available by
+# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
+#
+# The special entry "$names$" holds a signature over all sorted
+# filenames excluding itself.
+
+
+# Algorithm API
+cipher.c iQCVAwUAQDzrVjEAnp832S/7AQIPDgP+OVJ/YNWY5m7c09EBbPAzL/WsGoj6wrBNMmkRlMOqTHeh+OOtjuFHt1f9uhfM2Nzl7sJ5+h4ryZKLEZmQPRMTZTnAqkvGdsrJWJnigUA9QwYdV0ONqC9C63gpuG465gO9TZVOqlQu/FTxSRuTQYUulkaBNG71n8nZEOusBVwV2YA==58xH
+pubkey.c iQCVAwUAP9XQ3jEAnp832S/7AQJ5UgQAyHfEBvPVJ8wTRg8c7ixS2GiVmIgwIo5tvQaiQJTPWASevvYrB+2Z2qa9cATyu50ACjLzbaquGBgPzjJV3dU/qttT1gCqRuN/LCNvXFe5qnIZezejc3RAadFNTw/pOTHq0wxD1Keg66ruei9R36Nba59pEQIWIBXTfubRft2hMYk==E09t
+ac.c iQCVAwUAQDzsOzEAnp832S/7AQJCBQP/WI6EV/dsR4rmha6RVhvkjZo17kQ8z6pIl5J3cXOvqEkIFeD2HYu3HHrWST5l7yXlffhpDkVHkfMih4ruK76q6Fm0dxZ98pO4C/dVtgimlvvcy/wOQjpzsE0fYAe1BYdg81LJ09X33vW5x6C29lunfKROO2tPlV5i8ffeoFvmMF8==j26g
+md.c iQCVAwUAP+NFGjEAnp832S/7AQJs8wP/Qdk0EAKsyr3O1/pmOSN8AG4rPKbd6KDTzvoBPAN4upFwKYY4hWwvy12Q3YU9DmECrzZkRCXHR7mljVQKs6B7CRZJKjFKmOELpcJDtKvu40vTs1bOH4k9iJYZpGgRA83nkQ+ELAcphAbCA+KIpVr2K4mCJAB0FhpC2uOQ50JHAko==BeF6
+primegen.c iQCVAwUAQDzsoDEAnp832S/7AQKYRwP/TqAQBm1rHTnF0HYE05PqXfWlOqa6EosqVpaOcs/OIW6PaqX0xH1UlrukK7jNOjK3xC4o1qNQ1UKzz2dvQaq1bMvNNizeavxAh10SJZc0hIc/ofc83IbjLh8SZVWQ67JxjsUd3DOXmSmhPZ+Pqd7cUIiw8fDoF+I9EZqy3COu1wY==1ebT
+
+# Algorithm implementations
+arcfour.c iQCVAwUAP9XR/TEAnp832S/7AQJcRwP6AlvYEx++fpT4mIYo0xRDqKEQeqMQvbaRhIg2eV74JxItpHa3q5YsYIl+n1yUz5g35JRWWXSWmAZBwO5wLKsHii4kRUhgrKWnSoQZoPpl49L5+N3R58ON3S0ru5lsBiEJEze3xplf2vqwrH9v1QHVD+gU7UTlfNqrIJoOUXN+1O4==Tq+x
+blowfish.c iQCVAwUAP9XTETEAnp832S/7AQJaEgQAgiqqfuO+zQtscgTB0rvOzVymIKjRKjYhFuLjVuc79G4z1RCAffvIn/YM2d7kt+Z/QF7zjcTAOgETCQL1XokpX2zz9HPAMi2tlDY5zsDufTNqj0n4WBL9nM7w6XAvsiwP1B3bqCTv9SjJV4KbxJ58vw1yQE+sqW74R/QIHFvC7mU==wZnX
+cast5.c iQCVAwUAP9XT6DEAnp832S/7AQJ3xgP/ehLjEN3GELGudbqeo91Xd+PqitHrkuBbtRIYX7Udd/fyXLN+h8rMJVyIQX2m+mpxbBxudVU3x8/DNT8B0ZHAwK6qqJmEBLLhEYPgIuF76i9LMrP1KqUPhAwRZ2OppjIIugBQ+rP74aD4eLyd/aKQHNuXML8QGWR6KwQShohXM5I==/BRh
+crc.c iQCVAwUAP7ouejEAnp832S/7AQIgwQQApg5Nm63tH5DQkbN+zPzMO9Ygoj3ukxfFTyTBPYSXYKMiTjEbESegaU40uN8jnz2vprcIQWcgZfzO4+opEJMcI35aPwzEk0vKOp0S/PrBLUY2rJfnDVkX5XgJFZa2Q7LLe826UEBzTVYW924utiCCe8oOaOEWVNpg1mqdknu3M9o==kz5D
+des.c iQCVAwUAQCN2oDEAnp832S/7AQL/jwP6Auoq6nZCDBjpgc9tDzuIRwa9DqyuM3gX94uvgEpUwdHszb2bG43dz03kVmcYxtj1MzXbyCeCZOwox0b2SKmLgxIbrNP6yGbzVdTj6592gDYuf/ZXmc1ZNJ1DDldcPQ0n9fXUipUPwyPaNWo3mSZaNcMKSWWzdK0J6ciG6nk7SWI==9k/t
+dsa.c iQCVAwUAP9XZHDEAnp832S/7AQLBRgP/XrBzTEYx5ccMj1MMb6sg37liEHdIyyy49zjvt6jUqxj4RuwVEN8S6v3u4q/QyJkHAi1E0EkREgENlyHW6PKWhYbcrd0vPIAN15yjnl2yqtrCrJImexUCoqJJewK0E4JOicGbabTil8MZjk+mbhEPnjJBqOkyP1w0i31pEDgE/8M==pC8s
+elgamal.c iQCVAwUAP9XbYzEAnp832S/7AQLXagQA3HrvspZfbTGgmUH0IqLQTJ0exUPxJv5DET2TvoIy62trDmMN6lTAj5P+a7jQ8udcu0w+mR2vXUHcxUpNA2PxLaMwGzNSY4zRDNe9r3SFTDrFm6m4y9Ko2e8XtEA+WF6P/XLpck4Jn7vMEDmVGPwkNd22kXFFE8dBGwG6i5Hk1Mk==oBUs
+md4.c iQCVAwUAP9h50DEAnp832S/7AQJhHgQAzNA/B6MWFDlCtPkIVaW8RpP1Eg0ZNMsy0s7SJkopOCBlu6CwXUOKe+8ppcSxhjYKh4i4uQr/QtfipYlBjzKJGnrafoF/NugXNCOHSTGT11TvK7mCiBuUMVgvZGAlOJImk6eTTfUjRrMfaXM/SWl8bdJ4ZpzdjEyVh89r7I5JrGk==x2UD
+md5.c iQCVAwUAP9h7LzEAnp832S/7AQJUGQP/c0cbf6WZXCzmjufHxiE9FAQBzTsA0WtaNqdFcHl7fhmikGtknlaED8n5a7eYd/C481UQW6Wgq/oZdsvgoPWPhG3fOCy2CFP9cZVXITuMSf0ucyZTFUJNO15fnZ+nDfsUv+JPdv1aSeRinAUtfAcSKfkSyR9BCPZvkx+tgU6cphU==Zv+h
+rijndael.c iQCVAwUAP9h9cTEAnp832S/7AQKF1AP+P2L/tPqDJRDg+/fwbOk8Ts0MNxnvvYEm3gE73TKuLt1S+B2+jkrZcKNvM5VGPnVMJbnS0lmIK04nmedHCOftGTOwhGulZAHHIaKGystT3Jql4iPws/JMgAjE7Fyxh5WZMtB9yEljKBpJ5XNqhrMvvxcHpnyP3+YzIXNwzk34V+c==dJ5k
+rmd160.c iQCVAwUAP9h+bTEAnp832S/7AQK1OgP+PNKF6Nzi6X93easVlksdLqKEsArCAw2QjGWDGyxTnbiJM55qAl9JxR1mn3V+oOL7izLLwTt6EYK9evhzfcxY5N5Mni85RAcsLPsuAfQDEzjI6GUWHtQUKPbM+BaorzfhQjYFSZyvum/dZYJ/WfiwwwhqqIKyVU2ZFSqA38YGC/c==9jdA
+rsa.c iQCVAwUAP9iHIzEAnp832S/7AQKAYwQAuWtnMte54QHN+Hij9t4sGuypXogajOb1vQQwGgS0fKsaBZsuSP2amze4o5diIvsQTsFQ4CzjvqoCVuBDoHM3xkSD8wGDizgvtCamAxkdbF7wmzldKFn8SpJqlVwWQMP6kk1IjXHEuYb4IDWGTbVMhfEu+eOlU8+PSK4IhZqNvt4==/3hp
+serpent.c iQCVAwUAP9h/VzEAnp832S/7AQLyCwP/d1zbmb7l/PriZNa9/Z7mo01XFe5MnAqCfIwhl9GjeaMszcoS37jECNq5nLvrTTFIIJpm3rvBePwiCG4Wwx1I18HCxaP198pcSaR+BLOJ3Aj52EZPrxtqlDKuFr38ZOP5giyUqUYVYGVdrz4kRMNWAZQK53GeJnGhXCnhxojLEgA==ck46
+sha1.c iQCVAwUAP9iATTEAnp832S/7AQKcSwQAwAs/HnNqho3lU1ZUgCPNt5P2/Brm6W21+wWWGKJkSrra/c4NYVKJGDDwlsFE0b9ln1uZt7bHReFkKXK3JnrKTmNVcx/Cy64iCMRNMhaM72Mqy7wWx5yHBAmMBxzFGnNQKbmeY52zeGih5HsNLSibc2pPuOViWo2JPJ5Ci/wIwl8==/wtO
+sha256.c iQCVAwUAP9iAtzEAnp832S/7AQJD2QP/UqvL0hhjG1wEFbGrdkV9tba1sMDXdnnK6X7HdLuRpVAgNiQiFf8JDmntd/dZ2Q71p4Uae2ctqve4WoEijPUZPjACnpuZfx0SEQL0lQBkwxzJp7lz9ujVtwQ2cM/aYexJkXcWgGcloJNLM3JbWPGIJnuYbr/IwJ6RQF9vgj0357o==UWO1
+sha512.c iQCVAwUAP9iBTDEAnp832S/7AQIPBAQA28CJSUQLiW0s2x9u8/OH2eKnxPjA4sZmb50WP7920Lem66P31C3BrOqwfBot4RLhjL+zh/+Uc4s3HPwApZuj9E4BxNMlqLv+Tqk++DAbdaOeYT4jeUt+mlhQQ6mH/RDsy32rZsNsGQ2bUGxazZmfG++PL3JyhawqCy00SUDr/o0==H+0X
+tiger.c iQCVAwUAP9iCfjEAnp832S/7AQKufwP/fryv3MqSOYY+90325DH7X3/CtekxeooN0scGsHX0fxBakWSMecTNrj33KPddLS46gU/S89zIc2N/Bw/7EVIAXVFA3/3Ip+OrFOuIMO4Py1sCdB8o2Y+5ygv8iXLcsXIq1O0av79i9g774V3uaXa2qN9ZnXe0AEhcy8FHJ2i/wro==5XVB
+twofish.c iQCVAwUAP9iD6TEAnp832S/7AQKUnQP/Rq8FaYeHTG7HbZuqAs9pbPitzjDbkdZddmInWR7NmevBkKvhsJALjVooc0KGQfo2lAAmy3Xi/4QQN8VPn51DVjDIgf7x+DQh/9TFJHMccxI9asUgi4+TNnmMqLU1k3N8S2PjyZ1sjeC8B79fKPpwCzj72WkqPkzZw3l2jArr+dU==NdJT
+rfc2268.c iQCVAwUAQCN+3jEAnp832S/7AQLv1gQA1hJh29hAjKi4uLSGxXvJ6cyYmPdmevdKrbLnuHZWtHe4xvCgy/nTdEojEpxgLp/hL/ogasuWRC1W16Wiz9ryxf7YR0uhZWayO/bQNagpfU5MIkJTLuKqqgpwYumCSQfOugXVAqcgEzj+13eeyJaFVrzwrNa67sh84nmbjOjNjvE==0zBq
+
+# Random number related
+random.c iQCVAwUAP7nsITEAnp832S/7AQK4SAQAtvfUgrtGOQ2PlxGMla0qJLPHjJacMwgq0ecusiI79elPdDsFfCCk6dK1Ug2kFbNm22nCGHNcUquqbX7noi7ZVQnmPBQXzyLNZd7GmrawRZfdlRerTUDBpSnR8V8ui/5+YYp627E7kKGC0hPSgqXFql6oBMIfno0LZwFJTjIevRY==L419
+random.h iQCVAwUAP7ovKDEAnp832S/7AQJ3bQQAjnPebnyTC7sphAv2I7uIz+yPgw1ZfbVhLv+OiWDlO9ish+fRyyMpy+HELBOgZjJdgRegqhlZC6qyns5arM/VglYi+PzvdLO3hIqHE/YFfpIFPz8wBrcmlqrYyd3CsGqcYsfjocXNttCBLeSWmoJ09ltKQH8yzJf3oAgN6X1yuc4==eNoU
+rand-internal.h iQCVAwUAP7ouvDEAnp832S/7AQLYnAQAhdI7ERoJVCkV8GiV7MjaUxv1WIL7iZ+jIOvVhv4fNyhCGCGoEtTjkyput/lj7Nsh3FXEqRhypGGrCLf47x/gua5n+BwffogxVyUDqiOyyGhNTPpe3fQcNBvbPCtco8yMK4GJO5G3BqzlPyN+BMeogLymyV6Sm1mvh5LZDyAFbfQ==tZSE
+rndlinux.c iQCVAwUAP9iPYTEAnp832S/7AQL6/AP/ZDrbOkVuB9qJ7sKeX1MImZEsz3mi0xPovJzaBtBU7a0idcUKrWYOvQFWRlLUeq0iCT6+h2l5bniP7q7hepzlKa+VPY9VWaQthqeJm2l5LN6QQ5PyMfBq04QuBncw9BJnCGmEyTLt3RxIXBAPdxmiVxtcRIFUqCBtQvoUXGLvemw==t37k
+rndegd.c iQCVAwUAP9iPRDEAnp832S/7AQImBQP/WHKg+hKXcm1pQvilzML0jZpwK5PAMM4uBnnPJNIXWOYBO6I/Xg9d/tPLg8NlmmtyQCo2Eu0ybDSt+8mu+dWveAys+0LTi0MIqeP9BMzCKz8dnWH6+S8huLXwTF3m0IrqM0JLb6b71GK9SOq6sWQ22yW5vf61hXP8kH9dhIaoMZs==FaHV
+rndunix.c iQCVAwUAP9iQlzEAnp832S/7AQL/KgQA29GnvcD4Xb5qjDMBgW9THEE4+4lfex/6k+Fh0IT61OLJsWVLJ7bJpRntburw4uQm4Tf7CO8vaiDFDYhKKrzXeOF1fmdpcL8hA+fNp9I/MUOc4e9kN9+YJ9wikVa0SZj1OBfhzgcFLd1xOtulkr3ii52HLF9vhrxzkgVwvD10Bi8==2cML
+rndw32.c iQCVAwUAP9iRKDEAnp832S/7AQIuaAQA3AJr3WqnxNDsWCIdvehf8Suotthj+laX8nJsvDfFhXPKcXDpsg0wTTXSnnKgyED53+uYiMDnVRsxeWAyhKwvx1MjjlaSMMjzbH6isWTH8FaWpLgrxEkXoPeNqYf5FXpdUkcUxGX2RkQeuX/cIfiHLNE9CV0usaF2jysjBX2iERY==EEnO
+
+# Helper
+bithelp.h iQCVAwUAP7ouPTEAnp832S/7AQKXggQAqjcgvihIF3WclOgw1JV2rbARw4ISIDRMFqdaNCqBRx6BwEz3UGsEIlz6+iR1sS/reqN61WvtjLb+D0+tujAkGrgQJhFLG85WtG2tB5UVoI3am1fpkwiRm+bR4rv0rGk0BYk81bC7+l4KrK9o5lVp4lCsrorlUKsd48lNmBHyAXM==mDDN
+rmd.h iQCVAwUAP7oumjEAnp832S/7AQJiJQP/V4bJwjZaYndJzV+KRnIDbl1koHuw+ZK5heMYVu8Qk4ylqv//BGyeRa3jZCcfPHI35q6HilCs2VBm8hiBMjHSqY/VPn2ZQ0yg/lt6qEvl7YjsLmyMICvjG+ncszHoq9pRvnF3vTnM18sPIioXLk8fskuM0XOCNBs0ARBAQjY9UGI==olUN
+
+# Configuration
+Makefile.am iQCVAwUAQCN33TEAnp832S/7AQKFJAQAz7BDkC814q+QiuE/jnutJHR5qlgbrm3ikGbQwdRzYUscst4bCCWy3uKL/sIPGLg+JQXtF5FnsQy3s4D9BOYhp72cA9ktYK65hhi4pNm/JQ0lXkZMNfk8Go5lNzKezlWwHvkMwRXR0Fep0wPdyeaKW5BfaW2ABvgep6Bp+hHEbyg==zSyi
+$names$ iQCVAwUAQCN3EDEAnp832S/7AQJXLAP8DvHTpm5DkTF35EmzeKpi9ie59AZcZanD19ir/e/7+PaQxr2riuLHDGwFKTju+dcvvBsqrygXOC378GXVWzIF2OZwS4EdDcJ+pgojo9UpsqpKsJHouY4Ugx5cQialxba462kUn8hcihSBnMyc4LzbJ5WQ4puQuqy544d2x94+2ms==G4Ls
--- /dev/null
+/* ac.c - Alternative interface for asymmetric cryptography.
+ Copyright (C) 2003, 2004, 2005, 2006
+ 2007, 2008 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser general Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "mpi.h"
+
+\f
+
+/* At the moment the ac interface is a wrapper around the pk
+ interface, but this might change somewhen in the future, depending
+ on how many people prefer the ac interface. */
+
+/* Mapping of flag numbers to the according strings as it is expected
+ for S-expressions. */
+static struct number_string
+{
+ int number;
+ const char *string;
+} ac_flags[] =
+ {
+ { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
+ };
+
+/* The positions in this list correspond to the values contained in
+ the gcry_ac_key_type_t enumeration list. */
+static const char *ac_key_identifiers[] =
+ {
+ "private-key",
+ "public-key"
+ };
+
+/* These specifications are needed for key-pair generation; the caller
+ is allowed to pass additional, algorithm-specific `specs' to
+ gcry_ac_key_pair_generate. This list is used for decoding the
+ provided values according to the selected algorithm. */
+struct gcry_ac_key_generate_spec
+{
+ int algorithm; /* Algorithm for which this flag is
+ relevant. */
+ const char *name; /* Name of this flag. */
+ size_t offset; /* Offset in the cipher-specific spec
+ structure at which the MPI value
+ associated with this flag is to be
+ found. */
+} ac_key_generate_specs[] =
+ {
+ { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
+ { 0 }
+ };
+
+/* Handle structure. */
+struct gcry_ac_handle
+{
+ int algorithm; /* Algorithm ID associated with this
+ handle. */
+ const char *algorithm_name; /* Name of the algorithm. */
+ unsigned int flags; /* Flags, not used yet. */
+ gcry_module_t module; /* Reference to the algorithm
+ module. */
+};
+
+/* A named MPI value. */
+typedef struct gcry_ac_mpi
+{
+ char *name; /* Self-maintained copy of name. */
+ gcry_mpi_t mpi; /* MPI value. */
+ unsigned int flags; /* Flags. */
+} gcry_ac_mpi_t;
+
+/* A data set, that is simply a list of named MPI values. */
+struct gcry_ac_data
+{
+ gcry_ac_mpi_t *data; /* List of named values. */
+ unsigned int data_n; /* Number of values in DATA. */
+};
+
+/* A single key. */
+struct gcry_ac_key
+{
+ gcry_ac_data_t data; /* Data in native ac structure. */
+ gcry_ac_key_type_t type; /* Type of the key. */
+};
+
+/* A key pair. */
+struct gcry_ac_key_pair
+{
+ gcry_ac_key_t public;
+ gcry_ac_key_t secret;
+};
+
+\f
+
+/*
+ * Functions for working with data sets.
+ */
+
+/* Creates a new, empty data set and store it in DATA. */
+gcry_error_t
+_gcry_ac_data_new (gcry_ac_data_t *data)
+{
+ gcry_ac_data_t data_new;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_new = gcry_malloc (sizeof (*data_new));
+ if (! data_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ data_new->data = NULL;
+ data_new->data_n = 0;
+ *data = data_new;
+ err = 0;
+
+ out:
+
+ return err;
+}
+
+/* Destroys all the entries in DATA, but not DATA itself. */
+static void
+ac_data_values_destroy (gcry_ac_data_t data)
+{
+ unsigned int i;
+
+ for (i = 0; i < data->data_n; i++)
+ if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
+ {
+ gcry_mpi_release (data->data[i].mpi);
+ gcry_free (data->data[i].name);
+ }
+}
+
+/* Destroys the data set DATA. */
+void
+_gcry_ac_data_destroy (gcry_ac_data_t data)
+{
+ if (data)
+ {
+ ac_data_values_destroy (data);
+ gcry_free (data->data);
+ gcry_free (data);
+ }
+}
+
+/* This function creates a copy of the array of named MPIs DATA_MPIS,
+ which is of length DATA_MPIS_N; the copy is stored in
+ DATA_MPIS_CP. */
+static gcry_error_t
+ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
+ gcry_ac_mpi_t **data_mpis_cp)
+{
+ gcry_ac_mpi_t *data_mpis_new;
+ gcry_error_t err;
+ unsigned int i;
+ gcry_mpi_t mpi;
+ char *label;
+
+ data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
+ if (! data_mpis_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
+
+ err = 0;
+ for (i = 0; i < data_mpis_n; i++)
+ {
+ /* Copy values. */
+
+ label = gcry_strdup (data_mpis[i].name);
+ mpi = gcry_mpi_copy (data_mpis[i].mpi);
+ if (! (label && mpi))
+ {
+ err = gcry_error_from_errno (errno);
+ gcry_mpi_release (mpi);
+ gcry_free (label);
+ break;
+ }
+
+ data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
+ data_mpis_new[i].name = label;
+ data_mpis_new[i].mpi = mpi;
+ }
+ if (err)
+ goto out;
+
+ *data_mpis_cp = data_mpis_new;
+ err = 0;
+
+ out:
+
+ if (err)
+ if (data_mpis_new)
+ {
+ for (i = 0; i < data_mpis_n; i++)
+ {
+ gcry_mpi_release (data_mpis_new[i].mpi);
+ gcry_free (data_mpis_new[i].name);
+ }
+ gcry_free (data_mpis_new);
+ }
+
+ return err;
+}
+
+/* Create a copy of the data set DATA and store it in DATA_CP. */
+gcry_error_t
+_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
+{
+ gcry_ac_mpi_t *data_mpis = NULL;
+ gcry_ac_data_t data_new;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ /* Allocate data set. */
+ data_new = gcry_malloc (sizeof (*data_new));
+ if (! data_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
+ if (err)
+ goto out;
+
+ data_new->data_n = data->data_n;
+ data_new->data = data_mpis;
+ *data_cp = data_new;
+
+ out:
+
+ if (err)
+ gcry_free (data_new);
+
+ return err;
+}
+
+/* Returns the number of named MPI values inside of the data set
+ DATA. */
+unsigned int
+_gcry_ac_data_length (gcry_ac_data_t data)
+{
+ return data->data_n;
+}
+
+
+/* Add the value MPI to DATA with the label NAME. If FLAGS contains
+ GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
+ and MPI. If FLAGS contains GCRY_AC_FLAG_DEALLOC or
+ GCRY_AC_FLAG_COPY, the values contained in the data set will
+ be deallocated when they are to be removed from the data set. */
+gcry_error_t
+_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+{
+ gcry_error_t err;
+ gcry_mpi_t mpi_cp;
+ char *name_cp;
+ unsigned int i;
+
+ name_cp = NULL;
+ mpi_cp = NULL;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
+ {
+ err = gcry_error (GPG_ERR_INV_ARG);
+ goto out;
+ }
+
+ if (flags & GCRY_AC_FLAG_COPY)
+ {
+ /* Create copies. */
+
+ flags |= GCRY_AC_FLAG_DEALLOC;
+ name_cp = gcry_strdup (name);
+ mpi_cp = gcry_mpi_copy (mpi);
+ if (! (name_cp && mpi_cp))
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ }
+
+ /* Search for existing entry. */
+ for (i = 0; i < data->data_n; i++)
+ if (! strcmp (name, data->data[i].name))
+ break;
+ if (i < data->data_n)
+ {
+ /* An entry for NAME does already exist. */
+ if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
+ {
+ gcry_mpi_release (data->data[i].mpi);
+ gcry_free (data->data[i].name);
+ }
+ }
+ else
+ {
+ /* Create a new entry. */
+
+ gcry_ac_mpi_t *ac_mpis;
+
+ ac_mpis = gcry_realloc (data->data,
+ sizeof (*data->data) * (data->data_n + 1));
+ if (! ac_mpis)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ if (data->data != ac_mpis)
+ data->data = ac_mpis;
+ data->data_n++;
+ }
+
+ data->data[i].name = name_cp ? name_cp : ((char *) name);
+ data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
+ data->data[i].flags = flags;
+ err = 0;
+
+ out:
+
+ if (err)
+ {
+ gcry_mpi_release (mpi_cp);
+ gcry_free (name_cp);
+ }
+
+ return err;
+}
+
+/* Stores the value labelled with NAME found in the data set DATA in
+ MPI. The returned MPI value will be released in case
+ gcry_ac_data_set is used to associate the label NAME with a
+ different MPI value. */
+gcry_error_t
+_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+{
+ gcry_mpi_t mpi_return;
+ gcry_error_t err;
+ unsigned int i;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (flags & ~(GCRY_AC_FLAG_COPY))
+ {
+ err = gcry_error (GPG_ERR_INV_ARG);
+ goto out;
+ }
+
+ for (i = 0; i < data->data_n; i++)
+ if (! strcmp (name, data->data[i].name))
+ break;
+ if (i == data->data_n)
+ {
+ err = gcry_error (GPG_ERR_NOT_FOUND);
+ goto out;
+ }
+
+ if (flags & GCRY_AC_FLAG_COPY)
+ {
+ mpi_return = gcry_mpi_copy (data->data[i].mpi);
+ if (! mpi_return)
+ {
+ err = gcry_error_from_errno (errno); /* FIXME? */
+ goto out;
+ }
+ }
+ else
+ mpi_return = data->data[i].mpi;
+
+ *mpi = mpi_return;
+ err = 0;
+
+ out:
+
+ return err;
+}
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+ set DATA with the index IDX. NAME or MPI may be NULL. The
+ returned MPI value will be released in case gcry_ac_data_set is
+ used to associate the label NAME with a different MPI value. */
+gcry_error_t
+_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi)
+{
+ gcry_error_t err;
+ gcry_mpi_t mpi_cp;
+ char *name_cp;
+
+ name_cp = NULL;
+ mpi_cp = NULL;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ if (flags & ~(GCRY_AC_FLAG_COPY))
+ {
+ err = gcry_error (GPG_ERR_INV_ARG);
+ goto out;
+ }
+
+ if (idx >= data->data_n)
+ {
+ err = gcry_error (GPG_ERR_INV_ARG);
+ goto out;
+ }
+
+ if (flags & GCRY_AC_FLAG_COPY)
+ {
+ /* Return copies to the user. */
+ if (name)
+ {
+ name_cp = gcry_strdup (data->data[idx].name);
+ if (! name_cp)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ }
+ if (mpi)
+ {
+ mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
+ if (! mpi_cp)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ }
+ }
+
+ if (name)
+ *name = name_cp ? name_cp : data->data[idx].name;
+ if (mpi)
+ *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
+ err = 0;
+
+ out:
+
+ if (err)
+ {
+ gcry_mpi_release (mpi_cp);
+ gcry_free (name_cp);
+ }
+
+ return err;
+}
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+ stored in SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t
+_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+{
+ gcry_sexp_t sexp_new;
+ gcry_error_t err;
+ char *sexp_buffer;
+ size_t sexp_buffer_n;
+ size_t identifiers_n;
+ const char *label;
+ gcry_mpi_t mpi;
+ void **arg_list;
+ size_t data_n;
+ unsigned int i;
+
+ sexp_buffer_n = 1;
+ sexp_buffer = NULL;
+ arg_list = NULL;
+ err = 0;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ /* Calculate size of S-expression representation. */
+
+ i = 0;
+ if (identifiers)
+ while (identifiers[i])
+ {
+ /* For each identifier, we add "(<IDENTIFIER>)". */
+ sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
+ i++;
+ }
+ identifiers_n = i;
+
+ if (! identifiers_n)
+ /* If there are NO identifiers, we still add surrounding braces so
+ that we have a list of named MPI value lists. Otherwise it
+ wouldn't be too much fun to process these lists. */
+ sexp_buffer_n += 2;
+
+ data_n = _gcry_ac_data_length (data);
+ for (i = 0; i < data_n; i++)
+ {
+ err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
+ if (err)
+ break;
+ /* For each MPI we add "(<LABEL> %m)". */
+ sexp_buffer_n += 1 + strlen (label) + 4;
+ }
+ if (err)
+ goto out;
+
+ /* Allocate buffer. */
+
+ sexp_buffer = gcry_malloc (sexp_buffer_n);
+ if (! sexp_buffer)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Fill buffer. */
+
+ *sexp_buffer = 0;
+ sexp_buffer_n = 0;
+
+ /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)). */
+ if (identifiers_n)
+ {
+ /* Add nested identifier lists as usual. */
+ for (i = 0; i < identifiers_n; i++)
+ sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
+ identifiers[i]);
+ }
+ else
+ {
+ /* Add special list. */
+ sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
+ }
+
+ /* Add MPI list. */
+ arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
+ if (! arg_list)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ for (i = 0; i < data_n; i++)
+ {
+ err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
+ if (err)
+ break;
+ sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
+ "(%s %%m)", label);
+ arg_list[i] = &data->data[i].mpi;
+ }
+ if (err)
+ goto out;
+
+ if (identifiers_n)
+ {
+ /* Add closing braces for identifier lists as usual. */
+ for (i = 0; i < identifiers_n; i++)
+ sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
+ }
+ else
+ {
+ /* Add closing braces for special list. */
+ sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
+ }
+
+ /* Construct. */
+ err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
+ if (err)
+ goto out;
+
+ *sexp = sexp_new;
+
+ out:
+
+ gcry_free (sexp_buffer);
+ gcry_free (arg_list);
+
+ return err;
+}
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+ S-Expression SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t
+_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
+ const char **identifiers)
+{
+ gcry_ac_data_t data_set_new;
+ gcry_error_t err;
+ gcry_sexp_t sexp_cur;
+ gcry_sexp_t sexp_tmp;
+ gcry_mpi_t mpi;
+ char *string;
+ const char *data;
+ size_t data_n;
+ size_t sexp_n;
+ unsigned int i;
+ int skip_name;
+
+ data_set_new = NULL;
+ sexp_cur = sexp;
+ sexp_tmp = NULL;
+ string = NULL;
+ mpi = NULL;
+ err = 0;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ /* Process S-expression/identifiers. */
+
+ if (identifiers)
+ {
+ for (i = 0; identifiers[i]; i++)
+ {
+ /* Next identifier. Extract first data item from
+ SEXP_CUR. */
+ data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
+
+ if (! ((data_n == strlen (identifiers[i]))
+ && (! strncmp (data, identifiers[i], data_n))))
+ {
+ /* Identifier mismatch -> error. */
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ break;
+ }
+
+ /* Identifier matches. Now we have to distinguish two
+ cases:
+
+ (i) we are at the last identifier:
+ leave loop
+
+ (ii) we are not at the last identifier:
+ extract next element, which is supposed to be a
+ sublist. */
+
+ if (! identifiers[i + 1])
+ /* Last identifier. */
+ break;
+ else
+ {
+ /* Not the last identifier, extract next sublist. */
+
+ sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
+ if (! sexp_tmp)
+ {
+ /* Missing sublist. */
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ break;
+ }
+
+ /* Release old SEXP_CUR, in case it is not equal to the
+ original SEXP. */
+ if (sexp_cur != sexp)
+ gcry_sexp_release (sexp_cur);
+
+ /* Make SEXP_CUR point to the new current sublist. */
+ sexp_cur = sexp_tmp;
+ sexp_tmp = NULL;
+ }
+ }
+ if (err)
+ goto out;
+
+ if (i)
+ {
+ /* We have at least one identifier in the list, this means
+ the the list of named MPI values is prefixed, this means
+ that we need to skip the first item (the list name), when
+ processing the MPI values. */
+ skip_name = 1;
+ }
+ else
+ {
+ /* Since there is no identifiers list, the list of named MPI
+ values is not prefixed with a list name, therefore the
+ offset to use is zero. */
+ skip_name = 0;
+ }
+ }
+ else
+ /* Since there is no identifiers list, the list of named MPI
+ values is not prefixed with a list name, therefore the offset
+ to use is zero. */
+ skip_name = 0;
+
+ /* Create data set from S-expression data. */
+
+ err = gcry_ac_data_new (&data_set_new);
+ if (err)
+ goto out;
+
+ /* Figure out amount of named MPIs in SEXP_CUR. */
+ if (sexp_cur)
+ sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
+ else
+ sexp_n = 0;
+
+ /* Extracte the named MPIs sequentially. */
+ for (i = 0; i < sexp_n; i++)
+ {
+ /* Store next S-Expression pair, which is supposed to consist of
+ a name and an MPI value, in SEXP_TMP. */
+
+ sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
+ if (! sexp_tmp)
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ break;
+ }
+
+ /* Extract name from current S-Expression pair. */
+ data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
+ string = gcry_malloc (data_n + 1);
+ if (! string)
+ {
+ err = gcry_error_from_errno (errno);
+ break;
+ }
+ memcpy (string, data, data_n);
+ string[data_n] = 0;
+
+ /* Extract MPI value. */
+ mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
+ if (! mpi)
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
+ break;
+ }
+
+ /* Store named MPI in data_set_new. */
+ err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
+ if (err)
+ break;
+
+/* gcry_free (string); */
+ string = NULL;
+/* gcry_mpi_release (mpi); */
+ mpi = NULL;
+
+ gcry_sexp_release (sexp_tmp);
+ sexp_tmp = NULL;
+ }
+ if (err)
+ goto out;
+
+ *data_set = data_set_new;
+
+ out:
+
+ if (sexp_cur != sexp)
+ gcry_sexp_release (sexp_cur);
+ gcry_sexp_release (sexp_tmp);
+ gcry_mpi_release (mpi);
+ gcry_free (string);
+
+ if (err)
+ gcry_ac_data_destroy (data_set_new);
+
+ return err;
+}
+
+
+static void
+_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
+{
+ unsigned char *mpi_buffer;
+ size_t mpi_buffer_n;
+ unsigned int data_n;
+ gcry_error_t err;
+ const char *name;
+ gcry_mpi_t mpi;
+ unsigned int i;
+
+ if (! data)
+ return;
+
+ if (fips_mode ())
+ return;
+
+ mpi_buffer = NULL;
+
+ data_n = _gcry_ac_data_length (data);
+ for (i = 0; i < data_n; i++)
+ {
+ err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
+ if (err)
+ {
+ log_error ("failed to dump data set");
+ break;
+ }
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
+ if (err)
+ {
+ log_error ("failed to dump data set");
+ break;
+ }
+
+ log_printf ("%s%s%s: %s\n",
+ prefix ? prefix : "",
+ prefix ? ": " : ""
+ , name, mpi_buffer);
+
+ gcry_free (mpi_buffer);
+ mpi_buffer = NULL;
+ }
+
+ gcry_free (mpi_buffer);
+}
+
+/* Dump the named MPI values contained in the data set DATA to
+ Libgcrypt's logging stream. */
+void
+gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
+{
+ _gcry_ac_data_dump (prefix, data);
+}
+
+/* Destroys any values contained in the data set DATA. */
+void
+_gcry_ac_data_clear (gcry_ac_data_t data)
+{
+ ac_data_values_destroy (data);
+ gcry_free (data->data);
+ data->data = NULL;
+ data->data_n = 0;
+}
+
+\f
+
+/*
+ * Implementation of `ac io' objects.
+ */
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments AP. The list of variable arguments to specify depends on
+ the given TYPE. */
+void
+_gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
+ gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
+{
+ memset (ac_io, 0, sizeof (*ac_io));
+
+ if (fips_mode ())
+ return;
+
+ gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
+ gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
+
+ ac_io->mode = mode;
+ ac_io->type = type;
+
+ switch (mode)
+ {
+ case GCRY_AC_IO_READABLE:
+ switch (type)
+ {
+ case GCRY_AC_IO_STRING:
+ ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
+ ac_io->io.readable.string.data_n = va_arg (ap, size_t);
+ break;
+
+ case GCRY_AC_IO_CALLBACK:
+ ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
+ ac_io->io.readable.callback.opaque = va_arg (ap, void *);
+ break;
+ }
+ break;
+ case GCRY_AC_IO_WRITABLE:
+ switch (type)
+ {
+ case GCRY_AC_IO_STRING:
+ ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
+ ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
+ break;
+
+ case GCRY_AC_IO_CALLBACK:
+ ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
+ ac_io->io.writable.callback.opaque = va_arg (ap, void *);
+ break;
+ }
+ break;
+ }
+}
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments. The list of variable arguments to specify depends on
+ the given TYPE. */
+void
+_gcry_ac_io_init (gcry_ac_io_t *ac_io,
+ gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
+{
+ va_list ap;
+
+ va_start (ap, type);
+ _gcry_ac_io_init_va (ac_io, mode, type, ap);
+ va_end (ap);
+}
+
+
+/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER. Return
+ zero on success or error code. */
+static gcry_error_t
+_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
+{
+ gcry_error_t err;
+
+ gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
+ err = 0;
+
+ switch (ac_io->type)
+ {
+ case GCRY_AC_IO_STRING:
+ {
+ unsigned char *p;
+
+ if (*ac_io->io.writable.string.data)
+ {
+ p = gcry_realloc (*ac_io->io.writable.string.data,
+ *ac_io->io.writable.string.data_n + buffer_n);
+ if (! p)
+ err = gcry_error_from_errno (errno);
+ else
+ {
+ if (*ac_io->io.writable.string.data != p)
+ *ac_io->io.writable.string.data = p;
+ memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
+ *ac_io->io.writable.string.data_n += buffer_n;
+ }
+ }
+ else
+ {
+ if (gcry_is_secure (buffer))
+ p = gcry_malloc_secure (buffer_n);
+ else
+ p = gcry_malloc (buffer_n);
+ if (! p)
+ err = gcry_error_from_errno (errno);
+ else
+ {
+ memcpy (p, buffer, buffer_n);
+ *ac_io->io.writable.string.data = p;
+ *ac_io->io.writable.string.data_n = buffer_n;
+ }
+ }
+ }
+ break;
+
+ case GCRY_AC_IO_CALLBACK:
+ err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
+ buffer, buffer_n);
+ break;
+ }
+
+ return err;
+}
+
+/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
+ bytes have already been read from the object; on success, store the
+ amount of bytes read in *BUFFER_N; zero bytes read means EOF.
+ Return zero on success or error code. */
+static gcry_error_t
+_gcry_ac_io_read (gcry_ac_io_t *ac_io,
+ unsigned int nread, unsigned char *buffer, size_t *buffer_n)
+{
+ gcry_error_t err;
+
+ gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
+ err = 0;
+
+ switch (ac_io->type)
+ {
+ case GCRY_AC_IO_STRING:
+ {
+ size_t bytes_available;
+ size_t bytes_to_read;
+ size_t bytes_wanted;
+
+ bytes_available = ac_io->io.readable.string.data_n - nread;
+ bytes_wanted = *buffer_n;
+
+ if (bytes_wanted > bytes_available)
+ bytes_to_read = bytes_available;
+ else
+ bytes_to_read = bytes_wanted;
+
+ memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
+ *buffer_n = bytes_to_read;
+ err = 0;
+ break;
+ }
+
+ case GCRY_AC_IO_CALLBACK:
+ err = (*ac_io->io.readable.callback.cb)
+ (ac_io->io.readable.callback.opaque, buffer, buffer_n);
+ break;
+ }
+
+ return err;
+}
+
+/* Read all data available from the IO object AC_IO into newly
+ allocated memory, storing an appropriate pointer in *BUFFER and the
+ amount of bytes read in *BUFFER_N. Return zero on success or error
+ code. */
+static gcry_error_t
+_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
+{
+ unsigned char *buffer_new;
+ size_t buffer_new_n;
+ unsigned char buf[BUFSIZ];
+ size_t buf_n;
+ unsigned char *p;
+ gcry_error_t err;
+
+ buffer_new = NULL;
+ buffer_new_n = 0;
+
+ while (1)
+ {
+ buf_n = sizeof (buf);
+ err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
+ if (err)
+ break;
+
+ if (buf_n)
+ {
+ p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
+ if (! p)
+ {
+ err = gcry_error_from_errno (errno);
+ break;
+ }
+
+ if (buffer_new != p)
+ buffer_new = p;
+
+ memcpy (buffer_new + buffer_new_n, buf, buf_n);
+ buffer_new_n += buf_n;
+ }
+ else
+ break;
+ }
+ if (err)
+ goto out;
+
+ *buffer_n = buffer_new_n;
+ *buffer = buffer_new;
+
+ out:
+
+ if (err)
+ gcry_free (buffer_new);
+
+ return err;
+}
+
+/* Read data chunks from the IO object AC_IO until EOF, feeding them
+ to the callback function CB. Return zero on success or error
+ code. */
+static gcry_error_t
+_gcry_ac_io_process (gcry_ac_io_t *ac_io,
+ gcry_ac_data_write_cb_t cb, void *opaque)
+{
+ unsigned char buffer[BUFSIZ];
+ unsigned int nread;
+ size_t buffer_n;
+ gcry_error_t err;
+
+ nread = 0;
+
+ while (1)
+ {
+ buffer_n = sizeof (buffer);
+ err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
+ if (err)
+ break;
+ if (buffer_n)
+ {
+ err = (*cb) (opaque, buffer, buffer_n);
+ if (err)
+ break;
+ nread += buffer_n;
+ }
+ else
+ break;
+ }
+
+ return err;
+}
+
+\f
+
+/*
+ * Functions for converting data between the native ac and the
+ * S-expression structure used by the pk interface.
+ */
+
+/* Extract the S-Expression DATA_SEXP into DATA under the control of
+ TYPE and NAME. This function assumes that S-Expressions are of the
+ following structure:
+
+ (IDENTIFIER [...]
+ (ALGORITHM <list of named MPI values>)) */
+static gcry_error_t
+ac_data_extract (const char *identifier, const char *algorithm,
+ gcry_sexp_t sexp, gcry_ac_data_t *data)
+{
+ gcry_error_t err;
+ gcry_sexp_t value_sexp;
+ gcry_sexp_t data_sexp;
+ size_t data_sexp_n;
+ gcry_mpi_t value_mpi;
+ char *value_name;
+ const char *data_raw;
+ size_t data_raw_n;
+ gcry_ac_data_t data_new;
+ unsigned int i;
+
+ value_sexp = NULL;
+ data_sexp = NULL;
+ value_name = NULL;
+ value_mpi = NULL;
+ data_new = NULL;
+
+ /* Verify that the S-expression contains the correct identifier. */
+ data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
+ if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ goto out;
+ }
+
+ /* Extract inner S-expression. */
+ data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
+ if (! data_sexp)
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ goto out;
+ }
+
+ /* Count data elements. */
+ data_sexp_n = gcry_sexp_length (data_sexp);
+ data_sexp_n--;
+
+ /* Allocate new data set. */
+ err = _gcry_ac_data_new (&data_new);
+ if (err)
+ goto out;
+
+ /* Iterate through list of data elements and add them to the data
+ set. */
+ for (i = 0; i < data_sexp_n; i++)
+ {
+ /* Get the S-expression of the named MPI, that contains the name
+ and the MPI value. */
+ value_sexp = gcry_sexp_nth (data_sexp, i + 1);
+ if (! value_sexp)
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ break;
+ }
+
+ /* Extract the name. */
+ data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
+ if (! data_raw)
+ {
+ err = gcry_error (GPG_ERR_INV_SEXP);
+ break;
+ }
+
+ /* Extract the MPI value. */
+ value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
+ if (! value_mpi)
+ {
+ err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
+ break;
+ }
+
+ /* Duplicate the name. */
+ value_name = gcry_malloc (data_raw_n + 1);
+ if (! value_name)
+ {
+ err = gcry_error_from_errno (errno);
+ break;
+ }
+ strncpy (value_name, data_raw, data_raw_n);
+ value_name[data_raw_n] = 0;
+
+ err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
+ if (err)
+ break;
+
+ gcry_sexp_release (value_sexp);
+ value_sexp = NULL;
+ value_name = NULL;
+ value_mpi = NULL;
+ }
+ if (err)
+ goto out;
+
+ /* Copy out. */
+ *data = data_new;
+
+ out:
+
+ /* Deallocate resources. */
+ if (err)
+ {
+ _gcry_ac_data_destroy (data_new);
+ gcry_mpi_release (value_mpi);
+ gcry_free (value_name);
+ gcry_sexp_release (value_sexp);
+ }
+ gcry_sexp_release (data_sexp);
+
+ return err;
+}
+
+/* Construct an S-expression from the DATA and store it in
+ DATA_SEXP. The S-expression will be of the following structure:
+
+ (IDENTIFIER [(flags [...])]
+ (ALGORITHM <list of named MPI values>)) */
+static gcry_error_t
+ac_data_construct (const char *identifier, int include_flags,
+ unsigned int flags, const char *algorithm,
+ gcry_ac_data_t data, gcry_sexp_t *sexp)
+{
+ unsigned int data_length;
+ gcry_sexp_t sexp_new;
+ gcry_error_t err;
+ size_t sexp_format_n;
+ char *sexp_format;
+ void **arg_list;
+ unsigned int i;
+
+ arg_list = NULL;
+ sexp_new = NULL;
+ sexp_format = NULL;
+
+ /* We build a list of arguments to pass to
+ gcry_sexp_build_array(). */
+ data_length = _gcry_ac_data_length (data);
+ arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
+ if (! arg_list)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Fill list with MPIs. */
+ for (i = 0; i < data_length; i++)
+ {
+ char **nameaddr = &data->data[i].name;
+
+ arg_list[(i * 2) + 0] = nameaddr;
+ arg_list[(i * 2) + 1] = &data->data[i].mpi;
+ }
+
+ /* Calculate size of format string. */
+ sexp_format_n = (3
+ + (include_flags ? 7 : 0)
+ + (algorithm ? (2 + strlen (algorithm)) : 0)
+ + strlen (identifier));
+
+ for (i = 0; i < data_length; i++)
+ /* Per-element sizes. */
+ sexp_format_n += 6;
+
+ if (include_flags)
+ /* Add flags. */
+ for (i = 0; i < DIM (ac_flags); i++)
+ if (flags & ac_flags[i].number)
+ sexp_format_n += strlen (ac_flags[i].string) + 1;
+
+ /* Done. */
+ sexp_format = gcry_malloc (sexp_format_n);
+ if (! sexp_format)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Construct the format string. */
+
+ *sexp_format = 0;
+ strcat (sexp_format, "(");
+ strcat (sexp_format, identifier);
+ if (include_flags)
+ {
+ strcat (sexp_format, "(flags");
+ for (i = 0; i < DIM (ac_flags); i++)
+ if (flags & ac_flags[i].number)
+ {
+ strcat (sexp_format, " ");
+ strcat (sexp_format, ac_flags[i].string);
+ }
+ strcat (sexp_format, ")");
+ }
+ if (algorithm)
+ {
+ strcat (sexp_format, "(");
+ strcat (sexp_format, algorithm);
+ }
+ for (i = 0; i < data_length; i++)
+ strcat (sexp_format, "(%s%m)");
+ if (algorithm)
+ strcat (sexp_format, ")");
+ strcat (sexp_format, ")");
+
+ /* Create final S-expression. */
+ err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
+ if (err)
+ goto out;
+
+ *sexp = sexp_new;
+
+ out:
+
+ /* Deallocate resources. */
+ gcry_free (sexp_format);
+ gcry_free (arg_list);
+ if (err)
+ gcry_sexp_release (sexp_new);
+
+ return err;
+}
+
+\f
+
+/*
+ * Handle management.
+ */
+
+/* Creates a new handle for the algorithm ALGORITHM and stores it in
+ HANDLE. FLAGS is not used yet. */
+gcry_error_t
+_gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+{
+ gcry_ac_handle_t handle_new;
+ const char *algorithm_name;
+ gcry_module_t module;
+ gcry_error_t err;
+
+ *handle = NULL;
+ module = NULL;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ /* Get name. */
+ algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
+ if (! algorithm_name)
+ {
+ err = gcry_error (GPG_ERR_PUBKEY_ALGO);
+ goto out;
+ }
+
+ /* Acquire reference to the pubkey module. */
+ err = _gcry_pk_module_lookup (algorithm, &module);
+ if (err)
+ goto out;
+
+ /* Allocate. */
+ handle_new = gcry_malloc (sizeof (*handle_new));
+ if (! handle_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Done. */
+ handle_new->algorithm = algorithm;
+ handle_new->algorithm_name = algorithm_name;
+ handle_new->flags = flags;
+ handle_new->module = module;
+ *handle = handle_new;
+
+ out:
+
+ /* Deallocate resources. */
+ if (err)
+ _gcry_pk_module_release (module);
+
+ return err;
+}
+
+
+/* Destroys the handle HANDLE. */
+void
+_gcry_ac_close (gcry_ac_handle_t handle)
+{
+ /* Release reference to pubkey module. */
+ if (handle)
+ {
+ _gcry_pk_module_release (handle->module);
+ gcry_free (handle);
+ }
+}
+
+
+\f
+/*
+ * Key management.
+ */
+
+/* Initialize a key from a given data set. */
+/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
+ completely WRONG here. */
+gcry_error_t
+_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+{
+ gcry_ac_data_t data_new;
+ gcry_ac_key_t key_new;
+ gcry_error_t err;
+
+ (void)handle;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ /* Allocate. */
+ key_new = gcry_malloc (sizeof (*key_new));
+ if (! key_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Copy data set. */
+ err = _gcry_ac_data_copy (&data_new, data);
+ if (err)
+ goto out;
+
+ /* Done. */
+ key_new->data = data_new;
+ key_new->type = type;
+ *key = key_new;
+
+ out:
+
+ if (err)
+ /* Deallocate resources. */
+ gcry_free (key_new);
+
+ return err;
+}
+
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+ stores it in KEY_PAIR. In case non-standard settings are wanted, a
+ pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+ matching the selected algorithm, can be given as KEY_SPEC.
+ MISC_DATA is not used yet. */
+gcry_error_t
+_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
+ void *key_spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data)
+{
+ gcry_sexp_t genkey_sexp_request;
+ gcry_sexp_t genkey_sexp_reply;
+ gcry_ac_data_t key_data_secret;
+ gcry_ac_data_t key_data_public;
+ gcry_ac_key_pair_t key_pair_new;
+ gcry_ac_key_t key_secret;
+ gcry_ac_key_t key_public;
+ gcry_sexp_t key_sexp;
+ gcry_error_t err;
+ char *genkey_format;
+ size_t genkey_format_n;
+ void **arg_list;
+ size_t arg_list_n;
+ unsigned int i;
+ unsigned int j;
+
+ (void)misc_data;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ key_data_secret = NULL;
+ key_data_public = NULL;
+ key_secret = NULL;
+ key_public = NULL;
+ genkey_format = NULL;
+ arg_list = NULL;
+ genkey_sexp_request = NULL;
+ genkey_sexp_reply = NULL;
+ key_sexp = NULL;
+
+ /* Allocate key pair. */
+ key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
+ if (! key_pair_new)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Allocate keys. */
+ key_secret = gcry_malloc (sizeof (*key_secret));
+ if (! key_secret)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ key_public = gcry_malloc (sizeof (*key_public));
+ if (! key_public)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Calculate size of the format string, that is used for creating
+ the request S-expression. */
+ genkey_format_n = 22;
+
+ /* Respect any relevant algorithm specific commands. */
+ if (key_spec)
+ for (i = 0; i < DIM (ac_key_generate_specs); i++)
+ if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+ genkey_format_n += 6;
+
+ /* Create format string. */
+ genkey_format = gcry_malloc (genkey_format_n);
+ if (! genkey_format)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Fill format string. */
+ *genkey_format = 0;
+ strcat (genkey_format, "(genkey(%s(nbits%d)");
+ if (key_spec)
+ for (i = 0; i < DIM (ac_key_generate_specs); i++)
+ if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+ strcat (genkey_format, "(%s%m)");
+ strcat (genkey_format, "))");
+
+ /* Build list of argument pointers, the algorithm name and the nbits
+ are always needed. */
+ arg_list_n = 2;
+
+ /* Now the algorithm specific arguments. */
+ if (key_spec)
+ for (i = 0; i < DIM (ac_key_generate_specs); i++)
+ if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+ arg_list_n += 2;
+
+ /* Allocate list. */
+ arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
+ if (! arg_list)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ arg_list[0] = (void *) &handle->algorithm_name;
+ arg_list[1] = (void *) &nbits;
+ if (key_spec)
+ for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
+ if (handle->algorithm == ac_key_generate_specs[i].algorithm)
+ {
+ /* Add name of this specification flag and the
+ according member of the spec strucuture. */
+ arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
+ arg_list[j++] = (void *)
+ (((char *) key_spec)
+ + ac_key_generate_specs[i].offset);
+ /* FIXME: above seems to suck. */
+ }
+
+ /* Construct final request S-expression. */
+ err = gcry_sexp_build_array (&genkey_sexp_request,
+ NULL, genkey_format, arg_list);
+ if (err)
+ goto out;
+
+ /* Perform genkey operation. */
+ err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
+ if (err)
+ goto out;
+
+ key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
+ if (! key_sexp)
+ {
+ err = gcry_error (GPG_ERR_INTERNAL);
+ goto out;
+ }
+ err = ac_data_extract ("private-key", handle->algorithm_name,
+ key_sexp, &key_data_secret);
+ if (err)
+ goto out;
+
+ gcry_sexp_release (key_sexp);
+ key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
+ if (! key_sexp)
+ {
+ err = gcry_error (GPG_ERR_INTERNAL);
+ goto out;
+ }
+ err = ac_data_extract ("public-key", handle->algorithm_name,
+ key_sexp, &key_data_public);
+ if (err)
+ goto out;
+
+ /* Done. */
+
+ key_secret->type = GCRY_AC_KEY_SECRET;
+ key_secret->data = key_data_secret;
+ key_public->type = GCRY_AC_KEY_PUBLIC;
+ key_public->data = key_data_public;
+ key_pair_new->secret = key_secret;
+ key_pair_new->public = key_public;
+ *key_pair = key_pair_new;
+
+ out:
+
+ /* Deallocate resources. */
+
+ gcry_free (genkey_format);
+ gcry_free (arg_list);
+ gcry_sexp_release (genkey_sexp_request);
+ gcry_sexp_release (genkey_sexp_reply);
+ gcry_sexp_release (key_sexp);
+ if (err)
+ {
+ _gcry_ac_data_destroy (key_data_secret);
+ _gcry_ac_data_destroy (key_data_public);
+ gcry_free (key_secret);
+ gcry_free (key_public);
+ gcry_free (key_pair_new);
+ }
+
+ return err;
+}
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
+gcry_ac_key_t
+_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which)
+{
+ gcry_ac_key_t key;
+
+ if (fips_mode ())
+ return NULL;
+
+ switch (which)
+ {
+ case GCRY_AC_KEY_SECRET:
+ key = key_pair->secret;
+ break;
+
+ case GCRY_AC_KEY_PUBLIC:
+ key = key_pair->public;
+ break;
+
+ default:
+ key = NULL;
+ break;
+ }
+
+ return key;
+}
+
+/* Destroys the key KEY. */
+void
+_gcry_ac_key_destroy (gcry_ac_key_t key)
+{
+ unsigned int i;
+
+ if (key)
+ {
+ if (key->data)
+ {
+ for (i = 0; i < key->data->data_n; i++)
+ {
+ if (key->data->data[i].mpi)
+ gcry_mpi_release (key->data->data[i].mpi);
+ if (key->data->data[i].name)
+ gcry_free (key->data->data[i].name);
+ }
+ gcry_free (key->data->data);
+ gcry_free (key->data);
+ }
+ gcry_free (key);
+ }
+}
+
+/* Destroys the key pair KEY_PAIR. */
+void
+_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+{
+ if (key_pair)
+ {
+ gcry_ac_key_destroy (key_pair->secret);
+ gcry_ac_key_destroy (key_pair->public);
+ gcry_free (key_pair);
+ }
+}
+
+/* Returns the data set contained in the key KEY. */
+gcry_ac_data_t
+_gcry_ac_key_data_get (gcry_ac_key_t key)
+{
+ if (fips_mode ())
+ return NULL;
+ return key->data;
+}
+
+/* Verifies that the key KEY is sane via HANDLE. */
+gcry_error_t
+_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+{
+ gcry_sexp_t key_sexp;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ key_sexp = NULL;
+ err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+ handle->algorithm_name, key->data, &key_sexp);
+ if (err)
+ goto out;
+
+ err = gcry_pk_testkey (key_sexp);
+
+ out:
+
+ gcry_sexp_release (key_sexp);
+
+ return gcry_error (err);
+}
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE. */
+gcry_error_t
+_gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+{
+ gcry_sexp_t key_sexp;
+ gcry_error_t err;
+ unsigned int n;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ key_sexp = NULL;
+
+ err = ac_data_construct (ac_key_identifiers[key->type],
+ 0, 0, handle->algorithm_name, key->data, &key_sexp);
+ if (err)
+ goto out;
+
+ n = gcry_pk_get_nbits (key_sexp);
+ if (! n)
+ {
+ err = gcry_error (GPG_ERR_PUBKEY_ALGO);
+ goto out;
+ }
+
+ *nbits = n;
+
+ out:
+
+ gcry_sexp_release (key_sexp);
+
+ return err;
+}
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+ HANDLE. */
+gcry_error_t
+_gcry_ac_key_get_grip (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned char *key_grip)
+{
+ gcry_sexp_t key_sexp;
+ gcry_error_t err;
+ unsigned char *ret;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ key_sexp = NULL;
+ err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+ handle->algorithm_name, key->data, &key_sexp);
+ if (err)
+ goto out;
+
+ ret = gcry_pk_get_keygrip (key_sexp, key_grip);
+ if (! ret)
+ {
+ err = gcry_error (GPG_ERR_INV_OBJ);
+ goto out;
+ }
+
+ err = 0;
+
+ out:
+
+ gcry_sexp_release (key_sexp);
+
+ return err;
+}
+
+
+\f
+
+/*
+ * Functions performing cryptographic operations.
+ */
+
+/* Encrypts the plain text MPI value DATA_PLAIN with the key public
+ KEY under the control of the flags FLAGS and stores the resulting
+ data set into DATA_ENCRYPTED. */
+gcry_error_t
+_gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+{
+ gcry_ac_data_t data_encrypted_new;
+ gcry_ac_data_t data_value;
+ gcry_sexp_t sexp_request;
+ gcry_sexp_t sexp_reply;
+ gcry_sexp_t sexp_key;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_encrypted_new = NULL;
+ sexp_request = NULL;
+ sexp_reply = NULL;
+ data_value = NULL;
+ sexp_key = NULL;
+
+ if (key->type != GCRY_AC_KEY_PUBLIC)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+ handle->algorithm_name, key->data, &sexp_key);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_new (&data_value);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
+ if (err)
+ goto out;
+
+ err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
+ data_value, &sexp_request);
+ if (err)
+ goto out;
+
+ /* FIXME: error vs. errcode? */
+
+ err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
+ if (err)
+ goto out;
+
+ /* Extract data. */
+ err = ac_data_extract ("enc-val", handle->algorithm_name,
+ sexp_reply, &data_encrypted_new);
+ if (err)
+ goto out;
+
+ *data_encrypted = data_encrypted_new;
+
+ out:
+
+ /* Deallocate resources. */
+
+ gcry_sexp_release (sexp_request);
+ gcry_sexp_release (sexp_reply);
+ gcry_sexp_release (sexp_key);
+ _gcry_ac_data_destroy (data_value);
+
+ return err;
+}
+
+/* Decrypts the encrypted data contained in the data set
+ DATA_ENCRYPTED with the secret key KEY under the control of the
+ flags FLAGS and stores the resulting plain text MPI value in
+ DATA_PLAIN. */
+gcry_error_t
+_gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+{
+ gcry_mpi_t data_decrypted;
+ gcry_sexp_t sexp_request;
+ gcry_sexp_t sexp_reply;
+ gcry_sexp_t sexp_value;
+ gcry_sexp_t sexp_key;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ sexp_request = NULL;
+ sexp_reply = NULL;
+ sexp_value = NULL;
+ sexp_key = NULL;
+
+ if (key->type != GCRY_AC_KEY_SECRET)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+ handle->algorithm_name, key->data, &sexp_key);
+ if (err)
+ goto out;
+
+ /* Create S-expression from data. */
+ err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
+ data_encrypted, &sexp_request);
+ if (err)
+ goto out;
+
+ /* Decrypt. */
+ err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
+ if (err)
+ goto out;
+
+ /* Extract plain text. */
+ sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
+ if (! sexp_value)
+ {
+ /* FIXME? */
+ err = gcry_error (GPG_ERR_GENERAL);
+ goto out;
+ }
+
+ data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
+ if (! data_decrypted)
+ {
+ err = gcry_error (GPG_ERR_GENERAL);
+ goto out;
+ }
+
+ *data_plain = data_decrypted;
+
+ out:
+
+ /* Deallocate resources. */
+ gcry_sexp_release (sexp_request);
+ gcry_sexp_release (sexp_reply);
+ gcry_sexp_release (sexp_value);
+ gcry_sexp_release (sexp_key);
+
+ return gcry_error (err);
+
+}
+
+/* Signs the data contained in DATA with the secret key KEY and stores
+ the resulting signature data set in DATA_SIGNATURE. */
+gcry_error_t
+_gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+{
+ gcry_ac_data_t data_signed;
+ gcry_ac_data_t data_value;
+ gcry_sexp_t sexp_request;
+ gcry_sexp_t sexp_reply;
+ gcry_sexp_t sexp_key;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_signed = NULL;
+ data_value = NULL;
+ sexp_request = NULL;
+ sexp_reply = NULL;
+ sexp_key = NULL;
+
+ if (key->type != GCRY_AC_KEY_SECRET)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
+ handle->algorithm_name, key->data, &sexp_key);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_new (&data_value);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_set (data_value, 0, "value", data);
+ if (err)
+ goto out;
+
+ /* Create S-expression holding the data. */
+ err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
+ if (err)
+ goto out;
+
+ /* Sign. */
+ err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
+ if (err)
+ goto out;
+
+ /* Extract data. */
+ err = ac_data_extract ("sig-val", handle->algorithm_name,
+ sexp_reply, &data_signed);
+ if (err)
+ goto out;
+
+ /* Done. */
+ *data_signature = data_signed;
+
+ out:
+
+ gcry_sexp_release (sexp_request);
+ gcry_sexp_release (sexp_reply);
+ gcry_sexp_release (sexp_key);
+ _gcry_ac_data_destroy (data_value);
+
+ return gcry_error (err);
+}
+
+
+/* Verifies that the signature contained in the data set
+ DATA_SIGNATURE is indeed the result of signing the data contained
+ in DATA with the secret key belonging to the public key KEY. */
+gcry_error_t
+_gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+{
+ gcry_sexp_t sexp_signature;
+ gcry_ac_data_t data_value;
+ gcry_sexp_t sexp_data;
+ gcry_sexp_t sexp_key;
+ gcry_error_t err;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ sexp_signature = NULL;
+ data_value = NULL;
+ sexp_data = NULL;
+ sexp_key = NULL;
+
+ err = ac_data_construct ("public-key", 0, 0,
+ handle->algorithm_name, key->data, &sexp_key);
+ if (err)
+ goto out;
+
+ if (key->type != GCRY_AC_KEY_PUBLIC)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ /* Construct S-expression holding the signature data. */
+ err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
+ data_signature, &sexp_signature);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_new (&data_value);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_set (data_value, 0, "value", data);
+ if (err)
+ goto out;
+
+ /* Construct S-expression holding the data. */
+ err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
+ if (err)
+ goto out;
+
+ /* Verify signature. */
+ err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
+
+ out:
+
+ gcry_sexp_release (sexp_signature);
+ gcry_sexp_release (sexp_data);
+ gcry_sexp_release (sexp_key);
+ _gcry_ac_data_destroy (data_value);
+
+ return gcry_error (err);
+}
+
+
+
+\f
+/*
+ * Implementation of encoding methods (em).
+ */
+
+/* Type for functions that encode or decode (hence the name) a
+ message. */
+typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
+ void *options,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write);
+
+/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
+ random bytes of random level LEVEL. */
+static void
+em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
+ gcry_random_level_t level)
+{
+ unsigned char *buffer_rand;
+ unsigned int buffer_rand_n;
+ unsigned int zeros;
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < buffer_n; i++)
+ buffer[i] = 0;
+
+ do
+ {
+ /* Count zeros. */
+ for (i = zeros = 0; i < buffer_n; i++)
+ if (! buffer[i])
+ zeros++;
+
+ if (zeros)
+ {
+ /* Get random bytes. */
+ buffer_rand_n = zeros + (zeros / 128);
+ buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
+
+ /* Substitute zeros with non-zero random bytes. */
+ for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
+ if (! buffer[i])
+ {
+ while ((j < buffer_rand_n) && (! buffer_rand[j]))
+ j++;
+ if (j < buffer_rand_n)
+ {
+ buffer[i] = buffer_rand[j++];
+ zeros--;
+ }
+ else
+ break;
+ }
+ gcry_free (buffer_rand);
+ }
+ }
+ while (zeros);
+}
+
+/* Encode a message according to the Encoding Method for Encryption
+ `PKCS-V1_5' (EME-PKCS-V1_5). */
+static gcry_error_t
+eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ gcry_ac_eme_pkcs_v1_5_t *options;
+ gcry_error_t err;
+ unsigned char *buffer;
+ unsigned char *ps;
+ unsigned char *m;
+ size_t m_n;
+ unsigned int ps_n;
+ unsigned int k;
+
+ (void)flags;
+
+ options = opts;
+ buffer = NULL;
+ m = NULL;
+
+ err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
+ if (err)
+ goto out;
+
+ /* Figure out key length in bytes. */
+ k = options->key_size / 8;
+
+ if (m_n > k - 11)
+ {
+ /* Key is too short for message. */
+ err = gcry_error (GPG_ERR_TOO_SHORT);
+ goto out;
+ }
+
+ /* According to this encoding method, the first byte of the encoded
+ message is zero. This byte will be lost anyway, when the encoded
+ message is to be converted into an MPI, that's why we skip
+ it. */
+
+ /* Allocate buffer. */
+ buffer = gcry_malloc (k - 1);
+ if (! buffer)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Generate an octet string PS of length k - mLen - 3 consisting
+ of pseudorandomly generated nonzero octets. The length of PS
+ will be at least eight octets. */
+ ps_n = k - m_n - 3;
+ ps = buffer + 1;
+ em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
+
+ /* Concatenate PS, the message M, and other padding to form an
+ encoded message EM of length k octets as:
+
+ EM = 0x00 || 0x02 || PS || 0x00 || M. */
+
+ buffer[0] = 0x02;
+ buffer[ps_n + 1] = 0x00;
+ memcpy (buffer + ps_n + 2, m, m_n);
+
+ err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
+
+ out:
+
+ gcry_free (buffer);
+ gcry_free (m);
+
+ return err;
+}
+
+/* Decode a message according to the Encoding Method for Encryption
+ `PKCS-V1_5' (EME-PKCS-V1_5). */
+static gcry_error_t
+eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ gcry_ac_eme_pkcs_v1_5_t *options;
+ unsigned char *buffer;
+ unsigned char *em;
+ size_t em_n;
+ gcry_error_t err;
+ unsigned int i;
+ unsigned int k;
+
+ (void)flags;
+
+ options = opts;
+ buffer = NULL;
+ em = NULL;
+
+ err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
+ if (err)
+ goto out;
+
+ /* Figure out key size. */
+ k = options->key_size / 8;
+
+ /* Search for zero byte. */
+ for (i = 0; (i < em_n) && em[i]; i++);
+
+ /* According to this encoding method, the first byte of the encoded
+ message should be zero. This byte is lost. */
+
+ if (! ((em_n >= 10)
+ && (em_n == (k - 1))
+ && (em[0] == 0x02)
+ && (i < em_n)
+ && ((i - 1) >= 8)))
+ {
+ err = gcry_error (GPG_ERR_DECRYPT_FAILED);
+ goto out;
+ }
+
+ i++;
+ buffer = gcry_malloc (em_n - i);
+ if (! buffer)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ memcpy (buffer, em + i, em_n - i);
+ err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
+
+ out:
+
+ gcry_free (buffer);
+ gcry_free (em);
+
+ return err;
+}
+
+static gcry_error_t
+emsa_pkcs_v1_5_encode_data_cb (void *opaque,
+ unsigned char *buffer, size_t buffer_n)
+{
+ gcry_md_hd_t md_handle;
+
+ md_handle = opaque;
+ gcry_md_write (md_handle, buffer, buffer_n);
+
+ return 0;
+}
+
+
+/* Encode a message according to the Encoding Method for Signatures
+ with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5). */
+static gcry_error_t
+emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ gcry_ac_emsa_pkcs_v1_5_t *options;
+ gcry_error_t err;
+ gcry_md_hd_t md;
+ unsigned char *t;
+ size_t t_n;
+ unsigned char *h;
+ size_t h_n;
+ unsigned char *ps;
+ size_t ps_n;
+ unsigned char *buffer;
+ size_t buffer_n;
+ unsigned char asn[100]; /* FIXME, always enough? */
+ size_t asn_n;
+ unsigned int i;
+
+ (void)flags;
+
+ options = opts;
+ buffer = NULL;
+ md = NULL;
+ ps = NULL;
+ t = NULL;
+
+ /* Create hashing handle and get the necessary information. */
+ err = gcry_md_open (&md, options->md, 0);
+ if (err)
+ goto out;
+
+ asn_n = DIM (asn);
+ err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
+ if (err)
+ goto out;
+
+ h_n = gcry_md_get_algo_dlen (options->md);
+
+ err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
+ if (err)
+ goto out;
+
+ h = gcry_md_read (md, 0);
+
+ /* Encode the algorithm ID for the hash function and the hash value
+ into an ASN.1 value of type DigestInfo with the Distinguished
+ Encoding Rules (DER), where the type DigestInfo has the syntax:
+
+ DigestInfo ::== SEQUENCE {
+ digestAlgorithm AlgorithmIdentifier,
+ digest OCTET STRING
+ }
+
+ The first field identifies the hash function and the second
+ contains the hash value. Let T be the DER encoding of the
+ DigestInfo value and let tLen be the length in octets of T. */
+
+ t_n = asn_n + h_n;
+ t = gcry_malloc (t_n);
+ if (! t)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ for (i = 0; i < asn_n; i++)
+ t[i] = asn[i];
+ for (i = 0; i < h_n; i++)
+ t[asn_n + i] = h[i];
+
+ /* If emLen < tLen + 11, output "intended encoded message length
+ too short" and stop. */
+ if (options->em_n < t_n + 11)
+ {
+ err = gcry_error (GPG_ERR_TOO_SHORT);
+ goto out;
+ }
+
+ /* Generate an octet string PS consisting of emLen - tLen - 3 octets
+ with hexadecimal value 0xFF. The length of PS will be at least 8
+ octets. */
+ ps_n = options->em_n - t_n - 3;
+ ps = gcry_malloc (ps_n);
+ if (! ps)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ for (i = 0; i < ps_n; i++)
+ ps[i] = 0xFF;
+
+ /* Concatenate PS, the DER encoding T, and other padding to form the
+ encoded message EM as:
+
+ EM = 0x00 || 0x01 || PS || 0x00 || T. */
+
+ buffer_n = ps_n + t_n + 3;
+ buffer = gcry_malloc (buffer_n);
+ if (! buffer)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ buffer[0] = 0x00;
+ buffer[1] = 0x01;
+ for (i = 0; i < ps_n; i++)
+ buffer[2 + i] = ps[i];
+ buffer[2 + ps_n] = 0x00;
+ for (i = 0; i < t_n; i++)
+ buffer[3 + ps_n + i] = t[i];
+
+ err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
+
+ out:
+
+ gcry_md_close (md);
+
+ gcry_free (buffer);
+ gcry_free (ps);
+ gcry_free (t);
+
+ return err;
+}
+
+/* `Actions' for data_dencode(). */
+typedef enum dencode_action
+ {
+ DATA_ENCODE,
+ DATA_DECODE,
+ }
+dencode_action_t;
+
+/* Encode or decode a message according to the the encoding method
+ METHOD; ACTION specifies whether the message that is contained in
+ BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
+ The resulting message will be stored in a newly allocated buffer in
+ BUFFER_OUT and BUFFER_OUT_N. */
+static gcry_error_t
+ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ struct
+ {
+ gcry_ac_em_t method;
+ gcry_ac_em_dencode_t encode;
+ gcry_ac_em_dencode_t decode;
+ } methods[] =
+ {
+ { GCRY_AC_EME_PKCS_V1_5,
+ eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
+ { GCRY_AC_EMSA_PKCS_V1_5,
+ emsa_pkcs_v1_5_encode, NULL },
+ };
+ size_t methods_n;
+ gcry_error_t err;
+ unsigned int i;
+
+ methods_n = sizeof (methods) / sizeof (*methods);
+
+ for (i = 0; i < methods_n; i++)
+ if (methods[i].method == method)
+ break;
+ if (i == methods_n)
+ {
+ err = gcry_error (GPG_ERR_NOT_FOUND); /* FIXME? */
+ goto out;
+ }
+
+ err = 0;
+ switch (action)
+ {
+ case DATA_ENCODE:
+ if (methods[i].encode)
+ /* FIXME? */
+ err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
+ break;
+
+ case DATA_DECODE:
+ if (methods[i].decode)
+ /* FIXME? */
+ err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
+ break;
+
+ default:
+ err = gcry_error (GPG_ERR_INV_ARG);
+ break;
+ }
+
+ out:
+
+ return err;
+}
+
+/* Encode a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t
+_gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ return ac_data_dencode (method, DATA_ENCODE, flags, options,
+ ac_io_read, ac_io_write);
+}
+
+/* Dencode a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t
+_gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *ac_io_read,
+ gcry_ac_io_t *ac_io_write)
+{
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ return ac_data_dencode (method, DATA_DECODE, flags, options,
+ ac_io_read, ac_io_write);
+}
+
+/* Convert an MPI into an octet string. */
+void
+_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
+{
+ unsigned long digit;
+ gcry_mpi_t base;
+ unsigned int i;
+ unsigned int n;
+ gcry_mpi_t m;
+ gcry_mpi_t d;
+
+ if (fips_mode ())
+ return;
+
+ base = gcry_mpi_new (0);
+ gcry_mpi_set_ui (base, 256);
+
+ n = 0;
+ m = gcry_mpi_copy (mpi);
+ while (gcry_mpi_cmp_ui (m, 0))
+ {
+ n++;
+ gcry_mpi_div (m, NULL, m, base, 0);
+ }
+
+ gcry_mpi_set (m, mpi);
+ d = gcry_mpi_new (0);
+ for (i = 0; (i < n) && (i < os_n); i++)
+ {
+ gcry_mpi_mod (d, m, base);
+ _gcry_mpi_get_ui (d, &digit);
+ gcry_mpi_div (m, NULL, m, base, 0);
+ os[os_n - i - 1] = (digit & 0xFF);
+ }
+
+ for (; i < os_n; i++)
+ os[os_n - i - 1] = 0;
+
+ gcry_mpi_release (base);
+ gcry_mpi_release (d);
+ gcry_mpi_release (m);
+}
+
+/* Convert an MPI into an newly allocated octet string. */
+gcry_error_t
+_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
+{
+ unsigned char *buffer;
+ size_t buffer_n;
+ gcry_error_t err;
+ unsigned int nbits;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ nbits = gcry_mpi_get_nbits (mpi);
+ buffer_n = (nbits + 7) / 8;
+ buffer = gcry_malloc (buffer_n);
+ if (! buffer)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
+ *os = buffer;
+ *os_n = buffer_n;
+ err = 0;
+
+ out:
+
+ return err;
+}
+
+
+/* Convert an octet string into an MPI. */
+void
+_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
+{
+ unsigned int i;
+ gcry_mpi_t xi;
+ gcry_mpi_t x;
+ gcry_mpi_t a;
+
+ if (fips_mode ())
+ return;
+
+ a = gcry_mpi_new (0);
+ gcry_mpi_set_ui (a, 1);
+ x = gcry_mpi_new (0);
+ gcry_mpi_set_ui (x, 0);
+ xi = gcry_mpi_new (0);
+
+ for (i = 0; i < os_n; i++)
+ {
+ gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
+ gcry_mpi_add (x, x, xi);
+ gcry_mpi_mul_ui (a, a, 256);
+ }
+
+ gcry_mpi_release (xi);
+ gcry_mpi_release (a);
+
+ gcry_mpi_set (mpi, x);
+ gcry_mpi_release (x); /* FIXME: correct? */
+}
+
+
+\f
+/*
+ * Implementation of Encryption Schemes (ES) and Signature Schemes
+ * with Appendix (SSA).
+ */
+
+/* Schemes consist of two things: encoding methods and cryptographic
+ primitives.
+
+ Since encoding methods are accessible through a common API with
+ method-specific options passed as an anonymous struct, schemes have
+ to provide functions that construct this method-specific structure;
+ this is what the functions of type `gcry_ac_dencode_prepare_t' are
+ there for. */
+
+typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ void *opts,
+ void *opts_em);
+
+/* The `dencode_prepare' function for ES-PKCS-V1_5. */
+static gcry_error_t
+ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ void *opts, void *opts_em)
+{
+ gcry_ac_eme_pkcs_v1_5_t *options_em;
+ unsigned int nbits;
+ gcry_error_t err;
+
+ (void)opts;
+
+ err = _gcry_ac_key_get_nbits (handle, key, &nbits);
+ if (err)
+ goto out;
+
+ options_em = opts_em;
+ options_em->key_size = nbits;
+
+ out:
+
+ return err;
+}
+
+/* The `dencode_prepare' function for SSA-PKCS-V1_5. */
+static gcry_error_t
+ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ void *opts, void *opts_em)
+{
+ gcry_ac_emsa_pkcs_v1_5_t *options_em;
+ gcry_ac_ssa_pkcs_v1_5_t *options;
+ gcry_error_t err;
+ unsigned int k;
+
+ options_em = opts_em;
+ options = opts;
+
+ err = _gcry_ac_key_get_nbits (handle, key, &k);
+ if (err)
+ goto out;
+
+ k = (k + 7) / 8;
+ options_em->md = options->md;
+ options_em->em_n = k;
+
+ out:
+
+ return err;
+}
+
+/* Type holding the information about each supported
+ Encryption/Signature Scheme. */
+typedef struct ac_scheme
+{
+ gcry_ac_scheme_t scheme;
+ gcry_ac_em_t scheme_encoding;
+ gcry_ac_dencode_prepare_t dencode_prepare;
+ size_t options_em_n;
+} ac_scheme_t;
+
+/* List of supported Schemes. */
+static ac_scheme_t ac_schemes[] =
+ {
+ { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
+ ac_es_dencode_prepare_pkcs_v1_5,
+ sizeof (gcry_ac_eme_pkcs_v1_5_t) },
+ { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
+ ac_ssa_dencode_prepare_pkcs_v1_5,
+ sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
+ };
+
+/* Lookup a scheme by it's ID. */
+static ac_scheme_t *
+ac_scheme_get (gcry_ac_scheme_t scheme)
+{
+ ac_scheme_t *ac_scheme;
+ unsigned int i;
+
+ for (i = 0; i < DIM (ac_schemes); i++)
+ if (scheme == ac_schemes[i].scheme)
+ break;
+ if (i == DIM (ac_schemes))
+ ac_scheme = NULL;
+ else
+ ac_scheme = ac_schemes + i;
+
+ return ac_scheme;
+}
+
+/* Prepares the encoding/decoding by creating an according option
+ structure. */
+static gcry_error_t
+ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
+ ac_scheme_t scheme, void **opts_em)
+{
+ gcry_error_t err;
+ void *options_em;
+
+ options_em = gcry_malloc (scheme.options_em_n);
+ if (! options_em)
+ {
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
+ if (err)
+ goto out;
+
+ *opts_em = options_em;
+
+ out:
+
+ if (err)
+ free (options_em);
+
+ return err;
+}
+
+/* Convert a data set into a single MPI; currently, this is only
+ supported for data sets containing a single MPI. */
+static gcry_error_t
+ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
+{
+ gcry_error_t err;
+ gcry_mpi_t mpi_new;
+ unsigned int elems;
+
+ elems = _gcry_ac_data_length (data);
+
+ if (elems != 1)
+ {
+ /* FIXME: I guess, we should be more flexible in this respect by
+ allowing the actual encryption/signature schemes to implement
+ this conversion mechanism. */
+ err = gcry_error (GPG_ERR_CONFLICT);
+ goto out;
+ }
+
+ err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
+ if (err)
+ goto out;
+
+ *mpi = mpi_new;
+
+ out:
+
+ return err;
+}
+
+/* Encrypts the plain text message contained in M, which is of size
+ M_N, with the public key KEY_PUBLIC according to the Encryption
+ Scheme SCHEME_ID. HANDLE is used for accessing the low-level
+ cryptographic primitives. If OPTS is not NULL, it has to be an
+ anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
+ The encrypted message will be stored in C and C_N. */
+gcry_error_t
+_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme_id,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+{
+ gcry_error_t err;
+ gcry_ac_io_t io_em;
+ unsigned char *em;
+ size_t em_n;
+ gcry_mpi_t mpi_plain;
+ gcry_ac_data_t data_encrypted;
+ gcry_mpi_t mpi_encrypted;
+ unsigned char *buffer;
+ size_t buffer_n;
+ void *opts_em;
+ ac_scheme_t *scheme;
+
+ (void)flags;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_encrypted = NULL;
+ mpi_encrypted = NULL;
+ mpi_plain = NULL;
+ opts_em = NULL;
+ buffer = NULL;
+ em = NULL;
+
+ scheme = ac_scheme_get (scheme_id);
+ if (! scheme)
+ {
+ err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
+ goto out;
+ }
+
+ if (key->type != GCRY_AC_KEY_PUBLIC)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+ if (err)
+ goto out;
+
+ _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &em, &em_n);
+
+ err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+ io_message, &io_em);
+ if (err)
+ goto out;
+
+ mpi_plain = gcry_mpi_snew (0);
+ gcry_ac_os_to_mpi (mpi_plain, em, em_n);
+
+ err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
+ if (err)
+ goto out;
+
+ err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
+
+ out:
+
+ gcry_ac_data_destroy (data_encrypted);
+ gcry_mpi_release (mpi_encrypted);
+ gcry_mpi_release (mpi_plain);
+ gcry_free (opts_em);
+ gcry_free (buffer);
+ gcry_free (em);
+
+ return err;
+}
+
+/* Decryptes the cipher message contained in C, which is of size C_N,
+ with the secret key KEY_SECRET according to the Encryption Scheme
+ SCHEME_ID. Handle is used for accessing the low-level
+ cryptographic primitives. If OPTS is not NULL, it has to be an
+ anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
+ The decrypted message will be stored in M and M_N. */
+gcry_error_t
+_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme_id,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+{
+ gcry_ac_io_t io_em;
+ gcry_error_t err;
+ gcry_ac_data_t data_encrypted;
+ unsigned char *em;
+ size_t em_n;
+ gcry_mpi_t mpi_encrypted;
+ gcry_mpi_t mpi_decrypted;
+ void *opts_em;
+ ac_scheme_t *scheme;
+ char *elements_enc;
+ size_t elements_enc_n;
+ unsigned char *c;
+ size_t c_n;
+
+ (void)flags;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_encrypted = NULL;
+ mpi_encrypted = NULL;
+ mpi_decrypted = NULL;
+ elements_enc = NULL;
+ opts_em = NULL;
+ em = NULL;
+ c = NULL;
+
+ scheme = ac_scheme_get (scheme_id);
+ if (! scheme)
+ {
+ err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
+ goto out;
+ }
+
+ if (key->type != GCRY_AC_KEY_SECRET)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
+ if (err)
+ goto out;
+
+ mpi_encrypted = gcry_mpi_snew (0);
+ gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
+
+ err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
+ if (err)
+ goto out;
+
+ elements_enc_n = strlen (elements_enc);
+ if (elements_enc_n != 1)
+ {
+ /* FIXME? */
+ err = gcry_error (GPG_ERR_CONFLICT);
+ goto out;
+ }
+
+ err = _gcry_ac_data_new (&data_encrypted);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+ elements_enc, mpi_encrypted);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
+ if (err)
+ goto out;
+
+ err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+ if (err)
+ goto out;
+
+ _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, em, em_n);
+
+ err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
+ &io_em, io_message);
+ if (err)
+ goto out;
+
+ out:
+
+ _gcry_ac_data_destroy (data_encrypted);
+ gcry_mpi_release (mpi_encrypted);
+ gcry_mpi_release (mpi_decrypted);
+ free (elements_enc);
+ gcry_free (opts_em);
+ gcry_free (em);
+ gcry_free (c);
+
+ return err;
+}
+
+
+/* Signs the message contained in M, which is of size M_N, with the
+ secret key KEY according to the Signature Scheme SCHEME_ID. Handle
+ is used for accessing the low-level cryptographic primitives. If
+ OPTS is not NULL, it has to be an anonymous structure specific to
+ the chosen scheme (gcry_ac_ssa_*_t). The signed message will be
+ stored in S and S_N. */
+gcry_error_t
+_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme_id,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ gcry_ac_io_t io_em;
+ gcry_error_t err;
+ gcry_ac_data_t data_signed;
+ unsigned char *em;
+ size_t em_n;
+ gcry_mpi_t mpi;
+ void *opts_em;
+ unsigned char *buffer;
+ size_t buffer_n;
+ gcry_mpi_t mpi_signed;
+ ac_scheme_t *scheme;
+
+ (void)flags;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ data_signed = NULL;
+ mpi_signed = NULL;
+ opts_em = NULL;
+ buffer = NULL;
+ mpi = NULL;
+ em = NULL;
+
+ if (key->type != GCRY_AC_KEY_SECRET)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ scheme = ac_scheme_get (scheme_id);
+ if (! scheme)
+ {
+ /* FIXME: adjust api of scheme_get in respect to err codes. */
+ err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
+ goto out;
+ }
+
+ err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+ if (err)
+ goto out;
+
+ _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &em, &em_n);
+
+ err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+ io_message, &io_em);
+ if (err)
+ goto out;
+
+ mpi = gcry_mpi_new (0);
+ _gcry_ac_os_to_mpi (mpi, em, em_n);
+
+ err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
+ if (err)
+ goto out;
+
+ err = ac_data_set_to_mpi (data_signed, &mpi_signed);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
+
+ out:
+
+ _gcry_ac_data_destroy (data_signed);
+ gcry_mpi_release (mpi_signed);
+ gcry_mpi_release (mpi);
+ gcry_free (opts_em);
+ gcry_free (buffer);
+ gcry_free (em);
+
+ return err;
+}
+
+/* Verifies that the signature contained in S, which is of length S_N,
+ is indeed the result of signing the message contained in M, which
+ is of size M_N, with the secret key belonging to the public key
+ KEY_PUBLIC. If OPTS is not NULL, it has to be an anonymous
+ structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
+ ID is contained in SCHEME_ID. */
+gcry_error_t
+_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme_id,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ gcry_ac_io_t io_em;
+ gcry_error_t err;
+ gcry_ac_data_t data_signed;
+ unsigned char *em;
+ size_t em_n;
+ void *opts_em;
+ gcry_mpi_t mpi_signature;
+ gcry_mpi_t mpi_data;
+ ac_scheme_t *scheme;
+ char *elements_sig;
+ size_t elements_sig_n;
+ unsigned char *s;
+ size_t s_n;
+
+ (void)flags;
+
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ mpi_signature = NULL;
+ elements_sig = NULL;
+ data_signed = NULL;
+ mpi_data = NULL;
+ opts_em = NULL;
+ em = NULL;
+ s = NULL;
+
+ if (key->type != GCRY_AC_KEY_PUBLIC)
+ {
+ err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
+ goto out;
+ }
+
+ scheme = ac_scheme_get (scheme_id);
+ if (! scheme)
+ {
+ err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
+ goto out;
+ }
+
+ err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
+ if (err)
+ goto out;
+
+ _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &em, &em_n);
+
+ err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
+ io_message, &io_em);
+ if (err)
+ goto out;
+
+ mpi_data = gcry_mpi_new (0);
+ _gcry_ac_os_to_mpi (mpi_data, em, em_n);
+
+ err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
+ if (err)
+ goto out;
+
+ mpi_signature = gcry_mpi_new (0);
+ _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
+
+ err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
+ if (err)
+ goto out;
+
+ elements_sig_n = strlen (elements_sig);
+ if (elements_sig_n != 1)
+ {
+ /* FIXME? */
+ err = gcry_error (GPG_ERR_CONFLICT);
+ goto out;
+ }
+
+ err = _gcry_ac_data_new (&data_signed);
+ if (err)
+ goto out;
+
+ err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+ elements_sig, mpi_signature);
+ if (err)
+ goto out;
+
+ gcry_mpi_release (mpi_signature);
+ mpi_signature = NULL;
+
+ err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
+
+ out:
+
+ _gcry_ac_data_destroy (data_signed);
+ gcry_mpi_release (mpi_signature);
+ gcry_mpi_release (mpi_data);
+ free (elements_sig);
+ gcry_free (opts_em);
+ gcry_free (em);
+ gcry_free (s);
+
+ return err;
+}
+
+
+/*
+ * General functions.
+ */
+
+gcry_err_code_t
+_gcry_ac_init (void)
+{
+ if (fips_mode ())
+ return GPG_ERR_NOT_SUPPORTED;
+
+ return 0;
+}
--- /dev/null
+/* arcfour.c - The arcfour stream cipher
+ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of the algorithm, see:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9. Pages 397 ff.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+static const char *selftest(void);
+
+typedef struct {
+ int idx_i, idx_j;
+ byte sbox[256];
+} ARCFOUR_context;
+
+static void
+do_encrypt_stream( ARCFOUR_context *ctx,
+ byte *outbuf, const byte *inbuf, unsigned int length )
+{
+ register int i = ctx->idx_i;
+ register int j = ctx->idx_j;
+ register byte *sbox = ctx->sbox;
+ register int t;
+
+ while ( length-- )
+ {
+ i++;
+ i = i & 255; /* The and-op seems to be faster than the mod-op. */
+ j += sbox[i];
+ j &= 255;
+ t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
+ *outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
+ }
+
+ ctx->idx_i = i;
+ ctx->idx_j = j;
+}
+
+static void
+encrypt_stream (void *context,
+ byte *outbuf, const byte *inbuf, unsigned int length)
+{
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+ do_encrypt_stream (ctx, outbuf, inbuf, length );
+ _gcry_burn_stack (64);
+}
+
+
+static gcry_err_code_t
+do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
+{
+ static int initialized;
+ static const char* selftest_failed;
+ int i, j;
+ byte karr[256];
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+
+ if (!initialized )
+ {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error ("ARCFOUR selftest failed (%s)\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if( keylen < 40/8 ) /* we want at least 40 bits */
+ return GPG_ERR_INV_KEYLEN;
+
+ ctx->idx_i = ctx->idx_j = 0;
+ for (i=0; i < 256; i++ )
+ ctx->sbox[i] = i;
+ for (i=0; i < 256; i++ )
+ karr[i] = key[i%keylen];
+ for (i=j=0; i < 256; i++ )
+ {
+ int t;
+ j = (j + ctx->sbox[i] + karr[i]) % 256;
+ t = ctx->sbox[i];
+ ctx->sbox[i] = ctx->sbox[j];
+ ctx->sbox[j] = t;
+ }
+ memset( karr, 0, 256 );
+
+ return GPG_ERR_NO_ERROR;
+}
+
+static gcry_err_code_t
+arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
+{
+ ARCFOUR_context *ctx = (ARCFOUR_context *) context;
+ gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
+ _gcry_burn_stack (300);
+ return rc;
+}
+
+
+static const char*
+selftest(void)
+{
+ ARCFOUR_context ctx;
+ byte scratch[16];
+
+ /* Test vector from Cryptlib labeled there: "from the
+ State/Commerce Department". */
+ static byte key_1[] =
+ { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
+ static byte plaintext_1[] =
+ { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
+ static const byte ciphertext_1[] =
+ { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
+
+ arcfour_setkey( &ctx, key_1, sizeof(key_1));
+ encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1));
+ if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1)))
+ return "Arcfour encryption test 1 failed.";
+ arcfour_setkey( &ctx, key_1, sizeof(key_1));
+ encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */
+ if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1)))
+ return "Arcfour decryption test 1 failed.";
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
+ {
+ "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
+ arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
+ };
--- /dev/null
+/* bithelp.h - Some bit manipulation helpers
+ * Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_BITHELP_H
+#define G10_BITHELP_H
+
+
+/****************
+ * Rotate the 32 bit unsigned integer X by N bits left/right
+ */
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+rol( u32 x, int n)
+{
+ __asm__("roll %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+ror(u32 x, int n)
+{
+ __asm__("rorl %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+#endif
+
+
+#endif /*G10_BITHELP_H*/
--- /dev/null
+/* blowfish.c - Blowfish encryption
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of the algorithm, see:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9. Pages 336 ff.
+ */
+
+/* Test values:
+ * key "abcdefghijklmnopqrstuvwxyz";
+ * plain "BLOWFISH"
+ * cipher 32 4E D0 FE F4 13 A2 03
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+#define BLOWFISH_BLOCKSIZE 8
+#define BLOWFISH_ROUNDS 16
+
+typedef struct {
+ u32 s0[256];
+ u32 s1[256];
+ u32 s2[256];
+ u32 s3[256];
+ u32 p[BLOWFISH_ROUNDS+2];
+} BLOWFISH_context;
+
+static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+
+
+/* precomputed S boxes */
+static const u32 ks0[256] = {
+ 0xD1310BA6,0x98DFB5AC,0x2FFD72DB,0xD01ADFB7,0xB8E1AFED,0x6A267E96,
+ 0xBA7C9045,0xF12C7F99,0x24A19947,0xB3916CF7,0x0801F2E2,0x858EFC16,
+ 0x636920D8,0x71574E69,0xA458FEA3,0xF4933D7E,0x0D95748F,0x728EB658,
+ 0x718BCD58,0x82154AEE,0x7B54A41D,0xC25A59B5,0x9C30D539,0x2AF26013,
+ 0xC5D1B023,0x286085F0,0xCA417918,0xB8DB38EF,0x8E79DCB0,0x603A180E,
+ 0x6C9E0E8B,0xB01E8A3E,0xD71577C1,0xBD314B27,0x78AF2FDA,0x55605C60,
+ 0xE65525F3,0xAA55AB94,0x57489862,0x63E81440,0x55CA396A,0x2AAB10B6,
+ 0xB4CC5C34,0x1141E8CE,0xA15486AF,0x7C72E993,0xB3EE1411,0x636FBC2A,
+ 0x2BA9C55D,0x741831F6,0xCE5C3E16,0x9B87931E,0xAFD6BA33,0x6C24CF5C,
+ 0x7A325381,0x28958677,0x3B8F4898,0x6B4BB9AF,0xC4BFE81B,0x66282193,
+ 0x61D809CC,0xFB21A991,0x487CAC60,0x5DEC8032,0xEF845D5D,0xE98575B1,
+ 0xDC262302,0xEB651B88,0x23893E81,0xD396ACC5,0x0F6D6FF3,0x83F44239,
+ 0x2E0B4482,0xA4842004,0x69C8F04A,0x9E1F9B5E,0x21C66842,0xF6E96C9A,
+ 0x670C9C61,0xABD388F0,0x6A51A0D2,0xD8542F68,0x960FA728,0xAB5133A3,
+ 0x6EEF0B6C,0x137A3BE4,0xBA3BF050,0x7EFB2A98,0xA1F1651D,0x39AF0176,
+ 0x66CA593E,0x82430E88,0x8CEE8619,0x456F9FB4,0x7D84A5C3,0x3B8B5EBE,
+ 0xE06F75D8,0x85C12073,0x401A449F,0x56C16AA6,0x4ED3AA62,0x363F7706,
+ 0x1BFEDF72,0x429B023D,0x37D0D724,0xD00A1248,0xDB0FEAD3,0x49F1C09B,
+ 0x075372C9,0x80991B7B,0x25D479D8,0xF6E8DEF7,0xE3FE501A,0xB6794C3B,
+ 0x976CE0BD,0x04C006BA,0xC1A94FB6,0x409F60C4,0x5E5C9EC2,0x196A2463,
+ 0x68FB6FAF,0x3E6C53B5,0x1339B2EB,0x3B52EC6F,0x6DFC511F,0x9B30952C,
+ 0xCC814544,0xAF5EBD09,0xBEE3D004,0xDE334AFD,0x660F2807,0x192E4BB3,
+ 0xC0CBA857,0x45C8740F,0xD20B5F39,0xB9D3FBDB,0x5579C0BD,0x1A60320A,
+ 0xD6A100C6,0x402C7279,0x679F25FE,0xFB1FA3CC,0x8EA5E9F8,0xDB3222F8,
+ 0x3C7516DF,0xFD616B15,0x2F501EC8,0xAD0552AB,0x323DB5FA,0xFD238760,
+ 0x53317B48,0x3E00DF82,0x9E5C57BB,0xCA6F8CA0,0x1A87562E,0xDF1769DB,
+ 0xD542A8F6,0x287EFFC3,0xAC6732C6,0x8C4F5573,0x695B27B0,0xBBCA58C8,
+ 0xE1FFA35D,0xB8F011A0,0x10FA3D98,0xFD2183B8,0x4AFCB56C,0x2DD1D35B,
+ 0x9A53E479,0xB6F84565,0xD28E49BC,0x4BFB9790,0xE1DDF2DA,0xA4CB7E33,
+ 0x62FB1341,0xCEE4C6E8,0xEF20CADA,0x36774C01,0xD07E9EFE,0x2BF11FB4,
+ 0x95DBDA4D,0xAE909198,0xEAAD8E71,0x6B93D5A0,0xD08ED1D0,0xAFC725E0,
+ 0x8E3C5B2F,0x8E7594B7,0x8FF6E2FB,0xF2122B64,0x8888B812,0x900DF01C,
+ 0x4FAD5EA0,0x688FC31C,0xD1CFF191,0xB3A8C1AD,0x2F2F2218,0xBE0E1777,
+ 0xEA752DFE,0x8B021FA1,0xE5A0CC0F,0xB56F74E8,0x18ACF3D6,0xCE89E299,
+ 0xB4A84FE0,0xFD13E0B7,0x7CC43B81,0xD2ADA8D9,0x165FA266,0x80957705,
+ 0x93CC7314,0x211A1477,0xE6AD2065,0x77B5FA86,0xC75442F5,0xFB9D35CF,
+ 0xEBCDAF0C,0x7B3E89A0,0xD6411BD3,0xAE1E7E49,0x00250E2D,0x2071B35E,
+ 0x226800BB,0x57B8E0AF,0x2464369B,0xF009B91E,0x5563911D,0x59DFA6AA,
+ 0x78C14389,0xD95A537F,0x207D5BA2,0x02E5B9C5,0x83260376,0x6295CFA9,
+ 0x11C81968,0x4E734A41,0xB3472DCA,0x7B14A94A,0x1B510052,0x9A532915,
+ 0xD60F573F,0xBC9BC6E4,0x2B60A476,0x81E67400,0x08BA6FB5,0x571BE91F,
+ 0xF296EC6B,0x2A0DD915,0xB6636521,0xE7B9F9B6,0xFF34052E,0xC5855664,
+ 0x53B02D5D,0xA99F8FA1,0x08BA4799,0x6E85076A };
+
+static const u32 ks1[256] = {
+ 0x4B7A70E9,0xB5B32944,0xDB75092E,0xC4192623,0xAD6EA6B0,0x49A7DF7D,
+ 0x9CEE60B8,0x8FEDB266,0xECAA8C71,0x699A17FF,0x5664526C,0xC2B19EE1,
+ 0x193602A5,0x75094C29,0xA0591340,0xE4183A3E,0x3F54989A,0x5B429D65,
+ 0x6B8FE4D6,0x99F73FD6,0xA1D29C07,0xEFE830F5,0x4D2D38E6,0xF0255DC1,
+ 0x4CDD2086,0x8470EB26,0x6382E9C6,0x021ECC5E,0x09686B3F,0x3EBAEFC9,
+ 0x3C971814,0x6B6A70A1,0x687F3584,0x52A0E286,0xB79C5305,0xAA500737,
+ 0x3E07841C,0x7FDEAE5C,0x8E7D44EC,0x5716F2B8,0xB03ADA37,0xF0500C0D,
+ 0xF01C1F04,0x0200B3FF,0xAE0CF51A,0x3CB574B2,0x25837A58,0xDC0921BD,
+ 0xD19113F9,0x7CA92FF6,0x94324773,0x22F54701,0x3AE5E581,0x37C2DADC,
+ 0xC8B57634,0x9AF3DDA7,0xA9446146,0x0FD0030E,0xECC8C73E,0xA4751E41,
+ 0xE238CD99,0x3BEA0E2F,0x3280BBA1,0x183EB331,0x4E548B38,0x4F6DB908,
+ 0x6F420D03,0xF60A04BF,0x2CB81290,0x24977C79,0x5679B072,0xBCAF89AF,
+ 0xDE9A771F,0xD9930810,0xB38BAE12,0xDCCF3F2E,0x5512721F,0x2E6B7124,
+ 0x501ADDE6,0x9F84CD87,0x7A584718,0x7408DA17,0xBC9F9ABC,0xE94B7D8C,
+ 0xEC7AEC3A,0xDB851DFA,0x63094366,0xC464C3D2,0xEF1C1847,0x3215D908,
+ 0xDD433B37,0x24C2BA16,0x12A14D43,0x2A65C451,0x50940002,0x133AE4DD,
+ 0x71DFF89E,0x10314E55,0x81AC77D6,0x5F11199B,0x043556F1,0xD7A3C76B,
+ 0x3C11183B,0x5924A509,0xF28FE6ED,0x97F1FBFA,0x9EBABF2C,0x1E153C6E,
+ 0x86E34570,0xEAE96FB1,0x860E5E0A,0x5A3E2AB3,0x771FE71C,0x4E3D06FA,
+ 0x2965DCB9,0x99E71D0F,0x803E89D6,0x5266C825,0x2E4CC978,0x9C10B36A,
+ 0xC6150EBA,0x94E2EA78,0xA5FC3C53,0x1E0A2DF4,0xF2F74EA7,0x361D2B3D,
+ 0x1939260F,0x19C27960,0x5223A708,0xF71312B6,0xEBADFE6E,0xEAC31F66,
+ 0xE3BC4595,0xA67BC883,0xB17F37D1,0x018CFF28,0xC332DDEF,0xBE6C5AA5,
+ 0x65582185,0x68AB9802,0xEECEA50F,0xDB2F953B,0x2AEF7DAD,0x5B6E2F84,
+ 0x1521B628,0x29076170,0xECDD4775,0x619F1510,0x13CCA830,0xEB61BD96,
+ 0x0334FE1E,0xAA0363CF,0xB5735C90,0x4C70A239,0xD59E9E0B,0xCBAADE14,
+ 0xEECC86BC,0x60622CA7,0x9CAB5CAB,0xB2F3846E,0x648B1EAF,0x19BDF0CA,
+ 0xA02369B9,0x655ABB50,0x40685A32,0x3C2AB4B3,0x319EE9D5,0xC021B8F7,
+ 0x9B540B19,0x875FA099,0x95F7997E,0x623D7DA8,0xF837889A,0x97E32D77,
+ 0x11ED935F,0x16681281,0x0E358829,0xC7E61FD6,0x96DEDFA1,0x7858BA99,
+ 0x57F584A5,0x1B227263,0x9B83C3FF,0x1AC24696,0xCDB30AEB,0x532E3054,
+ 0x8FD948E4,0x6DBC3128,0x58EBF2EF,0x34C6FFEA,0xFE28ED61,0xEE7C3C73,
+ 0x5D4A14D9,0xE864B7E3,0x42105D14,0x203E13E0,0x45EEE2B6,0xA3AAABEA,
+ 0xDB6C4F15,0xFACB4FD0,0xC742F442,0xEF6ABBB5,0x654F3B1D,0x41CD2105,
+ 0xD81E799E,0x86854DC7,0xE44B476A,0x3D816250,0xCF62A1F2,0x5B8D2646,
+ 0xFC8883A0,0xC1C7B6A3,0x7F1524C3,0x69CB7492,0x47848A0B,0x5692B285,
+ 0x095BBF00,0xAD19489D,0x1462B174,0x23820E00,0x58428D2A,0x0C55F5EA,
+ 0x1DADF43E,0x233F7061,0x3372F092,0x8D937E41,0xD65FECF1,0x6C223BDB,
+ 0x7CDE3759,0xCBEE7460,0x4085F2A7,0xCE77326E,0xA6078084,0x19F8509E,
+ 0xE8EFD855,0x61D99735,0xA969A7AA,0xC50C06C2,0x5A04ABFC,0x800BCADC,
+ 0x9E447A2E,0xC3453484,0xFDD56705,0x0E1E9EC9,0xDB73DBD3,0x105588CD,
+ 0x675FDA79,0xE3674340,0xC5C43465,0x713E38D8,0x3D28F89E,0xF16DFF20,
+ 0x153E21E7,0x8FB03D4A,0xE6E39F2B,0xDB83ADF7 };
+
+static const u32 ks2[256] = {
+ 0xE93D5A68,0x948140F7,0xF64C261C,0x94692934,0x411520F7,0x7602D4F7,
+ 0xBCF46B2E,0xD4A20068,0xD4082471,0x3320F46A,0x43B7D4B7,0x500061AF,
+ 0x1E39F62E,0x97244546,0x14214F74,0xBF8B8840,0x4D95FC1D,0x96B591AF,
+ 0x70F4DDD3,0x66A02F45,0xBFBC09EC,0x03BD9785,0x7FAC6DD0,0x31CB8504,
+ 0x96EB27B3,0x55FD3941,0xDA2547E6,0xABCA0A9A,0x28507825,0x530429F4,
+ 0x0A2C86DA,0xE9B66DFB,0x68DC1462,0xD7486900,0x680EC0A4,0x27A18DEE,
+ 0x4F3FFEA2,0xE887AD8C,0xB58CE006,0x7AF4D6B6,0xAACE1E7C,0xD3375FEC,
+ 0xCE78A399,0x406B2A42,0x20FE9E35,0xD9F385B9,0xEE39D7AB,0x3B124E8B,
+ 0x1DC9FAF7,0x4B6D1856,0x26A36631,0xEAE397B2,0x3A6EFA74,0xDD5B4332,
+ 0x6841E7F7,0xCA7820FB,0xFB0AF54E,0xD8FEB397,0x454056AC,0xBA489527,
+ 0x55533A3A,0x20838D87,0xFE6BA9B7,0xD096954B,0x55A867BC,0xA1159A58,
+ 0xCCA92963,0x99E1DB33,0xA62A4A56,0x3F3125F9,0x5EF47E1C,0x9029317C,
+ 0xFDF8E802,0x04272F70,0x80BB155C,0x05282CE3,0x95C11548,0xE4C66D22,
+ 0x48C1133F,0xC70F86DC,0x07F9C9EE,0x41041F0F,0x404779A4,0x5D886E17,
+ 0x325F51EB,0xD59BC0D1,0xF2BCC18F,0x41113564,0x257B7834,0x602A9C60,
+ 0xDFF8E8A3,0x1F636C1B,0x0E12B4C2,0x02E1329E,0xAF664FD1,0xCAD18115,
+ 0x6B2395E0,0x333E92E1,0x3B240B62,0xEEBEB922,0x85B2A20E,0xE6BA0D99,
+ 0xDE720C8C,0x2DA2F728,0xD0127845,0x95B794FD,0x647D0862,0xE7CCF5F0,
+ 0x5449A36F,0x877D48FA,0xC39DFD27,0xF33E8D1E,0x0A476341,0x992EFF74,
+ 0x3A6F6EAB,0xF4F8FD37,0xA812DC60,0xA1EBDDF8,0x991BE14C,0xDB6E6B0D,
+ 0xC67B5510,0x6D672C37,0x2765D43B,0xDCD0E804,0xF1290DC7,0xCC00FFA3,
+ 0xB5390F92,0x690FED0B,0x667B9FFB,0xCEDB7D9C,0xA091CF0B,0xD9155EA3,
+ 0xBB132F88,0x515BAD24,0x7B9479BF,0x763BD6EB,0x37392EB3,0xCC115979,
+ 0x8026E297,0xF42E312D,0x6842ADA7,0xC66A2B3B,0x12754CCC,0x782EF11C,
+ 0x6A124237,0xB79251E7,0x06A1BBE6,0x4BFB6350,0x1A6B1018,0x11CAEDFA,
+ 0x3D25BDD8,0xE2E1C3C9,0x44421659,0x0A121386,0xD90CEC6E,0xD5ABEA2A,
+ 0x64AF674E,0xDA86A85F,0xBEBFE988,0x64E4C3FE,0x9DBC8057,0xF0F7C086,
+ 0x60787BF8,0x6003604D,0xD1FD8346,0xF6381FB0,0x7745AE04,0xD736FCCC,
+ 0x83426B33,0xF01EAB71,0xB0804187,0x3C005E5F,0x77A057BE,0xBDE8AE24,
+ 0x55464299,0xBF582E61,0x4E58F48F,0xF2DDFDA2,0xF474EF38,0x8789BDC2,
+ 0x5366F9C3,0xC8B38E74,0xB475F255,0x46FCD9B9,0x7AEB2661,0x8B1DDF84,
+ 0x846A0E79,0x915F95E2,0x466E598E,0x20B45770,0x8CD55591,0xC902DE4C,
+ 0xB90BACE1,0xBB8205D0,0x11A86248,0x7574A99E,0xB77F19B6,0xE0A9DC09,
+ 0x662D09A1,0xC4324633,0xE85A1F02,0x09F0BE8C,0x4A99A025,0x1D6EFE10,
+ 0x1AB93D1D,0x0BA5A4DF,0xA186F20F,0x2868F169,0xDCB7DA83,0x573906FE,
+ 0xA1E2CE9B,0x4FCD7F52,0x50115E01,0xA70683FA,0xA002B5C4,0x0DE6D027,
+ 0x9AF88C27,0x773F8641,0xC3604C06,0x61A806B5,0xF0177A28,0xC0F586E0,
+ 0x006058AA,0x30DC7D62,0x11E69ED7,0x2338EA63,0x53C2DD94,0xC2C21634,
+ 0xBBCBEE56,0x90BCB6DE,0xEBFC7DA1,0xCE591D76,0x6F05E409,0x4B7C0188,
+ 0x39720A3D,0x7C927C24,0x86E3725F,0x724D9DB9,0x1AC15BB4,0xD39EB8FC,
+ 0xED545578,0x08FCA5B5,0xD83D7CD3,0x4DAD0FC4,0x1E50EF5E,0xB161E6F8,
+ 0xA28514D9,0x6C51133C,0x6FD5C7E7,0x56E14EC4,0x362ABFCE,0xDDC6C837,
+ 0xD79A3234,0x92638212,0x670EFA8E,0x406000E0 };
+
+static const u32 ks3[256] = {
+ 0x3A39CE37,0xD3FAF5CF,0xABC27737,0x5AC52D1B,0x5CB0679E,0x4FA33742,
+ 0xD3822740,0x99BC9BBE,0xD5118E9D,0xBF0F7315,0xD62D1C7E,0xC700C47B,
+ 0xB78C1B6B,0x21A19045,0xB26EB1BE,0x6A366EB4,0x5748AB2F,0xBC946E79,
+ 0xC6A376D2,0x6549C2C8,0x530FF8EE,0x468DDE7D,0xD5730A1D,0x4CD04DC6,
+ 0x2939BBDB,0xA9BA4650,0xAC9526E8,0xBE5EE304,0xA1FAD5F0,0x6A2D519A,
+ 0x63EF8CE2,0x9A86EE22,0xC089C2B8,0x43242EF6,0xA51E03AA,0x9CF2D0A4,
+ 0x83C061BA,0x9BE96A4D,0x8FE51550,0xBA645BD6,0x2826A2F9,0xA73A3AE1,
+ 0x4BA99586,0xEF5562E9,0xC72FEFD3,0xF752F7DA,0x3F046F69,0x77FA0A59,
+ 0x80E4A915,0x87B08601,0x9B09E6AD,0x3B3EE593,0xE990FD5A,0x9E34D797,
+ 0x2CF0B7D9,0x022B8B51,0x96D5AC3A,0x017DA67D,0xD1CF3ED6,0x7C7D2D28,
+ 0x1F9F25CF,0xADF2B89B,0x5AD6B472,0x5A88F54C,0xE029AC71,0xE019A5E6,
+ 0x47B0ACFD,0xED93FA9B,0xE8D3C48D,0x283B57CC,0xF8D56629,0x79132E28,
+ 0x785F0191,0xED756055,0xF7960E44,0xE3D35E8C,0x15056DD4,0x88F46DBA,
+ 0x03A16125,0x0564F0BD,0xC3EB9E15,0x3C9057A2,0x97271AEC,0xA93A072A,
+ 0x1B3F6D9B,0x1E6321F5,0xF59C66FB,0x26DCF319,0x7533D928,0xB155FDF5,
+ 0x03563482,0x8ABA3CBB,0x28517711,0xC20AD9F8,0xABCC5167,0xCCAD925F,
+ 0x4DE81751,0x3830DC8E,0x379D5862,0x9320F991,0xEA7A90C2,0xFB3E7BCE,
+ 0x5121CE64,0x774FBE32,0xA8B6E37E,0xC3293D46,0x48DE5369,0x6413E680,
+ 0xA2AE0810,0xDD6DB224,0x69852DFD,0x09072166,0xB39A460A,0x6445C0DD,
+ 0x586CDECF,0x1C20C8AE,0x5BBEF7DD,0x1B588D40,0xCCD2017F,0x6BB4E3BB,
+ 0xDDA26A7E,0x3A59FF45,0x3E350A44,0xBCB4CDD5,0x72EACEA8,0xFA6484BB,
+ 0x8D6612AE,0xBF3C6F47,0xD29BE463,0x542F5D9E,0xAEC2771B,0xF64E6370,
+ 0x740E0D8D,0xE75B1357,0xF8721671,0xAF537D5D,0x4040CB08,0x4EB4E2CC,
+ 0x34D2466A,0x0115AF84,0xE1B00428,0x95983A1D,0x06B89FB4,0xCE6EA048,
+ 0x6F3F3B82,0x3520AB82,0x011A1D4B,0x277227F8,0x611560B1,0xE7933FDC,
+ 0xBB3A792B,0x344525BD,0xA08839E1,0x51CE794B,0x2F32C9B7,0xA01FBAC9,
+ 0xE01CC87E,0xBCC7D1F6,0xCF0111C3,0xA1E8AAC7,0x1A908749,0xD44FBD9A,
+ 0xD0DADECB,0xD50ADA38,0x0339C32A,0xC6913667,0x8DF9317C,0xE0B12B4F,
+ 0xF79E59B7,0x43F5BB3A,0xF2D519FF,0x27D9459C,0xBF97222C,0x15E6FC2A,
+ 0x0F91FC71,0x9B941525,0xFAE59361,0xCEB69CEB,0xC2A86459,0x12BAA8D1,
+ 0xB6C1075E,0xE3056A0C,0x10D25065,0xCB03A442,0xE0EC6E0E,0x1698DB3B,
+ 0x4C98A0BE,0x3278E964,0x9F1F9532,0xE0D392DF,0xD3A0342B,0x8971F21E,
+ 0x1B0A7441,0x4BA3348C,0xC5BE7120,0xC37632D8,0xDF359F8D,0x9B992F2E,
+ 0xE60B6F47,0x0FE3F11D,0xE54CDA54,0x1EDAD891,0xCE6279CF,0xCD3E7E6F,
+ 0x1618B166,0xFD2C1D05,0x848FD2C5,0xF6FB2299,0xF523F357,0xA6327623,
+ 0x93A83531,0x56CCCD02,0xACF08162,0x5A75EBB5,0x6E163697,0x88D273CC,
+ 0xDE966292,0x81B949D0,0x4C50901B,0x71C65614,0xE6C6C7BD,0x327A140A,
+ 0x45E1D006,0xC3F27B9A,0xC9AA53FD,0x62A80F00,0xBB25BFE2,0x35BDD2F6,
+ 0x71126905,0xB2040222,0xB6CBCF7C,0xCD769C2B,0x53113EC0,0x1640E3D3,
+ 0x38ABBD60,0x2547ADF0,0xBA38209C,0xF746CE76,0x77AFA1C5,0x20756060,
+ 0x85CBFE4E,0x8AE88DD8,0x7AAAF9B0,0x4CF9AA7E,0x1948C25C,0x02FB8A8C,
+ 0x01C36AE4,0xD6EBE1F9,0x90D4F869,0xA65CDEA0,0x3F09252D,0xC208E69F,
+ 0xB74E6132,0xCE77E25B,0x578FDFE3,0x3AC372E6 };
+
+static const u32 ps[BLOWFISH_ROUNDS+2] = {
+ 0x243F6A88,0x85A308D3,0x13198A2E,0x03707344,0xA4093822,0x299F31D0,
+ 0x082EFA98,0xEC4E6C89,0x452821E6,0x38D01377,0xBE5466CF,0x34E90C6C,
+ 0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
+
+
+
+#if BLOWFISH_ROUNDS != 16
+static inline u32
+function_F( BLOWFISH_context *bc, u32 x )
+{
+ u16 a, b, c, d;
+
+#ifdef WORDS_BIGENDIAN
+ a = ((byte*)&x)[0];
+ b = ((byte*)&x)[1];
+ c = ((byte*)&x)[2];
+ d = ((byte*)&x)[3];
+#else
+ a = ((byte*)&x)[3];
+ b = ((byte*)&x)[2];
+ c = ((byte*)&x)[1];
+ d = ((byte*)&x)[0];
+#endif
+
+ return ((bc->s0[a] + bc->s1[b]) ^ bc->s2[c] ) + bc->s3[d];
+}
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define F(x) ((( s0[((byte*)&x)[0]] + s1[((byte*)&x)[1]]) \
+ ^ s2[((byte*)&x)[2]]) + s3[((byte*)&x)[3]] )
+#else
+#define F(x) ((( s0[((byte*)&x)[3]] + s1[((byte*)&x)[2]]) \
+ ^ s2[((byte*)&x)[1]]) + s3[((byte*)&x)[0]] )
+#endif
+#define R(l,r,i) do { l ^= p[i]; r ^= F(l); } while(0)
+
+
+static void
+do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+#if BLOWFISH_ROUNDS == 16
+ u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+ s0 = bc->s0;
+ s1 = bc->s1;
+ s2 = bc->s2;
+ s3 = bc->s3;
+
+ R( xl, xr, 0);
+ R( xr, xl, 1);
+ R( xl, xr, 2);
+ R( xr, xl, 3);
+ R( xl, xr, 4);
+ R( xr, xl, 5);
+ R( xl, xr, 6);
+ R( xr, xl, 7);
+ R( xl, xr, 8);
+ R( xr, xl, 9);
+ R( xl, xr, 10);
+ R( xr, xl, 11);
+ R( xl, xr, 12);
+ R( xr, xl, 13);
+ R( xl, xr, 14);
+ R( xr, xl, 15);
+
+ xl ^= p[BLOWFISH_ROUNDS];
+ xr ^= p[BLOWFISH_ROUNDS+1];
+
+ *ret_xl = xr;
+ *ret_xr = xl;
+
+#else
+ u32 xl, xr, temp, *p;
+ int i;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+
+ for(i=0; i < BLOWFISH_ROUNDS; i++ )
+ {
+ xl ^= p[i];
+ xr ^= function_F(bc, xl);
+ temp = xl;
+ xl = xr;
+ xr = temp;
+ }
+ temp = xl;
+ xl = xr;
+ xr = temp;
+
+ xr ^= p[BLOWFISH_ROUNDS];
+ xl ^= p[BLOWFISH_ROUNDS+1];
+
+ *ret_xl = xl;
+ *ret_xr = xr;
+#endif
+}
+
+
+static void
+decrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+#if BLOWFISH_ROUNDS == 16
+ u32 xl, xr, *s0, *s1, *s2, *s3, *p;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+ s0 = bc->s0;
+ s1 = bc->s1;
+ s2 = bc->s2;
+ s3 = bc->s3;
+
+ R( xl, xr, 17);
+ R( xr, xl, 16);
+ R( xl, xr, 15);
+ R( xr, xl, 14);
+ R( xl, xr, 13);
+ R( xr, xl, 12);
+ R( xl, xr, 11);
+ R( xr, xl, 10);
+ R( xl, xr, 9);
+ R( xr, xl, 8);
+ R( xl, xr, 7);
+ R( xr, xl, 6);
+ R( xl, xr, 5);
+ R( xr, xl, 4);
+ R( xl, xr, 3);
+ R( xr, xl, 2);
+
+ xl ^= p[1];
+ xr ^= p[0];
+
+ *ret_xl = xr;
+ *ret_xr = xl;
+
+#else
+ u32 xl, xr, temp, *p;
+ int i;
+
+ xl = *ret_xl;
+ xr = *ret_xr;
+ p = bc->p;
+
+ for (i=BLOWFISH_ROUNDS+1; i > 1; i-- )
+ {
+ xl ^= p[i];
+ xr ^= function_F(bc, xl);
+ temp = xl;
+ xl = xr;
+ xr = temp;
+ }
+
+ temp = xl;
+ xl = xr;
+ xr = temp;
+
+ xr ^= p[1];
+ xl ^= p[0];
+
+ *ret_xl = xl;
+ *ret_xr = xr;
+#endif
+}
+
+#undef F
+#undef R
+
+static void
+do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
+{
+ u32 d1, d2;
+
+ d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+ d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+ do_encrypt( bc, &d1, &d2 );
+ outbuf[0] = (d1 >> 24) & 0xff;
+ outbuf[1] = (d1 >> 16) & 0xff;
+ outbuf[2] = (d1 >> 8) & 0xff;
+ outbuf[3] = d1 & 0xff;
+ outbuf[4] = (d2 >> 24) & 0xff;
+ outbuf[5] = (d2 >> 16) & 0xff;
+ outbuf[6] = (d2 >> 8) & 0xff;
+ outbuf[7] = d2 & 0xff;
+}
+
+static void
+encrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+ BLOWFISH_context *bc = (BLOWFISH_context *) context;
+ do_encrypt_block (bc, outbuf, inbuf);
+ _gcry_burn_stack (64);
+}
+
+
+static void
+do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
+{
+ u32 d1, d2;
+
+ d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+ d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+ decrypt( bc, &d1, &d2 );
+ outbuf[0] = (d1 >> 24) & 0xff;
+ outbuf[1] = (d1 >> 16) & 0xff;
+ outbuf[2] = (d1 >> 8) & 0xff;
+ outbuf[3] = d1 & 0xff;
+ outbuf[4] = (d2 >> 24) & 0xff;
+ outbuf[5] = (d2 >> 16) & 0xff;
+ outbuf[6] = (d2 >> 8) & 0xff;
+ outbuf[7] = d2 & 0xff;
+}
+
+static void
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+ BLOWFISH_context *bc = (BLOWFISH_context *) context;
+ do_decrypt_block (bc, outbuf, inbuf);
+ _gcry_burn_stack (64);
+}
+
+
+static const char*
+selftest(void)
+{
+ BLOWFISH_context c;
+ byte plain[] = "BLOWFISH";
+ byte buffer[8];
+ byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
+ byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
+ byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
+
+ bf_setkey( (void *) &c,
+ (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
+ encrypt_block( (void *) &c, buffer, plain );
+ if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) )
+ return "Blowfish selftest failed (1).";
+ decrypt_block( (void *) &c, buffer, buffer );
+ if( memcmp( buffer, plain, 8 ) )
+ return "Blowfish selftest failed (2).";
+
+ bf_setkey( (void *) &c, key3, 8 );
+ encrypt_block( (void *) &c, buffer, plain3 );
+ if( memcmp( buffer, cipher3, 8 ) )
+ return "Blowfish selftest failed (3).";
+ decrypt_block( (void *) &c, buffer, buffer );
+ if( memcmp( buffer, plain3, 8 ) )
+ return "Blowfish selftest failed (4).";
+ return NULL;
+}
+
+
+
+static gcry_err_code_t
+do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
+{
+ int i, j;
+ u32 data, datal, datar;
+ static int initialized;
+ static const char *selftest_failed;
+
+ if( !initialized )
+ {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error ("%s\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
+ c->p[i] = ps[i];
+ for(i=0; i < 256; i++ )
+ {
+ c->s0[i] = ks0[i];
+ c->s1[i] = ks1[i];
+ c->s2[i] = ks2[i];
+ c->s3[i] = ks3[i];
+ }
+
+ for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
+ {
+#ifdef WORDS_BIGENDIAN
+ ((byte*)&data)[0] = key[j];
+ ((byte*)&data)[1] = key[(j+1)%keylen];
+ ((byte*)&data)[2] = key[(j+2)%keylen];
+ ((byte*)&data)[3] = key[(j+3)%keylen];
+#else
+ ((byte*)&data)[3] = key[j];
+ ((byte*)&data)[2] = key[(j+1)%keylen];
+ ((byte*)&data)[1] = key[(j+2)%keylen];
+ ((byte*)&data)[0] = key[(j+3)%keylen];
+#endif
+ c->p[i] ^= data;
+ j = (j+4) % keylen;
+ }
+
+ datal = datar = 0;
+ for(i=0; i < BLOWFISH_ROUNDS+2; i += 2 )
+ {
+ do_encrypt( c, &datal, &datar );
+ c->p[i] = datal;
+ c->p[i+1] = datar;
+ }
+ for(i=0; i < 256; i += 2 )
+ {
+ do_encrypt( c, &datal, &datar );
+ c->s0[i] = datal;
+ c->s0[i+1] = datar;
+ }
+ for(i=0; i < 256; i += 2 )
+ {
+ do_encrypt( c, &datal, &datar );
+ c->s1[i] = datal;
+ c->s1[i+1] = datar;
+ }
+ for(i=0; i < 256; i += 2 )
+ {
+ do_encrypt( c, &datal, &datar );
+ c->s2[i] = datal;
+ c->s2[i+1] = datar;
+ }
+ for(i=0; i < 256; i += 2 )
+ {
+ do_encrypt( c, &datal, &datar );
+ c->s3[i] = datal;
+ c->s3[i+1] = datar;
+ }
+
+
+ /* Check for weak key. A weak key is a key in which a value in
+ the P-array (here c) occurs more than once per table. */
+ for(i=0; i < 255; i++ )
+ {
+ for( j=i+1; j < 256; j++)
+ {
+ if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
+ (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
+ return GPG_ERR_WEAK_KEY;
+ }
+ }
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+bf_setkey (void *context, const byte *key, unsigned keylen)
+{
+ BLOWFISH_context *c = (BLOWFISH_context *) context;
+ gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
+ _gcry_burn_stack (64);
+ return rc;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
+ {
+ "BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
+ sizeof (BLOWFISH_context),
+ bf_setkey, encrypt_block, decrypt_block
+ };
--- /dev/null
+/* camellia-glue.c - Glue for the Camellia cipher
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* I put all the libgcrypt-specific stuff in this file to keep the
+ camellia.c/camellia.h files exactly as provided by NTT. If they
+ update their code, this should make it easier to bring the changes
+ in. - dshaw
+
+ There is one small change which needs to be done: Include the
+ following code at the top of camellia.h: */
+#if 0
+
+/* To use Camellia with libraries it is often useful to keep the name
+ * space of the library clean. The following macro is thus useful:
+ *
+ * #define CAMELLIA_EXT_SYM_PREFIX foo_
+ *
+ * This prefixes all external symbols with "foo_".
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef CAMELLIA_EXT_SYM_PREFIX
+#define CAMELLIA_PREFIX1(x,y) x ## y
+#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
+#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
+#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
+#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
+#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
+#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
+#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
+#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
+#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
+#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
+#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
+#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
+#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+
+#endif /* Code sample. */
+
+
+#include <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "camellia.h"
+
+typedef struct
+{
+ int keybitlength;
+ KEY_TABLE_TYPE keytable;
+} CAMELLIA_context;
+
+static const char *selftest(void);
+
+static gcry_err_code_t
+camellia_setkey(void *c, const byte *key, unsigned keylen)
+{
+ CAMELLIA_context *ctx=c;
+ static int initialized=0;
+ static const char *selftest_failed=NULL;
+
+ if(keylen!=16 && keylen!=24 && keylen!=32)
+ return GPG_ERR_INV_KEYLEN;
+
+ if(!initialized)
+ {
+ initialized=1;
+ selftest_failed=selftest();
+ if(selftest_failed)
+ log_error("%s\n",selftest_failed);
+ }
+
+ if(selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ ctx->keybitlength=keylen*8;
+ Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
+ _gcry_burn_stack
+ ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
+ +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
+ +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
+ +3*2*sizeof(void*) /* Function calls. */
+ );
+
+ return 0;
+}
+
+static void
+camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+ CAMELLIA_context *ctx=c;
+
+ Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+ _gcry_burn_stack
+ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+ +4*sizeof(u32)
+ +2*sizeof(u32*)+4*sizeof(u32)
+ +2*2*sizeof(void*) /* Function calls. */
+ );
+}
+
+static void
+camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+ CAMELLIA_context *ctx=c;
+
+ Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+ _gcry_burn_stack
+ (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
+ +4*sizeof(u32)
+ +2*sizeof(u32*)+4*sizeof(u32)
+ +2*2*sizeof(void*) /* Function calls. */
+ );
+}
+
+static const char *
+selftest(void)
+{
+ CAMELLIA_context ctx;
+ byte scratch[16];
+
+ /* These test vectors are from RFC-3713 */
+ const byte plaintext[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+ };
+ const byte key_128[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
+ 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
+ };
+ const byte ciphertext_128[]=
+ {
+ 0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
+ 0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
+ };
+ const byte key_192[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
+ 0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
+ };
+ const byte ciphertext_192[]=
+ {
+ 0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
+ 0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
+ };
+ const byte key_256[]=
+ {
+ 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
+ 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
+ 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
+ };
+ const byte ciphertext_256[]=
+ {
+ 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
+ 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
+ };
+
+ camellia_setkey(&ctx,key_128,sizeof(key_128));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0)
+ return "CAMELLIA-128 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-128 test decryption failed.";
+
+ camellia_setkey(&ctx,key_192,sizeof(key_192));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0)
+ return "CAMELLIA-192 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-192 test decryption failed.";
+
+ camellia_setkey(&ctx,key_256,sizeof(key_256));
+ camellia_encrypt(&ctx,scratch,plaintext);
+ if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0)
+ return "CAMELLIA-256 test encryption failed.";
+ camellia_decrypt(&ctx,scratch,scratch);
+ if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
+ return "CAMELLIA-256 test decryption failed.";
+
+ return NULL;
+}
+
+/* These oids are from
+ <http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications_oid.html>,
+ retrieved May 1, 2007. */
+
+static gcry_cipher_oid_spec_t camellia128_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.2", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.1", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.3", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.4", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+static gcry_cipher_oid_spec_t camellia192_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.3", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.21", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.23", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.24", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+static gcry_cipher_oid_spec_t camellia256_oids[] =
+ {
+ {"1.2.392.200011.61.1.1.1.4", GCRY_CIPHER_MODE_CBC},
+ {"0.3.4401.5.3.1.9.41", GCRY_CIPHER_MODE_ECB},
+ {"0.3.4401.5.3.1.9.43", GCRY_CIPHER_MODE_OFB},
+ {"0.3.4401.5.3.1.9.44", GCRY_CIPHER_MODE_CFB},
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
+ {
+ "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
+ {
+ "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
+ {
+ "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
+ sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
+ };
--- /dev/null
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Algorithm Specification
+ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "camellia.h"
+
+/* u32 must be 32bit word */
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+/* key constants */
+
+#define CAMELLIA_SIGMA1L (0xA09E667FL)
+#define CAMELLIA_SIGMA1R (0x3BCC908BL)
+#define CAMELLIA_SIGMA2L (0xB67AE858L)
+#define CAMELLIA_SIGMA2R (0x4CAA73B2L)
+#define CAMELLIA_SIGMA3L (0xC6EF372FL)
+#define CAMELLIA_SIGMA3R (0xE94F82BEL)
+#define CAMELLIA_SIGMA4L (0x54FF53A5L)
+#define CAMELLIA_SIGMA4R (0xF1D36F1CL)
+#define CAMELLIA_SIGMA5L (0x10E527FAL)
+#define CAMELLIA_SIGMA5R (0xDE682D1DL)
+#define CAMELLIA_SIGMA6L (0xB05688C2L)
+#define CAMELLIA_SIGMA6R (0xB3E6C1FDL)
+
+/*
+ * macros
+ */
+
+
+#if defined(_MSC_VER)
+
+# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
+# define GETU32(p) SWAP(*((u32 *)(p)))
+# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));}
+
+#else /* not MS-VC */
+
+# define GETU32(pt) \
+ (((u32)(pt)[0] << 24) \
+ ^ ((u32)(pt)[1] << 16) \
+ ^ ((u32)(pt)[2] << 8) \
+ ^ ((u32)(pt)[3]))
+
+# define PUTU32(ct, st) { \
+ (ct)[0] = (u8)((st) >> 24); \
+ (ct)[1] = (u8)((st) >> 16); \
+ (ct)[2] = (u8)((st) >> 8); \
+ (ct)[3] = (u8)(st); }
+
+#endif
+
+#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2])
+#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1])
+
+/* rotation right shift 1byte */
+#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24))
+/* rotation left shift 1bit */
+#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31))
+/* rotation left shift 1byte */
+#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24))
+
+#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ ll = (ll << bits) + (lr >> (32 - bits)); \
+ lr = (lr << bits) + (rl >> (32 - bits)); \
+ rl = (rl << bits) + (rr >> (32 - bits)); \
+ rr = (rr << bits) + (w0 >> (32 - bits)); \
+ } while(0)
+
+#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \
+ do { \
+ w0 = ll; \
+ w1 = lr; \
+ ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \
+ lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \
+ rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \
+ rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \
+ } while(0)
+
+#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)])
+#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)])
+#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)])
+#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)])
+
+#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ il = xl ^ kl; \
+ ir = xr ^ kr; \
+ t0 = il >> 16; \
+ t1 = ir >> 16; \
+ yl = CAMELLIA_SP1110(ir & 0xff) \
+ ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \
+ ^ CAMELLIA_SP3033(t1 & 0xff) \
+ ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \
+ yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \
+ ^ CAMELLIA_SP0222(t0 & 0xff) \
+ ^ CAMELLIA_SP3033((il >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(il & 0xff); \
+ yl ^= yr; \
+ yr = CAMELLIA_RR8(yr); \
+ yr ^= yl; \
+ } while(0)
+
+
+/*
+ * for speed up
+ *
+ */
+#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \
+ do { \
+ t0 = kll; \
+ t0 &= ll; \
+ lr ^= CAMELLIA_RL1(t0); \
+ t1 = klr; \
+ t1 |= lr; \
+ ll ^= t1; \
+ \
+ t2 = krr; \
+ t2 |= rr; \
+ rl ^= t2; \
+ t3 = krl; \
+ t3 &= rl; \
+ rr ^= CAMELLIA_RL1(t3); \
+ } while(0)
+
+#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \
+ do { \
+ ir = CAMELLIA_SP1110(xr & 0xff) \
+ ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \
+ ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \
+ ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \
+ il = CAMELLIA_SP1110((xl >> 24) & 0xff) \
+ ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \
+ ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \
+ ^ CAMELLIA_SP4404(xl & 0xff); \
+ il ^= kl; \
+ ir ^= kr; \
+ ir ^= il; \
+ il = CAMELLIA_RR8(il); \
+ il ^= ir; \
+ yl ^= ir; \
+ yr ^= il; \
+ } while(0)
+
+
+static const u32 camellia_sp1110[256] = {
+ 0x70707000,0x82828200,0x2c2c2c00,0xececec00,
+ 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500,
+ 0xe4e4e400,0x85858500,0x57575700,0x35353500,
+ 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100,
+ 0x23232300,0xefefef00,0x6b6b6b00,0x93939300,
+ 0x45454500,0x19191900,0xa5a5a500,0x21212100,
+ 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00,
+ 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00,
+ 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00,
+ 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00,
+ 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00,
+ 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00,
+ 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00,
+ 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00,
+ 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600,
+ 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00,
+ 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600,
+ 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00,
+ 0x74747400,0x12121200,0x2b2b2b00,0x20202000,
+ 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900,
+ 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200,
+ 0x34343400,0x7e7e7e00,0x76767600,0x05050500,
+ 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100,
+ 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700,
+ 0x14141400,0x58585800,0x3a3a3a00,0x61616100,
+ 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00,
+ 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600,
+ 0x53535300,0x18181800,0xf2f2f200,0x22222200,
+ 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200,
+ 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100,
+ 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800,
+ 0x60606000,0xfcfcfc00,0x69696900,0x50505000,
+ 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00,
+ 0xa1a1a100,0x89898900,0x62626200,0x97979700,
+ 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500,
+ 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200,
+ 0x10101000,0xc4c4c400,0x00000000,0x48484800,
+ 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00,
+ 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00,
+ 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400,
+ 0x87878700,0x5c5c5c00,0x83838300,0x02020200,
+ 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300,
+ 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300,
+ 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200,
+ 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600,
+ 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00,
+ 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00,
+ 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00,
+ 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00,
+ 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00,
+ 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600,
+ 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900,
+ 0x78787800,0x98989800,0x06060600,0x6a6a6a00,
+ 0xe7e7e700,0x46464600,0x71717100,0xbababa00,
+ 0xd4d4d400,0x25252500,0xababab00,0x42424200,
+ 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00,
+ 0x72727200,0x07070700,0xb9b9b900,0x55555500,
+ 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00,
+ 0x36363600,0x49494900,0x2a2a2a00,0x68686800,
+ 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400,
+ 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00,
+ 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100,
+ 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400,
+ 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00,
+};
+
+static const u32 camellia_sp0222[256] = {
+ 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9,
+ 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb,
+ 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a,
+ 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282,
+ 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727,
+ 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242,
+ 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c,
+ 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b,
+ 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f,
+ 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d,
+ 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe,
+ 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434,
+ 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595,
+ 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a,
+ 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad,
+ 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a,
+ 0x00171717,0x001a1a1a,0x00353535,0x00cccccc,
+ 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a,
+ 0x00e8e8e8,0x00242424,0x00565656,0x00404040,
+ 0x00e1e1e1,0x00636363,0x00090909,0x00333333,
+ 0x00bfbfbf,0x00989898,0x00979797,0x00858585,
+ 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a,
+ 0x00dadada,0x006f6f6f,0x00535353,0x00626262,
+ 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf,
+ 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2,
+ 0x00bdbdbd,0x00363636,0x00222222,0x00383838,
+ 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c,
+ 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444,
+ 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565,
+ 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323,
+ 0x00484848,0x00101010,0x00d1d1d1,0x00515151,
+ 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0,
+ 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa,
+ 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f,
+ 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b,
+ 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5,
+ 0x00202020,0x00898989,0x00000000,0x00909090,
+ 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7,
+ 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5,
+ 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929,
+ 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404,
+ 0x009b9b9b,0x00949494,0x00212121,0x00666666,
+ 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7,
+ 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5,
+ 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c,
+ 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676,
+ 0x00030303,0x002d2d2d,0x00dedede,0x00969696,
+ 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c,
+ 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919,
+ 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d,
+ 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d,
+ 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2,
+ 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4,
+ 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575,
+ 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484,
+ 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5,
+ 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa,
+ 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414,
+ 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0,
+ 0x00787878,0x00707070,0x00e3e3e3,0x00494949,
+ 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6,
+ 0x00777777,0x00939393,0x00868686,0x00838383,
+ 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9,
+ 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d,
+};
+
+static const u32 camellia_sp3033[256] = {
+ 0x38003838,0x41004141,0x16001616,0x76007676,
+ 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2,
+ 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a,
+ 0x75007575,0x06000606,0x57005757,0xa000a0a0,
+ 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9,
+ 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090,
+ 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727,
+ 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede,
+ 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7,
+ 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767,
+ 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf,
+ 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d,
+ 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565,
+ 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e,
+ 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b,
+ 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6,
+ 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333,
+ 0xfd00fdfd,0x66006666,0x58005858,0x96009696,
+ 0x3a003a3a,0x09000909,0x95009595,0x10001010,
+ 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc,
+ 0xef00efef,0x26002626,0xe500e5e5,0x61006161,
+ 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282,
+ 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898,
+ 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb,
+ 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0,
+ 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e,
+ 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b,
+ 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111,
+ 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959,
+ 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8,
+ 0x12001212,0x04000404,0x74007474,0x54005454,
+ 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828,
+ 0x55005555,0x68006868,0x50005050,0xbe00bebe,
+ 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb,
+ 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca,
+ 0x70007070,0xff00ffff,0x32003232,0x69006969,
+ 0x08000808,0x62006262,0x00000000,0x24002424,
+ 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded,
+ 0x45004545,0x81008181,0x73007373,0x6d006d6d,
+ 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a,
+ 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101,
+ 0xe600e6e6,0x25002525,0x48004848,0x99009999,
+ 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9,
+ 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171,
+ 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313,
+ 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d,
+ 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5,
+ 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717,
+ 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646,
+ 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747,
+ 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b,
+ 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac,
+ 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535,
+ 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d,
+ 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121,
+ 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d,
+ 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa,
+ 0x7c007c7c,0x77007777,0x56005656,0x05000505,
+ 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434,
+ 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252,
+ 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd,
+ 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0,
+ 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a,
+ 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f,
+};
+
+static const u32 camellia_sp4404[256] = {
+ 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0,
+ 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae,
+ 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5,
+ 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092,
+ 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f,
+ 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b,
+ 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d,
+ 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c,
+ 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0,
+ 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084,
+ 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076,
+ 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004,
+ 0x14140014,0x3a3a003a,0xdede00de,0x11110011,
+ 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2,
+ 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a,
+ 0x24240024,0xe8e800e8,0x60600060,0x69690069,
+ 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062,
+ 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064,
+ 0x10100010,0x00000000,0xa3a300a3,0x75750075,
+ 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd,
+ 0x87870087,0x83830083,0xcdcd00cd,0x90900090,
+ 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf,
+ 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6,
+ 0x81810081,0x6f6f006f,0x13130013,0x63630063,
+ 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc,
+ 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4,
+ 0x78780078,0x06060006,0xe7e700e7,0x71710071,
+ 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d,
+ 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac,
+ 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1,
+ 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043,
+ 0x15150015,0xadad00ad,0x77770077,0x80800080,
+ 0x82820082,0xecec00ec,0x27270027,0xe5e500e5,
+ 0x85850085,0x35350035,0x0c0c000c,0x41410041,
+ 0xefef00ef,0x93930093,0x19190019,0x21210021,
+ 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd,
+ 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce,
+ 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a,
+ 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d,
+ 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d,
+ 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d,
+ 0x12120012,0x20200020,0xb1b100b1,0x99990099,
+ 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005,
+ 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7,
+ 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c,
+ 0x0f0f000f,0x16160016,0x18180018,0x22220022,
+ 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091,
+ 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050,
+ 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097,
+ 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2,
+ 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db,
+ 0x03030003,0xdada00da,0x3f3f003f,0x94940094,
+ 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033,
+ 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2,
+ 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b,
+ 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e,
+ 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e,
+ 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059,
+ 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba,
+ 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa,
+ 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a,
+ 0x49490049,0x68680068,0x38380038,0xa4a400a4,
+ 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1,
+ 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e,
+};
+
+
+/**
+ * Stuff related to the Camellia key schedule
+ */
+#define subl(x) subL[(x)]
+#define subr(x) subR[(x)]
+
+void camellia_setup128(const unsigned char *key, u32 *subkey)
+{
+ u32 kll, klr, krl, krr;
+ u32 il, ir, t0, t1, w0, w1;
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[26];
+ u32 subR[26];
+
+ /**
+ * k == kll || klr || krl || krr (|| is concatination)
+ */
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ /**
+ * generate KL dependent subkeys
+ */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(4) = kll; subr(4) = klr;
+ subl(5) = krl; subr(5) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(10) = kll; subr(10) = klr;
+ subl(11) = krl; subr(11) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(18) = kll; subr(18) = klr;
+ subl(19) = krl; subr(19) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+
+ /* generate KA */
+ kll = subl(0); klr = subr(0);
+ krl = subl(1); krr = subr(1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KA dependent subkeys */
+ subl(2) = kll; subr(2) = klr;
+ subl(3) = krl; subr(3) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(8) = kll; subr(8) = klr;
+ subl(9) = krl; subr(9) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(12) = kll; subr(12) = klr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(20) = kll; subr(20) = klr;
+ subl(21) = krl; subr(21) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(24) = kll; subr(24) = klr;
+ subl(25) = krl; subr(25) = krr;
+
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(24) ^= subl(1); subr(24) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(25); kw4r = subr(25);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ CamelliaSubkeyL(23) = subl(22);
+ CamelliaSubkeyR(23) = subr(22);
+ CamelliaSubkeyL(24) = subl(24) ^ subl(23);
+ CamelliaSubkeyR(24) = subr(24) ^ subr(23);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+
+ return;
+}
+
+void camellia_setup256(const unsigned char *key, u32 *subkey)
+{
+ u32 kll,klr,krl,krr; /* left half of key */
+ u32 krll,krlr,krrl,krrr; /* right half of key */
+ u32 il, ir, t0, t1, w0, w1; /* temporary variables */
+ u32 kw4l, kw4r, dw, tl, tr;
+ u32 subL[34];
+ u32 subR[34];
+
+ /**
+ * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr)
+ * (|| is concatination)
+ */
+
+ kll = GETU32(key );
+ klr = GETU32(key + 4);
+ krl = GETU32(key + 8);
+ krr = GETU32(key + 12);
+ krll = GETU32(key + 16);
+ krlr = GETU32(key + 20);
+ krrl = GETU32(key + 24);
+ krrr = GETU32(key + 28);
+
+ /* generate KL dependent subkeys */
+ subl(0) = kll; subr(0) = klr;
+ subl(1) = krl; subr(1) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45);
+ subl(12) = kll; subr(12) = klr;
+ subl(13) = krl; subr(13) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(16) = kll; subr(16) = klr;
+ subl(17) = krl; subr(17) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17);
+ subl(22) = kll; subr(22) = klr;
+ subl(23) = krl; subr(23) = krr;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34);
+ subl(30) = kll; subr(30) = klr;
+ subl(31) = krl; subr(31) = krr;
+
+ /* generate KR dependent subkeys */
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(4) = krll; subr(4) = krlr;
+ subl(5) = krrl; subr(5) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15);
+ subl(8) = krll; subr(8) = krlr;
+ subl(9) = krrl; subr(9) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(18) = krll; subr(18) = krlr;
+ subl(19) = krrl; subr(19) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+ subl(26) = krll; subr(26) = krlr;
+ subl(27) = krrl; subr(27) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34);
+
+ /* generate KA */
+ kll = subl(0) ^ krll; klr = subr(0) ^ krlr;
+ krl = subl(1) ^ krrl; krr = subr(1) ^ krrr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R,
+ w0, w1, il, ir, t0, t1);
+ krl ^= w0; krr ^= w1;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R,
+ kll, klr, il, ir, t0, t1);
+ kll ^= krll; klr ^= krlr;
+ CAMELLIA_F(kll, klr,
+ CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R,
+ krl, krr, il, ir, t0, t1);
+ krl ^= w0 ^ krrl; krr ^= w1 ^ krrr;
+ CAMELLIA_F(krl, krr,
+ CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R,
+ w0, w1, il, ir, t0, t1);
+ kll ^= w0; klr ^= w1;
+
+ /* generate KB */
+ krll ^= kll; krlr ^= klr;
+ krrl ^= krl; krrr ^= krr;
+ CAMELLIA_F(krll, krlr,
+ CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R,
+ w0, w1, il, ir, t0, t1);
+ krrl ^= w0; krrr ^= w1;
+ CAMELLIA_F(krrl, krrr,
+ CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R,
+ w0, w1, il, ir, t0, t1);
+ krll ^= w0; krlr ^= w1;
+
+ /* generate KA dependent subkeys */
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15);
+ subl(6) = kll; subr(6) = klr;
+ subl(7) = krl; subr(7) = krr;
+ CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30);
+ subl(14) = kll; subr(14) = klr;
+ subl(15) = krl; subr(15) = krr;
+ subl(24) = klr; subr(24) = krl;
+ subl(25) = krr; subr(25) = kll;
+ CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49);
+ subl(28) = kll; subr(28) = klr;
+ subl(29) = krl; subr(29) = krr;
+
+ /* generate KB dependent subkeys */
+ subl(2) = krll; subr(2) = krlr;
+ subl(3) = krrl; subr(3) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(10) = krll; subr(10) = krlr;
+ subl(11) = krrl; subr(11) = krrr;
+ CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30);
+ subl(20) = krll; subr(20) = krlr;
+ subl(21) = krrl; subr(21) = krrr;
+ CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51);
+ subl(32) = krll; subr(32) = krlr;
+ subl(33) = krrl; subr(33) = krrr;
+
+ /* absorb kw2 to other subkeys */
+ subl(3) ^= subl(1); subr(3) ^= subr(1);
+ subl(5) ^= subl(1); subr(5) ^= subr(1);
+ subl(7) ^= subl(1); subr(7) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(9);
+ dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(11) ^= subl(1); subr(11) ^= subr(1);
+ subl(13) ^= subl(1); subr(13) ^= subr(1);
+ subl(15) ^= subl(1); subr(15) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(17);
+ dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(19) ^= subl(1); subr(19) ^= subr(1);
+ subl(21) ^= subl(1); subr(21) ^= subr(1);
+ subl(23) ^= subl(1); subr(23) ^= subr(1);
+ subl(1) ^= subr(1) & ~subr(25);
+ dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw);
+ subl(27) ^= subl(1); subr(27) ^= subr(1);
+ subl(29) ^= subl(1); subr(29) ^= subr(1);
+ subl(31) ^= subl(1); subr(31) ^= subr(1);
+ subl(32) ^= subl(1); subr(32) ^= subr(1);
+
+ /* absorb kw4 to other subkeys */
+ kw4l = subl(33); kw4r = subr(33);
+ subl(30) ^= kw4l; subr(30) ^= kw4r;
+ subl(28) ^= kw4l; subr(28) ^= kw4r;
+ subl(26) ^= kw4l; subr(26) ^= kw4r;
+ kw4l ^= kw4r & ~subr(24);
+ dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw);
+ subl(22) ^= kw4l; subr(22) ^= kw4r;
+ subl(20) ^= kw4l; subr(20) ^= kw4r;
+ subl(18) ^= kw4l; subr(18) ^= kw4r;
+ kw4l ^= kw4r & ~subr(16);
+ dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw);
+ subl(14) ^= kw4l; subr(14) ^= kw4r;
+ subl(12) ^= kw4l; subr(12) ^= kw4r;
+ subl(10) ^= kw4l; subr(10) ^= kw4r;
+ kw4l ^= kw4r & ~subr(8);
+ dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw);
+ subl(6) ^= kw4l; subr(6) ^= kw4r;
+ subl(4) ^= kw4l; subr(4) ^= kw4r;
+ subl(2) ^= kw4l; subr(2) ^= kw4r;
+ subl(0) ^= kw4l; subr(0) ^= kw4r;
+
+ /* key XOR is end of F-function */
+ CamelliaSubkeyL(0) = subl(0) ^ subl(2);
+ CamelliaSubkeyR(0) = subr(0) ^ subr(2);
+ CamelliaSubkeyL(2) = subl(3);
+ CamelliaSubkeyR(2) = subr(3);
+ CamelliaSubkeyL(3) = subl(2) ^ subl(4);
+ CamelliaSubkeyR(3) = subr(2) ^ subr(4);
+ CamelliaSubkeyL(4) = subl(3) ^ subl(5);
+ CamelliaSubkeyR(4) = subr(3) ^ subr(5);
+ CamelliaSubkeyL(5) = subl(4) ^ subl(6);
+ CamelliaSubkeyR(5) = subr(4) ^ subr(6);
+ CamelliaSubkeyL(6) = subl(5) ^ subl(7);
+ CamelliaSubkeyR(6) = subr(5) ^ subr(7);
+ tl = subl(10) ^ (subr(10) & ~subr(8));
+ dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(7) = subl(6) ^ tl;
+ CamelliaSubkeyR(7) = subr(6) ^ tr;
+ CamelliaSubkeyL(8) = subl(8);
+ CamelliaSubkeyR(8) = subr(8);
+ CamelliaSubkeyL(9) = subl(9);
+ CamelliaSubkeyR(9) = subr(9);
+ tl = subl(7) ^ (subr(7) & ~subr(9));
+ dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(10) = tl ^ subl(11);
+ CamelliaSubkeyR(10) = tr ^ subr(11);
+ CamelliaSubkeyL(11) = subl(10) ^ subl(12);
+ CamelliaSubkeyR(11) = subr(10) ^ subr(12);
+ CamelliaSubkeyL(12) = subl(11) ^ subl(13);
+ CamelliaSubkeyR(12) = subr(11) ^ subr(13);
+ CamelliaSubkeyL(13) = subl(12) ^ subl(14);
+ CamelliaSubkeyR(13) = subr(12) ^ subr(14);
+ CamelliaSubkeyL(14) = subl(13) ^ subl(15);
+ CamelliaSubkeyR(14) = subr(13) ^ subr(15);
+ tl = subl(18) ^ (subr(18) & ~subr(16));
+ dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(15) = subl(14) ^ tl;
+ CamelliaSubkeyR(15) = subr(14) ^ tr;
+ CamelliaSubkeyL(16) = subl(16);
+ CamelliaSubkeyR(16) = subr(16);
+ CamelliaSubkeyL(17) = subl(17);
+ CamelliaSubkeyR(17) = subr(17);
+ tl = subl(15) ^ (subr(15) & ~subr(17));
+ dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(18) = tl ^ subl(19);
+ CamelliaSubkeyR(18) = tr ^ subr(19);
+ CamelliaSubkeyL(19) = subl(18) ^ subl(20);
+ CamelliaSubkeyR(19) = subr(18) ^ subr(20);
+ CamelliaSubkeyL(20) = subl(19) ^ subl(21);
+ CamelliaSubkeyR(20) = subr(19) ^ subr(21);
+ CamelliaSubkeyL(21) = subl(20) ^ subl(22);
+ CamelliaSubkeyR(21) = subr(20) ^ subr(22);
+ CamelliaSubkeyL(22) = subl(21) ^ subl(23);
+ CamelliaSubkeyR(22) = subr(21) ^ subr(23);
+ tl = subl(26) ^ (subr(26) & ~subr(24));
+ dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(23) = subl(22) ^ tl;
+ CamelliaSubkeyR(23) = subr(22) ^ tr;
+ CamelliaSubkeyL(24) = subl(24);
+ CamelliaSubkeyR(24) = subr(24);
+ CamelliaSubkeyL(25) = subl(25);
+ CamelliaSubkeyR(25) = subr(25);
+ tl = subl(23) ^ (subr(23) & ~subr(25));
+ dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw);
+ CamelliaSubkeyL(26) = tl ^ subl(27);
+ CamelliaSubkeyR(26) = tr ^ subr(27);
+ CamelliaSubkeyL(27) = subl(26) ^ subl(28);
+ CamelliaSubkeyR(27) = subr(26) ^ subr(28);
+ CamelliaSubkeyL(28) = subl(27) ^ subl(29);
+ CamelliaSubkeyR(28) = subr(27) ^ subr(29);
+ CamelliaSubkeyL(29) = subl(28) ^ subl(30);
+ CamelliaSubkeyR(29) = subr(28) ^ subr(30);
+ CamelliaSubkeyL(30) = subl(29) ^ subl(31);
+ CamelliaSubkeyR(30) = subr(29) ^ subr(31);
+ CamelliaSubkeyL(31) = subl(30);
+ CamelliaSubkeyR(31) = subr(30);
+ CamelliaSubkeyL(32) = subl(32) ^ subl(31);
+ CamelliaSubkeyR(32) = subr(32) ^ subr(31);
+
+ /* apply the inverse of the last half of P-function */
+ dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
+ dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
+ dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
+ dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
+ dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
+ dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
+ dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
+ dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
+ dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
+ dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
+ dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
+ dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
+ dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
+ dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
+ dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
+ dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
+ dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
+ dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
+ dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
+ dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
+ dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
+ dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
+ dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
+ dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
+ CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
+
+ return;
+}
+
+void camellia_setup192(const unsigned char *key, u32 *subkey)
+{
+ unsigned char kk[32];
+ u32 krll, krlr, krrl,krrr;
+
+ memcpy(kk, key, 24);
+ memcpy((unsigned char *)&krll, key+16,4);
+ memcpy((unsigned char *)&krlr, key+20,4);
+ krrl = ~krll;
+ krrr = ~krlr;
+ memcpy(kk+24, (unsigned char *)&krrl, 4);
+ memcpy(kk+28, (unsigned char *)&krrr, 4);
+ camellia_setup256(kk, subkey);
+ return;
+}
+
+
+/**
+ * Stuff related to camellia encryption/decryption
+ *
+ * "io" must be 4byte aligned and big-endian data.
+ */
+void camellia_encrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il, ir, t0, t1;
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+ /* main iteration */
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(24);
+ io[3] ^= CamelliaSubkeyR(24);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void camellia_decrypt128(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(24);
+ io[1] ^= CamelliaSubkeyR(24);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/**
+ * stuff for 192 and 256bit encryption/decryption
+ */
+void camellia_encrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(0);
+ io[1] ^= CamelliaSubkeyR(0);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(32);
+ io[3] ^= CamelliaSubkeyR(32);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+void camellia_decrypt256(const u32 *subkey, u32 *io)
+{
+ u32 il,ir,t0,t1; /* temporary valiables */
+
+ /* pre whitening but absorb kw2*/
+ io[0] ^= CamelliaSubkeyL(32);
+ io[1] ^= CamelliaSubkeyR(32);
+
+ /* main iteration */
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(31),CamelliaSubkeyR(31),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(30),CamelliaSubkeyR(30),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(29),CamelliaSubkeyR(29),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(28),CamelliaSubkeyR(28),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(27),CamelliaSubkeyR(27),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(26),CamelliaSubkeyR(26),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(25),CamelliaSubkeyR(25),
+ CamelliaSubkeyL(24),CamelliaSubkeyR(24),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(23),CamelliaSubkeyR(23),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(22),CamelliaSubkeyR(22),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(21),CamelliaSubkeyR(21),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(20),CamelliaSubkeyR(20),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(19),CamelliaSubkeyR(19),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(18),CamelliaSubkeyR(18),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(17),CamelliaSubkeyR(17),
+ CamelliaSubkeyL(16),CamelliaSubkeyR(16),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(15),CamelliaSubkeyR(15),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(14),CamelliaSubkeyR(14),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(13),CamelliaSubkeyR(13),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(12),CamelliaSubkeyR(12),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(11),CamelliaSubkeyR(11),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(10),CamelliaSubkeyR(10),
+ io[0],io[1],il,ir,t0,t1);
+
+ CAMELLIA_FLS(io[0],io[1],io[2],io[3],
+ CamelliaSubkeyL(9),CamelliaSubkeyR(9),
+ CamelliaSubkeyL(8),CamelliaSubkeyR(8),
+ t0,t1,il,ir);
+
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(7),CamelliaSubkeyR(7),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(6),CamelliaSubkeyR(6),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(5),CamelliaSubkeyR(5),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(4),CamelliaSubkeyR(4),
+ io[0],io[1],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[0],io[1],
+ CamelliaSubkeyL(3),CamelliaSubkeyR(3),
+ io[2],io[3],il,ir,t0,t1);
+ CAMELLIA_ROUNDSM(io[2],io[3],
+ CamelliaSubkeyL(2),CamelliaSubkeyR(2),
+ io[0],io[1],il,ir,t0,t1);
+
+ /* post whitening but kw4 */
+ io[2] ^= CamelliaSubkeyL(0);
+ io[3] ^= CamelliaSubkeyR(0);
+
+ t0 = io[0];
+ t1 = io[1];
+ io[0] = io[2];
+ io[1] = io[3];
+ io[2] = t0;
+ io[3] = t1;
+
+ return;
+}
+
+/***
+ *
+ * API for compatibility
+ */
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable)
+{
+ switch(keyBitLength) {
+ case 128:
+ camellia_setup128(rawKey, keyTable);
+ break;
+ case 192:
+ camellia_setup192(rawKey, keyTable);
+ break;
+ case 256:
+ camellia_setup256(rawKey, keyTable);
+ break;
+ default:
+ break;
+ }
+}
+
+
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *ciphertext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(plaintext);
+ tmp[1] = GETU32(plaintext + 4);
+ tmp[2] = GETU32(plaintext + 8);
+ tmp[3] = GETU32(plaintext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_encrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_encrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+
+ PUTU32(ciphertext, tmp[0]);
+ PUTU32(ciphertext + 4, tmp[1]);
+ PUTU32(ciphertext + 8, tmp[2]);
+ PUTU32(ciphertext + 12, tmp[3]);
+}
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *ciphertext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext)
+{
+ u32 tmp[4];
+
+ tmp[0] = GETU32(ciphertext);
+ tmp[1] = GETU32(ciphertext + 4);
+ tmp[2] = GETU32(ciphertext + 8);
+ tmp[3] = GETU32(ciphertext + 12);
+
+ switch (keyBitLength) {
+ case 128:
+ camellia_decrypt128(keyTable, tmp);
+ break;
+ case 192:
+ /* fall through */
+ case 256:
+ camellia_decrypt256(keyTable, tmp);
+ break;
+ default:
+ break;
+ }
+ PUTU32(plaintext, tmp[0]);
+ PUTU32(plaintext + 4, tmp[1]);
+ PUTU32(plaintext + 8, tmp[2]);
+ PUTU32(plaintext + 12, tmp[3]);
+}
--- /dev/null
+/* camellia.h ver 1.2.0
+ *
+ * Copyright (C) 2006,2007
+ * NTT (Nippon Telegraph and Telephone Corporation).
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef HEADER_CAMELLIA_H
+#define HEADER_CAMELLIA_H
+
+/* To use Camellia with libraries it is often useful to keep the name
+ * space of the library clean. The following macro is thus useful:
+ *
+ * #define CAMELLIA_EXT_SYM_PREFIX foo_
+ *
+ * This prefixes all external symbols with "foo_".
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#ifdef CAMELLIA_EXT_SYM_PREFIX
+#define CAMELLIA_PREFIX1(x,y) x ## y
+#define CAMELLIA_PREFIX2(x,y) CAMELLIA_PREFIX1(x,y)
+#define CAMELLIA_PREFIX(x) CAMELLIA_PREFIX2(CAMELLIA_EXT_SYM_PREFIX,x)
+#define Camellia_Ekeygen CAMELLIA_PREFIX(Camellia_Ekeygen)
+#define Camellia_EncryptBlock CAMELLIA_PREFIX(Camellia_EncryptBlock)
+#define Camellia_DecryptBlock CAMELLIA_PREFIX(Camellia_DecryptBlock)
+#define camellia_decrypt128 CAMELLIA_PREFIX(camellia_decrypt128)
+#define camellia_decrypt256 CAMELLIA_PREFIX(camellia_decrypt256)
+#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
+#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
+#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
+#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
+#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
+#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CAMELLIA_BLOCK_SIZE 16
+#define CAMELLIA_TABLE_BYTE_LEN 272
+#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4)
+
+typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN];
+
+
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
+ KEY_TABLE_TYPE keyTable);
+
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *cipherText);
+
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *cipherText,
+ const KEY_TABLE_TYPE keyTable,
+ unsigned char *plaintext);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_CAMELLIA_H */
--- /dev/null
+/* cast5.c - CAST5 cipher (RFC2144)
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* Test vectors:
+ *
+ * 128-bit key = 01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A
+ * plaintext = 01 23 45 67 89 AB CD EF
+ * ciphertext = 23 8B 4F E5 84 7E 44 B2
+ *
+ * 80-bit key = 01 23 45 67 12 34 56 78 23 45
+ * = 01 23 45 67 12 34 56 78 23 45 00 00 00 00 00 00
+ * plaintext = 01 23 45 67 89 AB CD EF
+ * ciphertext = EB 6A 71 1A 2C 02 27 1B
+ *
+ * 40-bit key = 01 23 45 67 12
+ * = 01 23 45 67 12 00 00 00 00 00 00 00 00 00 00 00
+ * plaintext = 01 23 45 67 89 AB CD EF
+ * ciphertext = 7A C8 16 D1 6E 9B 30 2E
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+
+#define CAST5_BLOCKSIZE 8
+
+typedef struct {
+ u32 Km[16];
+ byte Kr[16];
+} CAST5_context;
+
+static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
+static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
+static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
+
+
+
+
+static const u32 s1[256] = {
+0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
+0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
+0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
+0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
+0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
+0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
+0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
+0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
+0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
+0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
+0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
+0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
+0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
+0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
+0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
+0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
+0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
+0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
+0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
+0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
+0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
+0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
+0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
+0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
+0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
+0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
+0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
+0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
+0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
+0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
+0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
+0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
+};
+static const u32 s2[256] = {
+0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
+0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
+0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
+0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
+0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
+0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
+0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
+0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
+0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
+0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
+0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
+0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
+0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
+0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
+0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
+0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
+0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
+0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
+0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
+0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
+0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
+0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
+0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
+0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
+0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
+0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
+0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
+0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
+0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
+0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
+0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
+0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
+};
+static const u32 s3[256] = {
+0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
+0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
+0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
+0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
+0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
+0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
+0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
+0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
+0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
+0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
+0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
+0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
+0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
+0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
+0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
+0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
+0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
+0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
+0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
+0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
+0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
+0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
+0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
+0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
+0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
+0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
+0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
+0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
+0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
+0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
+0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
+0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
+};
+static const u32 s4[256] = {
+0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
+0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
+0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
+0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
+0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
+0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
+0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
+0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
+0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
+0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
+0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
+0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
+0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
+0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
+0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
+0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
+0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
+0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
+0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
+0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
+0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
+0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
+0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
+0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
+0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
+0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
+0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
+0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
+0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
+0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
+0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
+0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
+};
+static const u32 s5[256] = {
+0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
+0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
+0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
+0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
+0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
+0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
+0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
+0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
+0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
+0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
+0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
+0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
+0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
+0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
+0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
+0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
+0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
+0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
+0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
+0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
+0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
+0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
+0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
+0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
+0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
+0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
+0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
+0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
+0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
+0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
+0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
+0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
+};
+static const u32 s6[256] = {
+0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
+0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
+0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
+0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
+0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
+0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
+0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
+0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
+0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
+0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
+0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
+0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
+0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
+0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
+0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
+0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
+0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
+0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
+0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
+0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
+0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
+0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
+0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
+0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
+0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
+0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
+0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
+0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
+0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
+0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
+0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
+0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
+};
+static const u32 s7[256] = {
+0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
+0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
+0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
+0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
+0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
+0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
+0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
+0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
+0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
+0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
+0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
+0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
+0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
+0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
+0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
+0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
+0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
+0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
+0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
+0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
+0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
+0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
+0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
+0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
+0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
+0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
+0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
+0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
+0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
+0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
+0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
+0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
+};
+static const u32 s8[256] = {
+0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
+0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
+0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
+0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
+0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
+0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
+0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
+0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
+0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
+0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
+0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
+0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
+0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
+0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
+0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
+0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
+0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
+0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
+0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
+0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
+0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
+0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
+0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
+0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
+0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
+0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
+0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
+0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
+0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
+0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
+0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
+0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
+};
+
+
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+rol(int n, u32 x)
+{
+ __asm__("roll %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
+#endif
+
+#define F1(D,m,r) ( (I = ((m) + (D))), (I=rol((r),I)), \
+ (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
+#define F2(D,m,r) ( (I = ((m) ^ (D))), (I=rol((r),I)), \
+ (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
+#define F3(D,m,r) ( (I = ((m) - (D))), (I=rol((r),I)), \
+ (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
+
+static void
+do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
+{
+ u32 l, r, t;
+ u32 I; /* used by the Fx macros */
+ u32 *Km;
+ byte *Kr;
+
+ Km = c->Km;
+ Kr = c->Kr;
+
+ /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
+ * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
+ */
+ l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+ r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+
+ /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
+ * Li = Ri-1;
+ * Ri = Li-1 ^ f(Ri-1,Kmi,Kri), where f is defined in Section 2.2
+ * Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
+ * Rounds 2, 5, 8, 11, and 14 use f function Type 2.
+ * Rounds 3, 6, 9, 12, and 15 use f function Type 3.
+ */
+
+ t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
+ t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
+ t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
+ t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
+ t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
+ t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
+ t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
+ t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
+ t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
+ t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
+ t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+ t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
+ t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
+ t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
+ t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
+ t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
+
+ /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
+ * concatenate to form the ciphertext.) */
+ outbuf[0] = (r >> 24) & 0xff;
+ outbuf[1] = (r >> 16) & 0xff;
+ outbuf[2] = (r >> 8) & 0xff;
+ outbuf[3] = r & 0xff;
+ outbuf[4] = (l >> 24) & 0xff;
+ outbuf[5] = (l >> 16) & 0xff;
+ outbuf[6] = (l >> 8) & 0xff;
+ outbuf[7] = l & 0xff;
+}
+
+static void
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+ CAST5_context *c = (CAST5_context *) context;
+ do_encrypt_block (c, outbuf, inbuf);
+ _gcry_burn_stack (20+4*sizeof(void*));
+}
+
+
+static void
+do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
+{
+ u32 l, r, t;
+ u32 I;
+ u32 *Km;
+ byte *Kr;
+
+ Km = c->Km;
+ Kr = c->Kr;
+
+ l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
+ r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+
+ t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
+ t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
+ t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]);
+ t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]);
+ t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]);
+ t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]);
+ t = l; l = r; r = t ^ F1(r, Km[ 9], Kr[ 9]);
+ t = l; l = r; r = t ^ F3(r, Km[ 8], Kr[ 8]);
+ t = l; l = r; r = t ^ F2(r, Km[ 7], Kr[ 7]);
+ t = l; l = r; r = t ^ F1(r, Km[ 6], Kr[ 6]);
+ t = l; l = r; r = t ^ F3(r, Km[ 5], Kr[ 5]);
+ t = l; l = r; r = t ^ F2(r, Km[ 4], Kr[ 4]);
+ t = l; l = r; r = t ^ F1(r, Km[ 3], Kr[ 3]);
+ t = l; l = r; r = t ^ F3(r, Km[ 2], Kr[ 2]);
+ t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
+ t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
+
+ outbuf[0] = (r >> 24) & 0xff;
+ outbuf[1] = (r >> 16) & 0xff;
+ outbuf[2] = (r >> 8) & 0xff;
+ outbuf[3] = r & 0xff;
+ outbuf[4] = (l >> 24) & 0xff;
+ outbuf[5] = (l >> 16) & 0xff;
+ outbuf[6] = (l >> 8) & 0xff;
+ outbuf[7] = l & 0xff;
+}
+
+static void
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+ CAST5_context *c = (CAST5_context *) context;
+ do_decrypt_block (c, outbuf, inbuf);
+ _gcry_burn_stack (20+4*sizeof(void*));
+}
+
+
+static const char*
+selftest(void)
+{
+ CAST5_context c;
+ byte key[16] = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+ 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A };
+ byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
+ byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
+ byte buffer[8];
+
+ cast_setkey( &c, key, 16 );
+ encrypt_block( &c, buffer, plain );
+ if( memcmp( buffer, cipher, 8 ) )
+ return "1";
+ decrypt_block( &c, buffer, buffer );
+ if( memcmp( buffer, plain, 8 ) )
+ return "2";
+
+#if 0 /* full maintenance test */
+ {
+ int i;
+ byte a0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+ 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
+ byte b0[16] = { 0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
+ 0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A };
+ byte a1[16] = { 0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
+ 0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92 };
+ byte b1[16] = { 0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
+ 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E };
+
+ for(i=0; i < 1000000; i++ ) {
+ cast_setkey( &c, b0, 16 );
+ encrypt_block( &c, a0, a0 );
+ encrypt_block( &c, a0+8, a0+8 );
+ cast_setkey( &c, a0, 16 );
+ encrypt_block( &c, b0, b0 );
+ encrypt_block( &c, b0+8, b0+8 );
+ }
+ if( memcmp( a0, a1, 16 ) || memcmp( b0, b1, 16 ) )
+ return "3";
+
+ }
+#endif
+ return NULL;
+}
+
+
+static void
+key_schedule( u32 *x, u32 *z, u32 *k )
+{
+
+#define xi(i) ((x[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
+#define zi(i) ((z[(i)/4] >> (8*(3-((i)%4)))) & 0xff)
+
+ z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
+ z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
+ z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
+ z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
+ k[0] = s5[zi( 8)]^s6[zi( 9)]^s7[zi( 7)]^s8[zi( 6)]^s5[zi( 2)];
+ k[1] = s5[zi(10)]^s6[zi(11)]^s7[zi( 5)]^s8[zi( 4)]^s6[zi( 6)];
+ k[2] = s5[zi(12)]^s6[zi(13)]^s7[zi( 3)]^s8[zi( 2)]^s7[zi( 9)];
+ k[3] = s5[zi(14)]^s6[zi(15)]^s7[zi( 1)]^s8[zi( 0)]^s8[zi(12)];
+
+ x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
+ x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
+ x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
+ x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
+ k[4] = s5[xi( 3)]^s6[xi( 2)]^s7[xi(12)]^s8[xi(13)]^s5[xi( 8)];
+ k[5] = s5[xi( 1)]^s6[xi( 0)]^s7[xi(14)]^s8[xi(15)]^s6[xi(13)];
+ k[6] = s5[xi( 7)]^s6[xi( 6)]^s7[xi( 8)]^s8[xi( 9)]^s7[xi( 3)];
+ k[7] = s5[xi( 5)]^s6[xi( 4)]^s7[xi(10)]^s8[xi(11)]^s8[xi( 7)];
+
+ z[0] = x[0] ^ s5[xi(13)]^s6[xi(15)]^s7[xi(12)]^s8[xi(14)]^s7[xi( 8)];
+ z[1] = x[2] ^ s5[zi( 0)]^s6[zi( 2)]^s7[zi( 1)]^s8[zi( 3)]^s8[xi(10)];
+ z[2] = x[3] ^ s5[zi( 7)]^s6[zi( 6)]^s7[zi( 5)]^s8[zi( 4)]^s5[xi( 9)];
+ z[3] = x[1] ^ s5[zi(10)]^s6[zi( 9)]^s7[zi(11)]^s8[zi( 8)]^s6[xi(11)];
+ k[8] = s5[zi( 3)]^s6[zi( 2)]^s7[zi(12)]^s8[zi(13)]^s5[zi( 9)];
+ k[9] = s5[zi( 1)]^s6[zi( 0)]^s7[zi(14)]^s8[zi(15)]^s6[zi(12)];
+ k[10]= s5[zi( 7)]^s6[zi( 6)]^s7[zi( 8)]^s8[zi( 9)]^s7[zi( 2)];
+ k[11]= s5[zi( 5)]^s6[zi( 4)]^s7[zi(10)]^s8[zi(11)]^s8[zi( 6)];
+
+ x[0] = z[2] ^ s5[zi( 5)]^s6[zi( 7)]^s7[zi( 4)]^s8[zi( 6)]^s7[zi( 0)];
+ x[1] = z[0] ^ s5[xi( 0)]^s6[xi( 2)]^s7[xi( 1)]^s8[xi( 3)]^s8[zi( 2)];
+ x[2] = z[1] ^ s5[xi( 7)]^s6[xi( 6)]^s7[xi( 5)]^s8[xi( 4)]^s5[zi( 1)];
+ x[3] = z[3] ^ s5[xi(10)]^s6[xi( 9)]^s7[xi(11)]^s8[xi( 8)]^s6[zi( 3)];
+ k[12]= s5[xi( 8)]^s6[xi( 9)]^s7[xi( 7)]^s8[xi( 6)]^s5[xi( 3)];
+ k[13]= s5[xi(10)]^s6[xi(11)]^s7[xi( 5)]^s8[xi( 4)]^s6[xi( 7)];
+ k[14]= s5[xi(12)]^s6[xi(13)]^s7[xi( 3)]^s8[xi( 2)]^s7[xi( 8)];
+ k[15]= s5[xi(14)]^s6[xi(15)]^s7[xi( 1)]^s8[xi( 0)]^s8[xi(13)];
+
+#undef xi
+#undef zi
+}
+
+
+static gcry_err_code_t
+do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
+{
+ static int initialized;
+ static const char* selftest_failed;
+ int i;
+ u32 x[4];
+ u32 z[4];
+ u32 k[16];
+
+ if( !initialized )
+ {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error ("CAST5 selftest failed (%s).\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if( keylen != 16 )
+ return GPG_ERR_INV_KEYLEN;
+
+ x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3];
+ x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7];
+ x[2] = key[8] << 24 | key[9] << 16 | key[10] << 8 | key[11];
+ x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
+
+ key_schedule( x, z, k );
+ for(i=0; i < 16; i++ )
+ c->Km[i] = k[i];
+ key_schedule( x, z, k );
+ for(i=0; i < 16; i++ )
+ c->Kr[i] = k[i] & 0x1f;
+
+ memset(&x,0, sizeof x);
+ memset(&z,0, sizeof z);
+ memset(&k,0, sizeof k);
+
+#undef xi
+#undef zi
+ return GPG_ERR_NO_ERROR;
+}
+
+static gcry_err_code_t
+cast_setkey (void *context, const byte *key, unsigned keylen )
+{
+ CAST5_context *c = (CAST5_context *) context;
+ gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
+ _gcry_burn_stack (96+7*sizeof(void*));
+ return rc;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
+ {
+ "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
+ cast_setkey, encrypt_block, decrypt_block
+ };
--- /dev/null
+/* cipher.c - cipher dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+#define MAX_BLOCKSIZE 16
+#define TABLE_SIZE 14
+#define CTX_MAGIC_NORMAL 0x24091964
+#define CTX_MAGIC_SECURE 0x46919042
+
+/* Try to use 16 byte aligned cipher context for better performance.
+ We use the aligned attribute, thus it is only possible to implement
+ this with gcc. */
+#undef NEED_16BYTE_ALIGNED_CONTEXT
+#if defined (__GNUC__)
+# define NEED_16BYTE_ALIGNED_CONTEXT 1
+#endif
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+ field from the module specification against NULL and instead
+ directly test the respective fields of extraspecs. */
+static cipher_extra_spec_t dummy_extra_spec;
+
+/* This is the list of the default ciphers, which are included in
+ libgcrypt. */
+static struct cipher_table_entry
+{
+ gcry_cipher_spec_t *cipher;
+ cipher_extra_spec_t *extraspec;
+ unsigned int algorithm;
+ int fips_allowed;
+} cipher_table[] =
+ {
+#if USE_BLOWFISH
+ { &_gcry_cipher_spec_blowfish,
+ &dummy_extra_spec, GCRY_CIPHER_BLOWFISH },
+#endif
+#if USE_DES
+ { &_gcry_cipher_spec_des,
+ &dummy_extra_spec, GCRY_CIPHER_DES },
+ { &_gcry_cipher_spec_tripledes,
+ &_gcry_cipher_extraspec_tripledes, GCRY_CIPHER_3DES, 1 },
+#endif
+#if USE_ARCFOUR
+ { &_gcry_cipher_spec_arcfour,
+ &dummy_extra_spec, GCRY_CIPHER_ARCFOUR },
+#endif
+#if USE_CAST5
+ { &_gcry_cipher_spec_cast5,
+ &dummy_extra_spec, GCRY_CIPHER_CAST5 },
+#endif
+#if USE_AES
+ { &_gcry_cipher_spec_aes,
+ &_gcry_cipher_extraspec_aes, GCRY_CIPHER_AES, 1 },
+ { &_gcry_cipher_spec_aes192,
+ &_gcry_cipher_extraspec_aes192, GCRY_CIPHER_AES192, 1 },
+ { &_gcry_cipher_spec_aes256,
+ &_gcry_cipher_extraspec_aes256, GCRY_CIPHER_AES256, 1 },
+#endif
+#if USE_TWOFISH
+ { &_gcry_cipher_spec_twofish,
+ &dummy_extra_spec, GCRY_CIPHER_TWOFISH },
+ { &_gcry_cipher_spec_twofish128,
+ &dummy_extra_spec, GCRY_CIPHER_TWOFISH128 },
+#endif
+#if USE_SERPENT
+ { &_gcry_cipher_spec_serpent128,
+ &dummy_extra_spec, GCRY_CIPHER_SERPENT128 },
+ { &_gcry_cipher_spec_serpent192,
+ &dummy_extra_spec, GCRY_CIPHER_SERPENT192 },
+ { &_gcry_cipher_spec_serpent256,
+ &dummy_extra_spec, GCRY_CIPHER_SERPENT256 },
+#endif
+#if USE_RFC2268
+ { &_gcry_cipher_spec_rfc2268_40,
+ &dummy_extra_spec, GCRY_CIPHER_RFC2268_40 },
+#endif
+#if USE_SEED
+ { &_gcry_cipher_spec_seed,
+ &dummy_extra_spec, GCRY_CIPHER_SEED },
+#endif
+#if USE_CAMELLIA
+ { &_gcry_cipher_spec_camellia128,
+ &dummy_extra_spec, GCRY_CIPHER_CAMELLIA128 },
+ { &_gcry_cipher_spec_camellia192,
+ &dummy_extra_spec, GCRY_CIPHER_CAMELLIA192 },
+ { &_gcry_cipher_spec_camellia256,
+ &dummy_extra_spec, GCRY_CIPHER_CAMELLIA256 },
+#endif
+ { NULL }
+ };
+
+/* List of registered ciphers. */
+static gcry_module_t ciphers_registered;
+
+/* This is the lock protecting CIPHERS_REGISTERED. */
+static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
+
+/* Flag to check whether the default ciphers have already been
+ registered. */
+static int default_ciphers_registered;
+
+/* Convenient macro for registering the default ciphers. */
+#define REGISTER_DEFAULT_CIPHERS \
+ do \
+ { \
+ ath_mutex_lock (&ciphers_registered_lock); \
+ if (! default_ciphers_registered) \
+ { \
+ cipher_register_default (); \
+ default_ciphers_registered = 1; \
+ } \
+ ath_mutex_unlock (&ciphers_registered_lock); \
+ } \
+ while (0)
+
+
+/* A VIA processor with the Padlock engine as well as the Intel AES_NI
+ instructions require an alignment of most data on a 16 byte
+ boundary. Because we trick out the compiler while allocating the
+ context, the align attribute as used in rijndael.c does not work on
+ its own. Thus we need to make sure that the entire context
+ structure is a aligned on that boundary. We achieve this by
+ defining a new type and use that instead of our usual alignment
+ type. */
+typedef union
+{
+ PROPERLY_ALIGNED_TYPE foo;
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ char bar[16] __attribute__ ((aligned (16)));
+#endif
+ char c[1];
+} cipher_context_alignment_t;
+
+
+/* The handle structure. */
+struct gcry_cipher_handle
+{
+ int magic;
+ size_t actual_handle_size; /* Allocated size of this handle. */
+ size_t handle_offset; /* Offset to the malloced block. */
+ gcry_cipher_spec_t *cipher;
+ cipher_extra_spec_t *extraspec;
+ gcry_module_t module;
+
+ /* The algorithm id. This is a hack required because the module
+ interface does not easily allow to retrieve this value. */
+ int algo;
+
+ /* A structure with function pointers for bulk operations. Due to
+ limitations of the module system (we don't want to change the
+ API) we need to keep these function pointers here. The cipher
+ open function intializes them and the actual encryption routines
+ use them if they are not NULL. */
+ struct {
+ void (*cfb_enc)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+ void (*cfb_dec)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+ void (*cbc_enc)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks, int cbc_mac);
+ void (*cbc_dec)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+ void (*ctr_enc)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+ } bulk;
+
+
+ int mode;
+ unsigned int flags;
+
+ struct {
+ unsigned int key:1; /* Set to 1 if a key has been set. */
+ unsigned int iv:1; /* Set to 1 if a IV has been set. */
+ } marks;
+
+ /* The initialization vector. For best performance we make sure
+ that it is properly aligned. In particular some implementations
+ of bulk operations expect an 16 byte aligned IV. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char iv[MAX_BLOCKSIZE];
+ } u_iv;
+
+ /* The counter for CTR mode. This field is also used by AESWRAP and
+ thus we can't use the U_IV union. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char ctr[MAX_BLOCKSIZE];
+ } u_ctr;
+
+ /* Space to save an IV or CTR for chaining operations. */
+ unsigned char lastiv[MAX_BLOCKSIZE];
+ int unused; /* Number of unused bytes in LASTIV. */
+
+ /* What follows are two contexts of the cipher in use. The first
+ one needs to be aligned well enough for the cipher operation
+ whereas the second one is a copy created by cipher_setkey and
+ used by cipher_reset. That second copy has no need for proper
+ aligment because it is only accessed by memcpy. */
+ cipher_context_alignment_t context;
+};
+
+
+\f
+/* These dummy functions are used in case a cipher implementation
+ refuses to provide it's own functions. */
+
+static gcry_err_code_t
+dummy_setkey (void *c, const unsigned char *key, unsigned int keylen)
+{
+ (void)c;
+ (void)key;
+ (void)keylen;
+ return GPG_ERR_NO_ERROR;
+}
+
+static void
+dummy_encrypt_block (void *c,
+ unsigned char *outbuf, const unsigned char *inbuf)
+{
+ (void)c;
+ (void)outbuf;
+ (void)inbuf;
+ BUG();
+}
+
+static void
+dummy_decrypt_block (void *c,
+ unsigned char *outbuf, const unsigned char *inbuf)
+{
+ (void)c;
+ (void)outbuf;
+ (void)inbuf;
+ BUG();
+}
+
+static void
+dummy_encrypt_stream (void *c,
+ unsigned char *outbuf, const unsigned char *inbuf,
+ unsigned int n)
+{
+ (void)c;
+ (void)outbuf;
+ (void)inbuf;
+ (void)n;
+ BUG();
+}
+
+static void
+dummy_decrypt_stream (void *c,
+ unsigned char *outbuf, const unsigned char *inbuf,
+ unsigned int n)
+{
+ (void)c;
+ (void)outbuf;
+ (void)inbuf;
+ (void)n;
+ BUG();
+}
+
+\f
+/* Internal function. Register all the ciphers included in
+ CIPHER_TABLE. Note, that this function gets only used by the macro
+ REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
+static void
+cipher_register_default (void)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ int i;
+
+ for (i = 0; !err && cipher_table[i].cipher; i++)
+ {
+ if (! cipher_table[i].cipher->setkey)
+ cipher_table[i].cipher->setkey = dummy_setkey;
+ if (! cipher_table[i].cipher->encrypt)
+ cipher_table[i].cipher->encrypt = dummy_encrypt_block;
+ if (! cipher_table[i].cipher->decrypt)
+ cipher_table[i].cipher->decrypt = dummy_decrypt_block;
+ if (! cipher_table[i].cipher->stencrypt)
+ cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
+ if (! cipher_table[i].cipher->stdecrypt)
+ cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
+
+ if ( fips_mode () && !cipher_table[i].fips_allowed )
+ continue;
+
+ err = _gcry_module_add (&ciphers_registered,
+ cipher_table[i].algorithm,
+ (void *) cipher_table[i].cipher,
+ (void *) cipher_table[i].extraspec,
+ NULL);
+ }
+
+ if (err)
+ BUG ();
+}
+
+/* Internal callback function. Used via _gcry_module_lookup. */
+static int
+gcry_cipher_lookup_func_name (void *spec, void *data)
+{
+ gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
+ char *name = (char *) data;
+ const char **aliases = cipher->aliases;
+ int i, ret = ! stricmp (name, cipher->name);
+
+ if (aliases)
+ for (i = 0; aliases[i] && (! ret); i++)
+ ret = ! stricmp (name, aliases[i]);
+
+ return ret;
+}
+
+/* Internal callback function. Used via _gcry_module_lookup. */
+static int
+gcry_cipher_lookup_func_oid (void *spec, void *data)
+{
+ gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
+ char *oid = (char *) data;
+ gcry_cipher_oid_spec_t *oid_specs = cipher->oids;
+ int ret = 0, i;
+
+ if (oid_specs)
+ for (i = 0; oid_specs[i].oid && (! ret); i++)
+ if (! stricmp (oid, oid_specs[i].oid))
+ ret = 1;
+
+ return ret;
+}
+
+/* Internal function. Lookup a cipher entry by it's name. */
+static gcry_module_t
+gcry_cipher_lookup_name (const char *name)
+{
+ gcry_module_t cipher;
+
+ cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
+ gcry_cipher_lookup_func_name);
+
+ return cipher;
+}
+
+/* Internal function. Lookup a cipher entry by it's oid. */
+static gcry_module_t
+gcry_cipher_lookup_oid (const char *oid)
+{
+ gcry_module_t cipher;
+
+ cipher = _gcry_module_lookup (ciphers_registered, (void *) oid,
+ gcry_cipher_lookup_func_oid);
+
+ return cipher;
+}
+
+/* Register a new cipher module whose specification can be found in
+ CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t
+_gcry_cipher_register (gcry_cipher_spec_t *cipher,
+ cipher_extra_spec_t *extraspec,
+ int *algorithm_id,
+ gcry_module_t *module)
+{
+ gcry_err_code_t err = 0;
+ gcry_module_t mod;
+
+ /* We do not support module loading in fips mode. */
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ err = _gcry_module_add (&ciphers_registered, 0,
+ (void *)cipher,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
+ &mod);
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ if (! err)
+ {
+ *module = mod;
+ *algorithm_id = mod->mod_id;
+ }
+
+ return gcry_error (err);
+}
+
+/* Unregister the cipher identified by MODULE, which must have been
+ registered with gcry_cipher_register. */
+void
+gcry_cipher_unregister (gcry_module_t module)
+{
+ ath_mutex_lock (&ciphers_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&ciphers_registered_lock);
+}
+
+/* Locate the OID in the oid table and return the index or -1 when not
+ found. An opitonal "oid." or "OID." prefix in OID is ignored, the
+ OID is expected to be in standard IETF dotted notation. The
+ internal algorithm number is returned in ALGORITHM unless it
+ ispassed as NULL. A pointer to the specification of the module
+ implementing this algorithm is return in OID_SPEC unless passed as
+ NULL.*/
+static int
+search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
+{
+ gcry_module_t module;
+ int ret = 0;
+
+ if (oid && ((! strncmp (oid, "oid.", 4))
+ || (! strncmp (oid, "OID.", 4))))
+ oid += 4;
+
+ module = gcry_cipher_lookup_oid (oid);
+ if (module)
+ {
+ gcry_cipher_spec_t *cipher = module->spec;
+ int i;
+
+ for (i = 0; cipher->oids[i].oid && !ret; i++)
+ if (! stricmp (oid, cipher->oids[i].oid))
+ {
+ if (algorithm)
+ *algorithm = module->mod_id;
+ if (oid_spec)
+ *oid_spec = cipher->oids[i];
+ ret = 1;
+ }
+ _gcry_module_release (module);
+ }
+
+ return ret;
+}
+
+/* Map STRING to the cipher algorithm identifier. Returns the
+ algorithm ID of the cipher for the given name or 0 if the name is
+ not known. It is valid to pass NULL for STRING which results in a
+ return value of 0. */
+int
+gcry_cipher_map_name (const char *string)
+{
+ gcry_module_t cipher;
+ int ret, algorithm = 0;
+
+ if (! string)
+ return 0;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ /* If the string starts with a digit (optionally prefixed with
+ either "OID." or "oid."), we first look into our table of ASN.1
+ object identifiers to figure out the algorithm */
+
+ ath_mutex_lock (&ciphers_registered_lock);
+
+ ret = search_oid (string, &algorithm, NULL);
+ if (! ret)
+ {
+ cipher = gcry_cipher_lookup_name (string);
+ if (cipher)
+ {
+ algorithm = cipher->mod_id;
+ _gcry_module_release (cipher);
+ }
+ }
+
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return algorithm;
+}
+
+
+/* Given a STRING with an OID in dotted decimal notation, this
+ function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
+ with that OID or 0 if no mode is known. Passing NULL for string
+ yields a return value of 0. */
+int
+gcry_cipher_mode_from_oid (const char *string)
+{
+ gcry_cipher_oid_spec_t oid_spec;
+ int ret = 0, mode = 0;
+
+ if (!string)
+ return 0;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ ret = search_oid (string, NULL, &oid_spec);
+ if (ret)
+ mode = oid_spec.mode;
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return mode;
+}
+
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+static const char *
+cipher_algo_to_string (int algorithm)
+{
+ gcry_module_t cipher;
+ const char *name;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+ if (cipher)
+ {
+ name = ((gcry_cipher_spec_t *) cipher->spec)->name;
+ _gcry_module_release (cipher);
+ }
+ else
+ name = "?";
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return name;
+}
+
+/* Map the cipher algorithm identifier ALGORITHM to a string
+ representing this algorithm. This string is the default name as
+ used by Libgcrypt. An pointer to an empty string is returned for
+ an unknown algorithm. NULL is never returned. */
+const char *
+gcry_cipher_algo_name (int algorithm)
+{
+ return cipher_algo_to_string (algorithm);
+}
+
+
+/* Flag the cipher algorithm with the identifier ALGORITHM as
+ disabled. There is no error return, the function does nothing for
+ unknown algorithms. Disabled algorithms are vitually not available
+ in Libgcrypt. */
+static void
+disable_cipher_algo (int algorithm)
+{
+ gcry_module_t cipher;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+ if (cipher)
+ {
+ if (! (cipher->flags & FLAG_MODULE_DISABLED))
+ cipher->flags |= FLAG_MODULE_DISABLED;
+ _gcry_module_release (cipher);
+ }
+ ath_mutex_unlock (&ciphers_registered_lock);
+}
+
+
+/* Return 0 if the cipher algorithm with identifier ALGORITHM is
+ available. Returns a basic error code value if it is not
+ available. */
+static gcry_err_code_t
+check_cipher_algo (int algorithm)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t cipher;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+ if (cipher)
+ {
+ if (cipher->flags & FLAG_MODULE_DISABLED)
+ err = GPG_ERR_CIPHER_ALGO;
+ _gcry_module_release (cipher);
+ }
+ else
+ err = GPG_ERR_CIPHER_ALGO;
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return err;
+}
+
+
+/* Return the standard length of the key for the cipher algorithm with
+ the identifier ALGORITHM. This function expects a valid algorithm
+ and will abort if the algorithm is not available or the length of
+ the key is not known. */
+static unsigned int
+cipher_get_keylen (int algorithm)
+{
+ gcry_module_t cipher;
+ unsigned len = 0;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+ if (cipher)
+ {
+ len = ((gcry_cipher_spec_t *) cipher->spec)->keylen;
+ if (!len)
+ log_bug ("cipher %d w/o key length\n", algorithm);
+ _gcry_module_release (cipher);
+ }
+ else
+ log_bug ("cipher %d not found\n", algorithm);
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return len;
+}
+
+/* Return the block length of the cipher algorithm with the identifier
+ ALGORITHM. This function expects a valid algorithm and will abort
+ if the algorithm is not available or the length of the key is not
+ known. */
+static unsigned int
+cipher_get_blocksize (int algorithm)
+{
+ gcry_module_t cipher;
+ unsigned len = 0;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
+ if (cipher)
+ {
+ len = ((gcry_cipher_spec_t *) cipher->spec)->blocksize;
+ if (! len)
+ log_bug ("cipher %d w/o blocksize\n", algorithm);
+ _gcry_module_release (cipher);
+ }
+ else
+ log_bug ("cipher %d not found\n", algorithm);
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return len;
+}
+
+
+/*
+ Open a cipher handle for use with cipher algorithm ALGORITHM, using
+ the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
+ handle in HANDLE. Put NULL into HANDLE and return an error code if
+ something goes wrong. FLAGS may be used to modify the
+ operation. The defined flags are:
+
+ GCRY_CIPHER_SECURE: allocate all internal buffers in secure memory.
+ GCRY_CIPHER_ENABLE_SYNC: Enable the sync operation as used in OpenPGP.
+ GCRY_CIPHER_CBC_CTS: Enable CTS mode.
+ GCRY_CIPHER_CBC_MAC: Enable MAC mode.
+
+ Values for these flags may be combined using OR.
+ */
+gcry_error_t
+gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ int secure = (flags & GCRY_CIPHER_SECURE);
+ gcry_cipher_spec_t *cipher = NULL;
+ cipher_extra_spec_t *extraspec = NULL;
+ gcry_module_t module = NULL;
+ gcry_cipher_hd_t h = NULL;
+ gcry_err_code_t err = 0;
+
+ /* If the application missed to call the random poll function, we do
+ it here to ensure that it is used once in a while. */
+ _gcry_fast_random_poll ();
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ /* Fetch the according module and check whether the cipher is marked
+ available for use. */
+ ath_mutex_lock (&ciphers_registered_lock);
+ module = _gcry_module_lookup_id (ciphers_registered, algo);
+ if (module)
+ {
+ /* Found module. */
+
+ if (module->flags & FLAG_MODULE_DISABLED)
+ {
+ /* Not available for use. */
+ err = GPG_ERR_CIPHER_ALGO;
+ }
+ else
+ {
+ cipher = (gcry_cipher_spec_t *) module->spec;
+ extraspec = module->extraspec;
+ }
+ }
+ else
+ err = GPG_ERR_CIPHER_ALGO;
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ /* check flags */
+ if ((! err)
+ && ((flags & ~(0
+ | GCRY_CIPHER_SECURE
+ | GCRY_CIPHER_ENABLE_SYNC
+ | GCRY_CIPHER_CBC_CTS
+ | GCRY_CIPHER_CBC_MAC))
+ || (flags & GCRY_CIPHER_CBC_CTS & GCRY_CIPHER_CBC_MAC)))
+ err = GPG_ERR_CIPHER_ALGO;
+
+ /* check that a valid mode has been requested */
+ if (! err)
+ switch (mode)
+ {
+ case GCRY_CIPHER_MODE_ECB:
+ case GCRY_CIPHER_MODE_CBC:
+ case GCRY_CIPHER_MODE_CFB:
+ case GCRY_CIPHER_MODE_OFB:
+ case GCRY_CIPHER_MODE_CTR:
+ case GCRY_CIPHER_MODE_AESWRAP:
+ if ((cipher->encrypt == dummy_encrypt_block)
+ || (cipher->decrypt == dummy_decrypt_block))
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ if ((cipher->stencrypt == dummy_encrypt_stream)
+ || (cipher->stdecrypt == dummy_decrypt_stream))
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ /* This mode may be used for debugging. It copies the main
+ text verbatim to the ciphertext. We do not allow this in
+ fips mode or if no debug flag has been set. */
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ err = GPG_ERR_INV_CIPHER_MODE;
+ break;
+
+ default:
+ err = GPG_ERR_INV_CIPHER_MODE;
+ }
+
+ /* Perform selftest here and mark this with a flag in cipher_table?
+ No, we should not do this as it takes too long. Further it does
+ not make sense to exclude algorithms with failing selftests at
+ runtime: If a selftest fails there is something seriously wrong
+ with the system and thus we better die immediately. */
+
+ if (! err)
+ {
+ size_t size = (sizeof (*h)
+ + 2 * cipher->contextsize
+ - sizeof (cipher_context_alignment_t)
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ + 15 /* Space for leading alignment gap. */
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+ );
+
+ if (secure)
+ h = gcry_calloc_secure (1, size);
+ else
+ h = gcry_calloc (1, size);
+
+ if (! h)
+ err = gpg_err_code_from_syserror ();
+ else
+ {
+ size_t off = 0;
+
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+ if ( ((unsigned long)h & 0x0f) )
+ {
+ /* The malloced block is not aligned on a 16 byte
+ boundary. Correct for this. */
+ off = 16 - ((unsigned long)h & 0x0f);
+ h = (void*)((char*)h + off);
+ }
+#endif /*NEED_16BYTE_ALIGNED_CONTEXT*/
+
+ h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+ h->actual_handle_size = size - off;
+ h->handle_offset = off;
+ h->cipher = cipher;
+ h->extraspec = extraspec;
+ h->module = module;
+ h->algo = algo;
+ h->mode = mode;
+ h->flags = flags;
+
+ /* Setup bulk encryption routines. */
+ switch (algo)
+ {
+#ifdef USE_AES
+ case GCRY_CIPHER_AES128:
+ case GCRY_CIPHER_AES192:
+ case GCRY_CIPHER_AES256:
+ h->bulk.cfb_enc = _gcry_aes_cfb_enc;
+ h->bulk.cfb_dec = _gcry_aes_cfb_dec;
+ h->bulk.cbc_enc = _gcry_aes_cbc_enc;
+ h->bulk.cbc_dec = _gcry_aes_cbc_dec;
+ h->bulk.ctr_enc = _gcry_aes_ctr_enc;
+ break;
+#endif /*USE_AES*/
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Done. */
+
+ if (err)
+ {
+ if (module)
+ {
+ /* Release module. */
+ ath_mutex_lock (&ciphers_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&ciphers_registered_lock);
+ }
+ }
+
+ *handle = err ? NULL : h;
+
+ return gcry_error (err);
+}
+
+
+/* Release all resources associated with the cipher handle H. H may be
+ NULL in which case this is a no-operation. */
+void
+gcry_cipher_close (gcry_cipher_hd_t h)
+{
+ size_t off;
+
+ if (!h)
+ return;
+
+ if ((h->magic != CTX_MAGIC_SECURE)
+ && (h->magic != CTX_MAGIC_NORMAL))
+ _gcry_fatal_error(GPG_ERR_INTERNAL,
+ "gcry_cipher_close: already closed/invalid handle");
+ else
+ h->magic = 0;
+
+ /* Release module. */
+ ath_mutex_lock (&ciphers_registered_lock);
+ _gcry_module_release (h->module);
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ /* We always want to wipe out the memory even when the context has
+ been allocated in secure memory. The user might have disabled
+ secure memory or is using his own implementation which does not
+ do the wiping. To accomplish this we need to keep track of the
+ actual size of this structure because we have no way to known
+ how large the allocated area was when using a standard malloc. */
+ off = h->handle_offset;
+ wipememory (h, h->actual_handle_size);
+
+ gcry_free ((char*)h - off);
+}
+
+
+/* Set the key to be used for the encryption context C to KEY with
+ length KEYLEN. The length should match the required length. */
+static gcry_error_t
+cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen)
+{
+ gcry_err_code_t ret;
+
+ ret = (*c->cipher->setkey) (&c->context.c, key, keylen);
+ if (!ret)
+ {
+ /* Duplicate initial context. */
+ memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
+ (void *) &c->context.c,
+ c->cipher->contextsize);
+ c->marks.key = 1;
+ }
+ else
+ c->marks.key = 0;
+
+ return gcry_error (ret);
+}
+
+
+/* Set the IV to be used for the encryption context C to IV with
+ length IVLEN. The length should match the required length. */
+static void
+cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
+{
+ memset (c->u_iv.iv, 0, c->cipher->blocksize);
+ if (iv)
+ {
+ if (ivlen != c->cipher->blocksize)
+ {
+ log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
+ ivlen, (unsigned int)c->cipher->blocksize);
+ fips_signal_error ("IV length does not match blocklength");
+ }
+ if (ivlen > c->cipher->blocksize)
+ ivlen = c->cipher->blocksize;
+ memcpy (c->u_iv.iv, iv, ivlen);
+ c->marks.iv = 1;
+ }
+ else
+ c->marks.iv = 0;
+ c->unused = 0;
+}
+
+
+/* Reset the cipher context to the initial context. This is basically
+ the same as an release followed by a new. */
+static void
+cipher_reset (gcry_cipher_hd_t c)
+{
+ memcpy (&c->context.c,
+ (char *) &c->context.c + c->cipher->contextsize,
+ c->cipher->contextsize);
+ memset (&c->marks, 0, sizeof c->marks);
+ memset (c->u_iv.iv, 0, c->cipher->blocksize);
+ memset (c->lastiv, 0, c->cipher->blocksize);
+ memset (c->u_ctr.ctr, 0, c->cipher->blocksize);
+}
+
+
+\f
+static gcry_err_code_t
+do_ecb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned int blocksize = c->cipher->blocksize;
+ unsigned int n, nblocks;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+
+ nblocks = inbuflen / c->cipher->blocksize;
+
+ for (n=0; n < nblocks; n++ )
+ {
+ c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf);
+ inbuf += blocksize;
+ outbuf += blocksize;
+ }
+ return 0;
+}
+
+static gcry_err_code_t
+do_ecb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned int blocksize = c->cipher->blocksize;
+ unsigned int n, nblocks;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ if ((inbuflen % blocksize))
+ return GPG_ERR_INV_LENGTH;
+ nblocks = inbuflen / c->cipher->blocksize;
+
+ for (n=0; n < nblocks; n++ )
+ {
+ c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf );
+ inbuf += blocksize;
+ outbuf += blocksize;
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_cbc_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned int n;
+ unsigned char *ivp;
+ int i;
+ size_t blocksize = c->cipher->blocksize;
+ unsigned nblocks = inbuflen / blocksize;
+
+ if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ((inbuflen % c->cipher->blocksize)
+ && !(inbuflen > c->cipher->blocksize
+ && (c->flags & GCRY_CIPHER_CBC_CTS)))
+ return GPG_ERR_INV_LENGTH;
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ {
+ if ((inbuflen % blocksize) == 0)
+ nblocks--;
+ }
+
+ if (c->bulk.cbc_enc)
+ {
+ c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
+ (c->flags & GCRY_CIPHER_CBC_MAC));
+ inbuf += nblocks * blocksize;
+ if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+ outbuf += nblocks * blocksize;
+ }
+ else
+ {
+ for (n=0; n < nblocks; n++ )
+ {
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ outbuf[i] = inbuf[i] ^ *ivp++;
+ c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
+ memcpy (c->u_iv.iv, outbuf, blocksize );
+ inbuf += blocksize;
+ if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+ outbuf += blocksize;
+ }
+ }
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ {
+ /* We have to be careful here, since outbuf might be equal to
+ inbuf. */
+ int restbytes;
+ unsigned char b;
+
+ if ((inbuflen % blocksize) == 0)
+ restbytes = blocksize;
+ else
+ restbytes = inbuflen % blocksize;
+
+ outbuf -= blocksize;
+ for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
+ {
+ b = inbuf[i];
+ outbuf[blocksize + i] = outbuf[i];
+ outbuf[i] = b ^ *ivp++;
+ }
+ for (; i < blocksize; i++)
+ outbuf[i] = 0 ^ *ivp++;
+
+ c->cipher->encrypt (&c->context.c, outbuf, outbuf);
+ memcpy (c->u_iv.iv, outbuf, blocksize);
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_cbc_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned int n;
+ unsigned char *ivp;
+ int i;
+ size_t blocksize = c->cipher->blocksize;
+ unsigned int nblocks = inbuflen / blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ((inbuflen % c->cipher->blocksize)
+ && !(inbuflen > c->cipher->blocksize
+ && (c->flags & GCRY_CIPHER_CBC_CTS)))
+ return GPG_ERR_INV_LENGTH;
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ {
+ nblocks--;
+ if ((inbuflen % blocksize) == 0)
+ nblocks--;
+ memcpy (c->lastiv, c->u_iv.iv, blocksize);
+ }
+
+ if (c->bulk.cbc_dec)
+ {
+ c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ inbuf += nblocks * blocksize;
+ outbuf += nblocks * blocksize;
+ }
+ else
+ {
+ for (n=0; n < nblocks; n++ )
+ {
+ /* Because outbuf and inbuf might be the same, we have to
+ * save the original ciphertext block. We use LASTIV for
+ * this here because it is not used otherwise. */
+ memcpy (c->lastiv, inbuf, blocksize);
+ c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ outbuf[i] ^= *ivp++;
+ memcpy(c->u_iv.iv, c->lastiv, blocksize );
+ inbuf += c->cipher->blocksize;
+ outbuf += c->cipher->blocksize;
+ }
+ }
+
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ {
+ int restbytes;
+
+ if ((inbuflen % blocksize) == 0)
+ restbytes = blocksize;
+ else
+ restbytes = inbuflen % blocksize;
+
+ memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */
+ memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
+
+ c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
+ for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
+ outbuf[i] ^= *ivp++;
+
+ memcpy(outbuf + blocksize, outbuf, restbytes);
+ for(i=restbytes; i < blocksize; i++)
+ c->u_iv.iv[i] = outbuf[i];
+ c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv);
+ for(ivp=c->lastiv,i=0; i < blocksize; i++ )
+ outbuf[i] ^= *ivp++;
+ /* c->lastiv is now really lastlastiv, does this matter? */
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_cfb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned char *ivp;
+ size_t blocksize = c->cipher->blocksize;
+ size_t blocksize_x_2 = blocksize + blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV and store input into IV. */
+ for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
+ inbuflen;
+ inbuflen--, c->unused-- )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ return 0;
+ }
+
+ if ( c->unused )
+ {
+ /* XOR the input with the IV and store input into IV */
+ inbuflen -= c->unused;
+ for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ }
+
+ /* Now we can process complete blocks. We use a loop as long as we
+ have at least 2 blocks and use conditions for the rest. This
+ also allows to use a bulk encryption function if available. */
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
+ {
+ unsigned int nblocks = inbuflen / blocksize;
+ c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ outbuf += nblocks * blocksize;
+ inbuf += nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
+ }
+ else
+ {
+ while ( inbuflen >= blocksize_x_2 )
+ {
+ int i;
+ /* Encrypt the IV. */
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ /* XOR the input with the IV and store input into IV. */
+ for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ inbuflen -= blocksize;
+ }
+ }
+
+ if ( inbuflen >= blocksize )
+ {
+ int i;
+ /* Save the current IV and then encrypt the IV. */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ /* XOR the input with the IV and store input into IV */
+ for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ inbuflen -= blocksize;
+ }
+ if ( inbuflen )
+ {
+ /* Save the current IV and then encrypt the IV. */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ c->unused = blocksize;
+ /* Apply the XOR. */
+ c->unused -= inbuflen;
+ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ }
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_cfb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned char *ivp;
+ unsigned long temp;
+ int i;
+ size_t blocksize = c->cipher->blocksize;
+ size_t blocksize_x_2 = blocksize + blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if (inbuflen <= c->unused)
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV and store input into IV. */
+ for (ivp=c->u_iv.iv+blocksize - c->unused;
+ inbuflen;
+ inbuflen--, c->unused--)
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ return 0;
+ }
+
+ if (c->unused)
+ {
+ /* XOR the input with the IV and store input into IV. */
+ inbuflen -= c->unused;
+ for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ }
+
+ /* Now we can process complete blocks. We use a loop as long as we
+ have at least 2 blocks and use conditions for the rest. This
+ also allows to use a bulk encryption function if available. */
+ if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
+ {
+ unsigned int nblocks = inbuflen / blocksize;
+ c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ outbuf += nblocks * blocksize;
+ inbuf += nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
+ }
+ else
+ {
+ while (inbuflen >= blocksize_x_2 )
+ {
+ /* Encrypt the IV. */
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ /* XOR the input with the IV and store input into IV. */
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ inbuflen -= blocksize;
+ }
+ }
+
+ if (inbuflen >= blocksize )
+ {
+ /* Save the current IV and then encrypt the IV. */
+ memcpy ( c->lastiv, c->u_iv.iv, blocksize);
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ /* XOR the input with the IV and store input into IV */
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ inbuflen -= blocksize;
+ }
+
+ if (inbuflen)
+ {
+ /* Save the current IV and then encrypt the IV. */
+ memcpy ( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ c->unused = blocksize;
+ /* Apply the XOR. */
+ c->unused -= inbuflen;
+ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ }
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_ofb_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned char *ivp;
+ size_t blocksize = c->cipher->blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if ( inbuflen <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV */
+ for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
+ inbuflen;
+ inbuflen--, c->unused-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ return 0;
+ }
+
+ if( c->unused )
+ {
+ inbuflen -= c->unused;
+ for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ }
+
+ /* Now we can process complete blocks. */
+ while ( inbuflen >= blocksize )
+ {
+ int i;
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ inbuflen -= blocksize;
+ }
+ if ( inbuflen )
+ { /* process the remaining bytes */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ c->unused = blocksize;
+ c->unused -= inbuflen;
+ for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ }
+ return 0;
+}
+
+static gcry_err_code_t
+do_ofb_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned char *ivp;
+ size_t blocksize = c->cipher->blocksize;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ if( inbuflen <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--)
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ return 0;
+ }
+
+ if ( c->unused )
+ {
+ inbuflen -= c->unused;
+ for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ }
+
+ /* Now we can process complete blocks. */
+ while ( inbuflen >= blocksize )
+ {
+ int i;
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ inbuflen -= blocksize;
+ }
+ if ( inbuflen )
+ { /* Process the remaining bytes. */
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->u_iv.iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+ c->unused = blocksize;
+ c->unused -= inbuflen;
+ for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ }
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_ctr_encrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ unsigned int n;
+ int i;
+ unsigned int blocksize = c->cipher->blocksize;
+ unsigned int nblocks;
+
+ if (outbuflen < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+
+ /* First process a left over encrypted counter. */
+ if (c->unused)
+ {
+ gcry_assert (c->unused < blocksize);
+ i = blocksize - c->unused;
+ for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++)
+ {
+ /* XOR input with encrypted counter and store in output. */
+ outbuf[n] = inbuf[n] ^ c->lastiv[i];
+ }
+ inbuf += n;
+ outbuf += n;
+ inbuflen -= n;
+ }
+
+
+ /* Use a bulk method if available. */
+ nblocks = inbuflen / blocksize;
+ if (nblocks && c->bulk.ctr_enc)
+ {
+ c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+ inbuf += nblocks * blocksize;
+ outbuf += nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
+ }
+
+ /* If we don't have a bulk method use the standard method. We also
+ use this method for the a remaining partial block. */
+ if (inbuflen)
+ {
+ unsigned char tmp[MAX_BLOCKSIZE];
+
+ for (n=0; n < inbuflen; n++)
+ {
+ if ((n % blocksize) == 0)
+ {
+ c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr);
+
+ for (i = blocksize; i > 0; i--)
+ {
+ c->u_ctr.ctr[i-1]++;
+ if (c->u_ctr.ctr[i-1] != 0)
+ break;
+ }
+ }
+
+ /* XOR input with encrypted counter and store in output. */
+ outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
+ }
+
+ /* Save the unused bytes of the counter. */
+ n %= blocksize;
+ c->unused = (blocksize - n) % blocksize;
+ if (c->unused)
+ memcpy (c->lastiv+n, tmp+n, c->unused);
+
+ wipememory (tmp, sizeof tmp);
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t
+do_ctr_decrypt (gcry_cipher_hd_t c,
+ unsigned char *outbuf, unsigned int outbuflen,
+ const unsigned char *inbuf, unsigned int inbuflen)
+{
+ return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+/* Perform the AES-Wrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+static gcry_err_code_t
+do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen )
+{
+ int j, x;
+ unsigned int n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->cipher->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data plus one
+ additional block. */
+ if (outbuflen < inbuflen + 8)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least two 64 bit blocks. */
+ if (n < 2)
+ return GPG_ERR_INV_ARG;
+
+ r = outbuf;
+ a = outbuf; /* We store A directly in OUTBUF. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
+
+ /* If an IV has been set we use that IV as the Alternative Initial
+ Value; if it has not been set we use the standard value. */
+ if (c->marks.iv)
+ memcpy (a, c->u_iv.iv, 8);
+ else
+ memset (a, 0xa6, 8);
+
+ /* Copy the inbuf to the outbuf. */
+ memmove (r+8, inbuf, inbuflen);
+
+ memset (t, 0, sizeof t); /* t := 0. */
+
+ for (j = 0; j <= 5; j++)
+ {
+ for (i = 1; i <= n; i++)
+ {
+ /* B := AES_k( A | R[i] ) */
+ memcpy (b, a, 8);
+ memcpy (b+8, r+i*8, 8);
+ c->cipher->encrypt (&c->context.c, b, b);
+ /* t := t + 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]++;
+ if (t[x])
+ break;
+ }
+ /* A := MSB_64(B) ^ t */
+ for (x=0; x < 8; x++)
+ a[x] = b[x] ^ t[x];
+ /* R[i] := LSB_64(B) */
+ memcpy (r+i*8, b+8, 8);
+ }
+ }
+
+ return 0;
+}
+
+/* Perform the AES-Unwrap algorithm as specified by RFC3394. We
+ implement this as a mode usable with any cipher algorithm of
+ blocksize 128. */
+static gcry_err_code_t
+do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
+{
+ int j, x;
+ unsigned int n, i;
+ unsigned char *r, *a, *b;
+ unsigned char t[8];
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+ /* We require a cipher with a 128 bit block length. */
+ if (c->cipher->blocksize != 16)
+ return GPG_ERR_INV_LENGTH;
+
+ /* The output buffer must be able to hold the input data minus one
+ additional block. Fixme: The caller has more restrictive checks
+ - we may want to fix them for this mode. */
+ if (outbuflen + 8 < inbuflen)
+ return GPG_ERR_BUFFER_TOO_SHORT;
+ /* Input data must be multiple of 64 bits. */
+ if (inbuflen % 8)
+ return GPG_ERR_INV_ARG;
+
+ n = inbuflen / 8;
+
+ /* We need at least three 64 bit blocks. */
+ if (n < 3)
+ return GPG_ERR_INV_ARG;
+
+ r = outbuf;
+ a = c->lastiv; /* We use c->LASTIV as buffer for A. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
+
+ /* Copy the inbuf to the outbuf and save A. */
+ memcpy (a, inbuf, 8);
+ memmove (r, inbuf+8, inbuflen-8);
+ n--; /* Reduce to actual number of data blocks. */
+
+ /* t := 6 * n */
+ i = n * 6; /* The range is valid because: n = inbuflen / 8 - 1. */
+ for (x=0; x < 8 && x < sizeof (i); x++)
+ t[7-x] = i >> (8*x);
+ for (; x < 8; x++)
+ t[7-x] = 0;
+
+ for (j = 5; j >= 0; j--)
+ {
+ for (i = n; i >= 1; i--)
+ {
+ /* B := AES_k^1( (A ^ t)| R[i] ) */
+ for (x = 0; x < 8; x++)
+ b[x] = a[x] ^ t[x];
+ memcpy (b+8, r+(i-1)*8, 8);
+ c->cipher->decrypt (&c->context.c, b, b);
+ /* t := t - 1 */
+ for (x = 7; x >= 0; x--)
+ {
+ t[x]--;
+ if (t[x] != 0xff)
+ break;
+ }
+ /* A := MSB_64(B) */
+ memcpy (a, b, 8);
+ /* R[i] := LSB_64(B) */
+ memcpy (r+(i-1)*8, b+8, 8);
+ }
+ }
+
+ /* If an IV has been set we compare against this Alternative Initial
+ Value; if it has not been set we compare against the standard IV. */
+ if (c->marks.iv)
+ j = memcmp (a, c->u_iv.iv, 8);
+ else
+ {
+ for (j=0, x=0; x < 8; x++)
+ if (a[x] != 0xa6)
+ {
+ j=1;
+ break;
+ }
+ }
+ return j? GPG_ERR_CHECKSUM : 0;
+}
+
+
+/****************
+ * Encrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some constraints apply to INBUFLEN.
+ */
+static gcry_err_code_t
+cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
+{
+ gcry_err_code_t rc;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_ECB:
+ rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CBC:
+ rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CFB:
+ rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_OFB:
+ rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CTR:
+ rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_AESWRAP:
+ rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ c->cipher->stencrypt (&c->context.c,
+ outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+ rc = 0;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+
+ return rc;
+}
+
+
+/****************
+ * Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has
+ * been requested.
+ */
+gcry_error_t
+gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ gcry_err_code_t err;
+
+ if (!in) /* Caller requested in-place encryption. */
+ err = cipher_encrypt (h, out, outsize, out, outsize);
+ else
+ err = cipher_encrypt (h, out, outsize, in, inlen);
+
+ /* Failsafe: Make sure that the plaintext will never make it into
+ OUT if the encryption returned an error. */
+ if (err && out)
+ memset (out, 0x42, outsize);
+
+ return gcry_error (err);
+}
+
+
+
+/****************
+ * Decrypt INBUF to OUTBUF with the mode selected at open.
+ * inbuf and outbuf may overlap or be the same.
+ * Depending on the mode some some contraints apply to INBUFLEN.
+ */
+static gcry_err_code_t
+cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
+ const byte *inbuf, unsigned int inbuflen)
+{
+ gcry_err_code_t rc;
+
+ switch (c->mode)
+ {
+ case GCRY_CIPHER_MODE_ECB:
+ rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CBC:
+ rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CFB:
+ rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_OFB:
+ rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_CTR:
+ rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_AESWRAP:
+ rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ break;
+
+ case GCRY_CIPHER_MODE_STREAM:
+ c->cipher->stdecrypt (&c->context.c,
+ outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+ rc = 0;
+ break;
+
+ case GCRY_CIPHER_MODE_NONE:
+ if (fips_mode () || !_gcry_get_debug_flag (0))
+ {
+ fips_signal_error ("cipher mode NONE used");
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ }
+ else
+ {
+ if (inbuf != outbuf)
+ memmove (outbuf, inbuf, inbuflen);
+ rc = 0;
+ }
+ break;
+
+ default:
+ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
+ rc = GPG_ERR_INV_CIPHER_MODE;
+ break;
+ }
+
+ return rc;
+}
+
+
+gcry_error_t
+gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ gcry_err_code_t err;
+
+ if (!in) /* Caller requested in-place encryption. */
+ err = cipher_decrypt (h, out, outsize, out, outsize);
+ else
+ err = cipher_decrypt (h, out, outsize, in, inlen);
+
+ return gcry_error (err);
+}
+
+
+
+/****************
+ * Used for PGP's somewhat strange CFB mode. Only works if
+ * the corresponding flag is set.
+ */
+static void
+cipher_sync (gcry_cipher_hd_t c)
+{
+ if ((c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused)
+ {
+ memmove (c->u_iv.iv + c->unused,
+ c->u_iv.iv, c->cipher->blocksize - c->unused);
+ memcpy (c->u_iv.iv,
+ c->lastiv + c->cipher->blocksize - c->unused, c->unused);
+ c->unused = 0;
+ }
+}
+
+
+gcry_error_t
+_gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+ return cipher_setkey (hd, (void*)key, keylen);
+}
+
+
+gcry_error_t
+_gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+ cipher_setiv (hd, iv, ivlen);
+ return 0;
+}
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero
+ block. */
+gpg_error_t
+_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+ if (ctr && ctrlen == hd->cipher->blocksize)
+ {
+ memcpy (hd->u_ctr.ctr, ctr, hd->cipher->blocksize);
+ hd->unused = 0;
+ }
+ else if (!ctr || !ctrlen)
+ {
+ memset (hd->u_ctr.ctr, 0, hd->cipher->blocksize);
+ hd->unused = 0;
+ }
+ else
+ return gpg_error (GPG_ERR_INV_ARG);
+ return 0;
+}
+
+
+gcry_error_t
+gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+ switch (cmd)
+ {
+ case GCRYCTL_SET_KEY: /* Deprecated; use gcry_cipher_setkey. */
+ rc = cipher_setkey( h, buffer, buflen );
+ break;
+
+ case GCRYCTL_SET_IV: /* Deprecated; use gcry_cipher_setiv. */
+ cipher_setiv( h, buffer, buflen );
+ break;
+
+ case GCRYCTL_RESET:
+ cipher_reset (h);
+ break;
+
+ case GCRYCTL_CFB_SYNC:
+ cipher_sync( h );
+ break;
+
+ case GCRYCTL_SET_CBC_CTS:
+ if (buflen)
+ if (h->flags & GCRY_CIPHER_CBC_MAC)
+ rc = GPG_ERR_INV_FLAG;
+ else
+ h->flags |= GCRY_CIPHER_CBC_CTS;
+ else
+ h->flags &= ~GCRY_CIPHER_CBC_CTS;
+ break;
+
+ case GCRYCTL_SET_CBC_MAC:
+ if (buflen)
+ if (h->flags & GCRY_CIPHER_CBC_CTS)
+ rc = GPG_ERR_INV_FLAG;
+ else
+ h->flags |= GCRY_CIPHER_CBC_MAC;
+ else
+ h->flags &= ~GCRY_CIPHER_CBC_MAC;
+ break;
+
+ case GCRYCTL_DISABLE_ALGO:
+ /* This command expects NULL for H and BUFFER to point to an
+ integer with the algo number. */
+ if( h || !buffer || buflen != sizeof(int) )
+ return gcry_error (GPG_ERR_CIPHER_ALGO);
+ disable_cipher_algo( *(int*)buffer );
+ break;
+
+ case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr. */
+ rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen));
+ break;
+
+ case 61: /* Disable weak key detection (private). */
+ if (h->extraspec->set_extra_info)
+ rc = h->extraspec->set_extra_info
+ (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
+ else
+ rc = GPG_ERR_NOT_SUPPORTED;
+ break;
+
+ case 62: /* Return current input vector (private). */
+ /* This is the input block as used in CFB and OFB mode which has
+ initially been set as IV. The returned format is:
+ 1 byte Actual length of the block in bytes.
+ n byte The block.
+ If the provided buffer is too short, an error is returned. */
+ if (buflen < (1 + h->cipher->blocksize))
+ rc = GPG_ERR_TOO_SHORT;
+ else
+ {
+ unsigned char *ivp;
+ unsigned char *dst = buffer;
+ int n = h->unused;
+
+ if (!n)
+ n = h->cipher->blocksize;
+ gcry_assert (n <= h->cipher->blocksize);
+ *dst++ = n;
+ ivp = h->u_iv.iv + h->cipher->blocksize - n;
+ while (n--)
+ *dst++ = *ivp++;
+ }
+ break;
+
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (rc);
+}
+
+
+/* Return information about the cipher handle H. CMD is the kind of
+ information requested. BUFFER and NBYTES are reserved for now.
+
+ There are no values for CMD yet defined.
+
+ The function always returns GPG_ERR_INV_OP.
+
+ */
+gcry_error_t
+gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ (void)h;
+ (void)buffer;
+ (void)nbytes;
+
+ switch (cmd)
+ {
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+/* Return information about the given cipher algorithm ALGO.
+
+ WHAT select the kind of information returned:
+
+ GCRYCTL_GET_KEYLEN:
+ Return the length of the key. If the algorithm ALGO
+ supports multiple key lengths, the maximum supported key length
+ is returned. The key length is returned as number of octets.
+ BUFFER and NBYTES must be zero.
+
+ GCRYCTL_GET_BLKLEN:
+ Return the blocklength of the algorithm ALGO counted in octets.
+ BUFFER and NBYTES must be zero.
+
+ GCRYCTL_TEST_ALGO:
+ Returns 0 if the specified algorithm ALGO is available for use.
+ BUFFER and NBYTES must be zero.
+
+ Note: Because this function is in most cases used to return an
+ integer value, we can make it easier for the caller to just look at
+ the return value. The caller will in all cases consult the value
+ and thereby detecting whether a error occurred or not (i.e. while
+ checking the block size)
+ */
+gcry_error_t
+gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ unsigned int ui;
+
+ switch (what)
+ {
+ case GCRYCTL_GET_KEYLEN:
+ if (buffer || (! nbytes))
+ err = GPG_ERR_CIPHER_ALGO;
+ else
+ {
+ ui = cipher_get_keylen (algo);
+ if ((ui > 0) && (ui <= 512))
+ *nbytes = (size_t) ui / 8;
+ else
+ /* The only reason is an invalid algo or a strange
+ blocksize. */
+ err = GPG_ERR_CIPHER_ALGO;
+ }
+ break;
+
+ case GCRYCTL_GET_BLKLEN:
+ if (buffer || (! nbytes))
+ err = GPG_ERR_CIPHER_ALGO;
+ else
+ {
+ ui = cipher_get_blocksize (algo);
+ if ((ui > 0) && (ui < 10000))
+ *nbytes = ui;
+ else
+ /* The only reason is an invalid algo or a strange
+ blocksize. */
+ err = GPG_ERR_CIPHER_ALGO;
+ }
+ break;
+
+ case GCRYCTL_TEST_ALGO:
+ if (buffer || nbytes)
+ err = GPG_ERR_INV_ARG;
+ else
+ err = check_cipher_algo (algo);
+ break;
+
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* This function returns length of the key for algorithm ALGO. If the
+ algorithm supports multiple key lengths, the maximum supported key
+ length is returned. On error 0 is returned. The key length is
+ returned as number of octets.
+
+ This is a convenience functions which should be preferred over
+ gcry_cipher_algo_info because it allows for proper type
+ checking. */
+size_t
+gcry_cipher_get_algo_keylen (int algo)
+{
+ size_t n;
+
+ if (gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
+ n = 0;
+ return n;
+}
+
+/* This functions returns the blocklength of the algorithm ALGO
+ counted in octets. On error 0 is returned.
+
+ This is a convenience functions which should be preferred over
+ gcry_cipher_algo_info because it allows for proper type
+ checking. */
+size_t
+gcry_cipher_get_algo_blklen (int algo)
+{
+ size_t n;
+
+ if (gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
+ n = 0;
+ return n;
+}
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_cipher_init (void)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ return err;
+}
+
+/* Get a list consisting of the IDs of the loaded cipher modules. If
+ LIST is zero, write the number of loaded cipher modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t
+gcry_cipher_list (int *list, int *list_length)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ err = _gcry_module_list (ciphers_registered, list, list_length);
+ ath_mutex_unlock (&ciphers_registered_lock);
+
+ return err;
+}
+
+
+/* Run the selftests for cipher algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_module_t module = NULL;
+ cipher_extra_spec_t *extraspec = NULL;
+ gcry_err_code_t ec = 0;
+
+ REGISTER_DEFAULT_CIPHERS;
+
+ ath_mutex_lock (&ciphers_registered_lock);
+ module = _gcry_module_lookup_id (ciphers_registered, algo);
+ if (module && !(module->flags & FLAG_MODULE_DISABLED))
+ extraspec = module->extraspec;
+ ath_mutex_unlock (&ciphers_registered_lock);
+ if (extraspec && extraspec->selftest)
+ ec = extraspec->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_CIPHER_ALGO;
+ if (report)
+ report ("cipher", algo, "module",
+ module && !(module->flags & FLAG_MODULE_DISABLED)?
+ "no selftest available" :
+ module? "algorithm disabled" : "algorithm not found");
+ }
+
+ if (module)
+ {
+ ath_mutex_lock (&ciphers_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&ciphers_registered_lock);
+ }
+ return gpg_error (ec);
+}
--- /dev/null
+/* crc.c - Cyclic redundancy checks.
+ * Copyright (C) 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+/* Table of CRCs of all 8-bit messages. Generated by running code
+ from RFC 1952 modified to print out the table. */
+static u32 crc32_table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+ 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+ 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+ 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+ 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+ 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+ 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+ 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+ 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+ 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+ 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+ 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+ 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+ 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+ 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+ 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+ 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+ 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+ 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+ 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+ 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+ 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+ * The following function was extracted from RFC 1952 by Simon
+ * Josefsson, for the Shishi project, and modified to be compatible
+ * with the modified CRC-32 used by RFC 1510, and subsequently
+ * modified for GNU Libgcrypt to allow it to be used for calculating
+ * both unmodified CRC-32 and modified CRC-32 values. Original
+ * copyright and notice from the document follows:
+ *
+ * Copyright (c) 1996 L. Peter Deutsch
+ *
+ * Permission is granted to copy and distribute this document for
+ * any purpose and without charge, including translations into
+ * other languages and incorporation into compilations, provided
+ * that the copyright notice and this notice are preserved, and
+ * that any substantive changes or deletions from the original are
+ * clearly marked.
+ *
+ * The copyright on RFCs, and consequently the function below, are
+ * supposedly also retroactively claimed by the Internet Society
+ * (according to rfc-editor@rfc-editor.org), with the following
+ * copyright notice:
+ *
+ * Copyright (C) The Internet Society. All Rights Reserved.
+ *
+ * This document and translations of it may be copied and furnished
+ * to others, and derivative works that comment on or otherwise
+ * explain it or assist in its implementation may be prepared,
+ * copied, published and distributed, in whole or in part, without
+ * restriction of any kind, provided that the above copyright
+ * notice and this paragraph are included on all such copies and
+ * derivative works. However, this document itself may not be
+ * modified in any way, such as by removing the copyright notice or
+ * references to the Internet Society or other Internet
+ * organizations, except as needed for the purpose of developing
+ * Internet standards in which case the procedures for copyrights
+ * defined in the Internet Standards process must be followed, or
+ * as required to translate it into languages other than English.
+ *
+ * The limited permissions granted above are perpetual and will not be
+ * revoked by the Internet Society or its successors or assigns.
+ *
+ * This document and the information contained herein is provided
+ * on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+ * ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
+ * OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
+ * PARTICULAR PURPOSE.
+ *
+ */
+static u32
+update_crc32 (u32 crc, const void *buf_arg, size_t len)
+{
+ const char *buf = buf_arg;
+ size_t n;
+
+ for (n = 0; n < len; n++)
+ crc = crc32_table[(crc ^ buf[n]) & 0xff] ^ (crc >> 8);
+
+ return crc;
+}
+
+typedef struct
+{
+ u32 CRC;
+ byte buf[4];
+}
+CRC_CONTEXT;
+
+/* CRC32 */
+
+static void
+crc32_init (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC = 0 ^ 0xffffffffL;
+}
+
+static void
+crc32_write (void *context, const void *inbuf, size_t inlen)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ if (!inbuf)
+ return;
+ ctx->CRC = update_crc32 (ctx->CRC, inbuf, inlen);
+}
+
+static byte *
+crc32_read (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ return ctx->buf;
+}
+
+static void
+crc32_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC ^= 0xffffffffL;
+ ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
+ ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
+ ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
+ ctx->buf[3] = (ctx->CRC ) & 0xFF;
+}
+
+/* CRC32 a'la RFC 1510 */
+static void
+crc32rfc1510_init (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC = 0;
+}
+
+static void
+crc32rfc1510_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->buf[0] = (ctx->CRC >> 24) & 0xFF;
+ ctx->buf[1] = (ctx->CRC >> 16) & 0xFF;
+ ctx->buf[2] = (ctx->CRC >> 8) & 0xFF;
+ ctx->buf[3] = (ctx->CRC ) & 0xFF;
+}
+
+/* CRC24 a'la RFC 2440 */
+/*
+ * The following CRC 24 routines are adapted from RFC 2440, which has
+ * the following copyright notice:
+ *
+ * Copyright (C) The Internet Society (1998). All Rights Reserved.
+ *
+ * This document and translations of it may be copied and furnished
+ * to others, and derivative works that comment on or otherwise
+ * explain it or assist in its implementation may be prepared,
+ * copied, published and distributed, in whole or in part, without
+ * restriction of any kind, provided that the above copyright notice
+ * and this paragraph are included on all such copies and derivative
+ * works. However, this document itself may not be modified in any
+ * way, such as by removing the copyright notice or references to
+ * the Internet Society or other Internet organizations, except as
+ * needed for the purpose of developing Internet standards in which
+ * case the procedures for copyrights defined in the Internet
+ * Standards process must be followed, or as required to translate
+ * it into languages other than English.
+ *
+ * The limited permissions granted above are perpetual and will not be
+ * revoked by the Internet Society or its successors or assigns.
+ *
+ * This document and the information contained herein is provided on
+ * an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+ * ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE
+ * OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+#define CRC24_INIT 0xb704ceL
+#define CRC24_POLY 0x1864cfbL
+
+static void
+crc24rfc2440_init (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->CRC = CRC24_INIT;
+}
+
+static void
+crc24rfc2440_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ int i;
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+
+ if (!inbuf)
+ return;
+
+ while (inlen--) {
+ ctx->CRC ^= (*inbuf++) << 16;
+ for (i = 0; i < 8; i++) {
+ ctx->CRC <<= 1;
+ if (ctx->CRC & 0x1000000)
+ ctx->CRC ^= CRC24_POLY;
+ }
+ }
+}
+
+static void
+crc24rfc2440_final (void *context)
+{
+ CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+ ctx->buf[0] = (ctx->CRC >> 16) & 0xFF;
+ ctx->buf[1] = (ctx->CRC >> 8) & 0xFF;
+ ctx->buf[2] = (ctx->CRC ) & 0xFF;
+}
+
+gcry_md_spec_t _gcry_digest_spec_crc32 =
+ {
+ "CRC32", NULL, 0, NULL, 4,
+ crc32_init, crc32_write, crc32_final, crc32_read,
+ sizeof (CRC_CONTEXT)
+ };
+
+gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
+ {
+ "CRC32RFC1510", NULL, 0, NULL, 4,
+ crc32rfc1510_init, crc32_write,
+ crc32rfc1510_final, crc32_read,
+ sizeof (CRC_CONTEXT)
+ };
+
+gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440 =
+ {
+ "CRC24RFC2440", NULL, 0, NULL, 3,
+ crc24rfc2440_init, crc24rfc2440_write,
+ crc24rfc2440_final, crc32_read,
+ sizeof (CRC_CONTEXT)
+ };
--- /dev/null
+/* des.c - DES and Triple-DES encryption/decryption Algorithm
+ * Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * For a description of triple encryption, see:
+ * Bruce Schneier: Applied Cryptography. Second Edition.
+ * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
+ * This implementation is according to the definition of DES in FIPS
+ * PUB 46-2 from December 1993.
+ */
+
+
+/*
+ * Written by Michael Roth <mroth@nessie.de>, September 1998
+ */
+
+
+/*
+ * U S A G E
+ * ===========
+ *
+ * For DES or Triple-DES encryption/decryption you must initialize a proper
+ * encryption context with a key.
+ *
+ * A DES key is 64bit wide but only 56bits of the key are used. The remaining
+ * bits are parity bits and they will _not_ checked in this implementation, but
+ * simply ignored.
+ *
+ * For Triple-DES you could use either two 64bit keys or three 64bit keys.
+ * The parity bits will _not_ checked, too.
+ *
+ * After initializing a context with a key you could use this context to
+ * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode.
+ *
+ * (In the examples below the slashes at the beginning and ending of comments
+ * are omited.)
+ *
+ * DES Example
+ * -----------
+ * unsigned char key[8];
+ * unsigned char plaintext[8];
+ * unsigned char ciphertext[8];
+ * unsigned char recoverd[8];
+ * des_ctx context;
+ *
+ * * Fill 'key' and 'plaintext' with some data *
+ * ....
+ *
+ * * Set up the DES encryption context *
+ * des_setkey(context, key);
+ *
+ * * Encrypt the plaintext *
+ * des_ecb_encrypt(context, plaintext, ciphertext);
+ *
+ * * To recover the orginal plaintext from ciphertext use: *
+ * des_ecb_decrypt(context, ciphertext, recoverd);
+ *
+ *
+ * Triple-DES Example
+ * ------------------
+ * unsigned char key1[8];
+ * unsigned char key2[8];
+ * unsigned char key3[8];
+ * unsigned char plaintext[8];
+ * unsigned char ciphertext[8];
+ * unsigned char recoverd[8];
+ * tripledes_ctx context;
+ *
+ * * If you would like to use two 64bit keys, fill 'key1' and'key2'
+ * then setup the encryption context: *
+ * tripledes_set2keys(context, key1, key2);
+ *
+ * * To use three 64bit keys with Triple-DES use: *
+ * tripledes_set3keys(context, key1, key2, key3);
+ *
+ * * Encrypting plaintext with Triple-DES *
+ * tripledes_ecb_encrypt(context, plaintext, ciphertext);
+ *
+ * * Decrypting ciphertext to recover the plaintext with Triple-DES *
+ * tripledes_ecb_decrypt(context, ciphertext, recoverd);
+ *
+ *
+ * Selftest
+ * --------
+ * char *error_msg;
+ *
+ * * To perform a selftest of this DES/Triple-DES implementation use the
+ * function selftest(). It will return an error string if there are
+ * some problems with this library. *
+ *
+ * if ( (error_msg = selftest()) )
+ * {
+ * fprintf(stderr, "An error in the DES/Triple-DES implementation occurred: %s\n", error_msg);
+ * abort();
+ * }
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h> /* memcpy, memcmp */
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#if defined(__GNUC__) && defined(__GNU_LIBRARY__)
+#define working_memcmp memcmp
+#else
+/*
+ * According to the SunOS man page, memcmp returns indeterminate sign
+ * depending on whether characters are signed or not.
+ */
+static int
+working_memcmp( const char *a, const char *b, size_t n )
+{
+ for( ; n; n--, a++, b++ )
+ if( *a != *b )
+ return (int)(*(byte*)a) - (int)(*(byte*)b);
+ return 0;
+}
+#endif
+
+/*
+ * Encryption/Decryption context of DES
+ */
+typedef struct _des_ctx
+ {
+ u32 encrypt_subkeys[32];
+ u32 decrypt_subkeys[32];
+ }
+des_ctx[1];
+
+/*
+ * Encryption/Decryption context of Triple-DES
+ */
+typedef struct _tripledes_ctx
+ {
+ u32 encrypt_subkeys[96];
+ u32 decrypt_subkeys[96];
+ struct {
+ int no_weak_key;
+ } flags;
+ }
+tripledes_ctx[1];
+
+static void des_key_schedule (const byte *, u32 *);
+static int des_setkey (struct _des_ctx *, const byte *);
+static int des_ecb_crypt (struct _des_ctx *, const byte *, byte *, int);
+static int tripledes_set2keys (struct _tripledes_ctx *,
+ const byte *, const byte *);
+static int tripledes_set3keys (struct _tripledes_ctx *,
+ const byte *, const byte *, const byte *);
+static int tripledes_ecb_crypt (struct _tripledes_ctx *,
+ const byte *, byte *, int);
+static int is_weak_key ( const byte *key );
+static const char *selftest (void);
+
+static int initialized;
+
+
+
+
+/*
+ * The s-box values are permuted according to the 'primitive function P'
+ * and are rotated one bit to the left.
+ */
+static u32 sbox1[64] =
+{
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
+
+static u32 sbox2[64] =
+{
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static u32 sbox3[64] =
+{
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static u32 sbox4[64] =
+{
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static u32 sbox5[64] =
+{
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static u32 sbox6[64] =
+{
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static u32 sbox7[64] =
+{
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static u32 sbox8[64] =
+{
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+
+/*
+ * These two tables are part of the 'permuted choice 1' function.
+ * In this implementation several speed improvements are done.
+ */
+static u32 leftkey_swap[16] =
+{
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static u32 rightkey_swap[16] =
+{
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+};
+
+
+
+/*
+ * Numbers of left shifts per round for encryption subkeys.
+ * To calculate the decryption subkeys we just reverse the
+ * ordering of the calculated encryption subkeys. So their
+ * is no need for a decryption rotate tab.
+ */
+static byte encrypt_rotate_tab[16] =
+{
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+
+
+/*
+ * Table with weak DES keys sorted in ascending order.
+ * In DES their are 64 known keys which are weak. They are weak
+ * because they produce only one, two or four different
+ * subkeys in the subkey scheduling process.
+ * The keys in this table have all their parity bits cleared.
+ */
+static byte weak_keys[64][8] =
+{
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*w*/
+ { 0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e },
+ { 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0 },
+ { 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe },
+ { 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e }, /*sw*/
+ { 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00 },
+ { 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe },
+ { 0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0 },
+ { 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0 }, /*sw*/
+ { 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe },
+ { 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00 },
+ { 0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e },
+ { 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe }, /*sw*/
+ { 0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0 },
+ { 0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e },
+ { 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00 },
+ { 0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e },
+ { 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00 }, /*sw*/
+ { 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe },
+ { 0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0 },
+ { 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00 },
+ { 0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e }, /*w*/
+ { 0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0 },
+ { 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe },
+ { 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe },
+ { 0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0 }, /*sw*/
+ { 0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e },
+ { 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00 },
+ { 0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0 },
+ { 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe }, /*sw*/
+ { 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00 },
+ { 0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e },
+ { 0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0 },
+ { 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe },
+ { 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00 }, /*sw*/
+ { 0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e },
+ { 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe },
+ { 0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0 },
+ { 0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e }, /*sw*/
+ { 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00 },
+ { 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00 },
+ { 0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e },
+ { 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0 }, /*w*/
+ { 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe },
+ { 0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e },
+ { 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00 },
+ { 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe }, /*sw*/
+ { 0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0 },
+ { 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe },
+ { 0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0 },
+ { 0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e },
+ { 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00 }, /*sw*/
+ { 0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0 },
+ { 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe },
+ { 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00 },
+ { 0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e }, /*sw*/
+ { 0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e },
+ { 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00 },
+ { 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe },
+ { 0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0 }, /*sw*/
+ { 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00 },
+ { 0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e },
+ { 0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0 },
+ { 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe } /*w*/
+};
+static unsigned char weak_keys_chksum[20] = {
+ 0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7,
+ 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41
+};
+
+
+
+/*
+ * Macro to swap bits across two words.
+ */
+#define DO_PERMUTATION(a, temp, b, offset, mask) \
+ temp = ((a>>offset) ^ b) & mask; \
+ b ^= temp; \
+ a ^= temp<<offset;
+
+
+/*
+ * This performs the 'initial permutation' of the data to be encrypted
+ * or decrypted. Additionally the resulting two words are rotated one bit
+ * to the left.
+ */
+#define INITIAL_PERMUTATION(left, temp, right) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ right = (right << 1) | (right >> 31); \
+ temp = (left ^ right) & 0xaaaaaaaa; \
+ right ^= temp; \
+ left ^= temp; \
+ left = (left << 1) | (left >> 31);
+
+/*
+ * The 'inverse initial permutation'.
+ */
+#define FINAL_PERMUTATION(left, temp, right) \
+ left = (left << 31) | (left >> 1); \
+ temp = (left ^ right) & 0xaaaaaaaa; \
+ left ^= temp; \
+ right ^= temp; \
+ right = (right << 31) | (right >> 1); \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
+
+
+/*
+ * A full DES round including 'expansion function', 'sbox substitution'
+ * and 'primitive function P' but without swapping the left and right word.
+ * Please note: The data in 'from' and 'to' is already rotated one bit to
+ * the left, done in the initial permutation.
+ */
+#define DES_ROUND(from, to, work, subkey) \
+ work = from ^ *subkey++; \
+ to ^= sbox8[ work & 0x3f ]; \
+ to ^= sbox6[ (work>>8) & 0x3f ]; \
+ to ^= sbox4[ (work>>16) & 0x3f ]; \
+ to ^= sbox2[ (work>>24) & 0x3f ]; \
+ work = ((from << 28) | (from >> 4)) ^ *subkey++; \
+ to ^= sbox7[ work & 0x3f ]; \
+ to ^= sbox5[ (work>>8) & 0x3f ]; \
+ to ^= sbox3[ (work>>16) & 0x3f ]; \
+ to ^= sbox1[ (work>>24) & 0x3f ];
+
+/*
+ * Macros to convert 8 bytes from/to 32bit words.
+ */
+#define READ_64BIT_DATA(data, left, right) \
+ left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
+ right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+
+#define WRITE_64BIT_DATA(data, left, right) \
+ data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
+ data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
+ data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
+ data[6] = (right >> 8) &0xff; data[7] = right &0xff;
+
+/*
+ * Handy macros for encryption and decryption of data
+ */
+#define des_ecb_encrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 0)
+#define des_ecb_decrypt(ctx, from, to) des_ecb_crypt(ctx, from, to, 1)
+#define tripledes_ecb_encrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,0)
+#define tripledes_ecb_decrypt(ctx, from, to) tripledes_ecb_crypt(ctx,from,to,1)
+
+
+
+
+
+
+/*
+ * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
+ * 16 encryption rounds.
+ * To calculate subkeys for decryption the caller
+ * have to reorder the generated subkeys.
+ *
+ * rawkey: 8 Bytes of key data
+ * subkey: Array of at least 32 u32s. Will be filled
+ * with calculated subkeys.
+ *
+ */
+static void
+des_key_schedule (const byte * rawkey, u32 * subkey)
+{
+ u32 left, right, work;
+ int round;
+
+ READ_64BIT_DATA (rawkey, left, right)
+
+ DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
+ DO_PERMUTATION (right, work, left, 0, 0x10101010)
+
+ left = ((leftkey_swap[(left >> 0) & 0xf] << 3)
+ | (leftkey_swap[(left >> 8) & 0xf] << 2)
+ | (leftkey_swap[(left >> 16) & 0xf] << 1)
+ | (leftkey_swap[(left >> 24) & 0xf])
+ | (leftkey_swap[(left >> 5) & 0xf] << 7)
+ | (leftkey_swap[(left >> 13) & 0xf] << 6)
+ | (leftkey_swap[(left >> 21) & 0xf] << 5)
+ | (leftkey_swap[(left >> 29) & 0xf] << 4));
+
+ left &= 0x0fffffff;
+
+ right = ((rightkey_swap[(right >> 1) & 0xf] << 3)
+ | (rightkey_swap[(right >> 9) & 0xf] << 2)
+ | (rightkey_swap[(right >> 17) & 0xf] << 1)
+ | (rightkey_swap[(right >> 25) & 0xf])
+ | (rightkey_swap[(right >> 4) & 0xf] << 7)
+ | (rightkey_swap[(right >> 12) & 0xf] << 6)
+ | (rightkey_swap[(right >> 20) & 0xf] << 5)
+ | (rightkey_swap[(right >> 28) & 0xf] << 4));
+
+ right &= 0x0fffffff;
+
+ for (round = 0; round < 16; ++round)
+ {
+ left = ((left << encrypt_rotate_tab[round])
+ | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+ right = ((right << encrypt_rotate_tab[round])
+ | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+
+ *subkey++ = (((left << 4) & 0x24000000)
+ | ((left << 28) & 0x10000000)
+ | ((left << 14) & 0x08000000)
+ | ((left << 18) & 0x02080000)
+ | ((left << 6) & 0x01000000)
+ | ((left << 9) & 0x00200000)
+ | ((left >> 1) & 0x00100000)
+ | ((left << 10) & 0x00040000)
+ | ((left << 2) & 0x00020000)
+ | ((left >> 10) & 0x00010000)
+ | ((right >> 13) & 0x00002000)
+ | ((right >> 4) & 0x00001000)
+ | ((right << 6) & 0x00000800)
+ | ((right >> 1) & 0x00000400)
+ | ((right >> 14) & 0x00000200)
+ | (right & 0x00000100)
+ | ((right >> 5) & 0x00000020)
+ | ((right >> 10) & 0x00000010)
+ | ((right >> 3) & 0x00000008)
+ | ((right >> 18) & 0x00000004)
+ | ((right >> 26) & 0x00000002)
+ | ((right >> 24) & 0x00000001));
+
+ *subkey++ = (((left << 15) & 0x20000000)
+ | ((left << 17) & 0x10000000)
+ | ((left << 10) & 0x08000000)
+ | ((left << 22) & 0x04000000)
+ | ((left >> 2) & 0x02000000)
+ | ((left << 1) & 0x01000000)
+ | ((left << 16) & 0x00200000)
+ | ((left << 11) & 0x00100000)
+ | ((left << 3) & 0x00080000)
+ | ((left >> 6) & 0x00040000)
+ | ((left << 15) & 0x00020000)
+ | ((left >> 4) & 0x00010000)
+ | ((right >> 2) & 0x00002000)
+ | ((right << 8) & 0x00001000)
+ | ((right >> 14) & 0x00000808)
+ | ((right >> 9) & 0x00000400)
+ | ((right) & 0x00000200)
+ | ((right << 7) & 0x00000100)
+ | ((right >> 7) & 0x00000020)
+ | ((right >> 3) & 0x00000011)
+ | ((right << 2) & 0x00000004)
+ | ((right >> 21) & 0x00000002));
+ }
+}
+
+
+/*
+ * Fill a DES context with subkeys calculated from a 64bit key.
+ * Does not check parity bits, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+des_setkey (struct _des_ctx *ctx, const byte * key)
+{
+ static const char *selftest_failed;
+ int i;
+
+ if (!fips_mode () && !initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+
+ if (selftest_failed)
+ log_error ("%s\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ des_key_schedule (key, ctx->encrypt_subkeys);
+ _gcry_burn_stack (32);
+
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Electronic Codebook Mode DES encryption/decryption of data according
+ * to 'mode'.
+ */
+static int
+des_ecb_crypt (struct _des_ctx *ctx, const byte * from, byte * to, int mode)
+{
+ u32 left, right, work;
+ u32 *keys;
+
+ keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
+
+ READ_64BIT_DATA (from, left, right)
+ INITIAL_PERMUTATION (left, work, right)
+
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+ FINAL_PERMUTATION (right, work, left)
+ WRITE_64BIT_DATA (to, right, left)
+
+ return 0;
+}
+
+
+
+/*
+ * Fill a Triple-DES context with subkeys calculated from two 64bit keys.
+ * Does not check the parity bits of the keys, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+tripledes_set2keys (struct _tripledes_ctx *ctx,
+ const byte * key1,
+ const byte * key2)
+{
+ int i;
+
+ des_key_schedule (key1, ctx->encrypt_subkeys);
+ des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+ _gcry_burn_stack (32);
+
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+
+ ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
+ ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
+
+ ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
+ ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Fill a Triple-DES context with subkeys calculated from three 64bit keys.
+ * Does not check the parity bits of the keys, but simply ignore them.
+ * Does not check for weak keys.
+ */
+static int
+tripledes_set3keys (struct _tripledes_ctx *ctx,
+ const byte * key1,
+ const byte * key2,
+ const byte * key3)
+{
+ static const char *selftest_failed;
+ int i;
+
+ if (!fips_mode () && !initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+
+ if (selftest_failed)
+ log_error ("%s\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ des_key_schedule (key1, ctx->encrypt_subkeys);
+ des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
+ des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
+ _gcry_burn_stack (32);
+
+ for(i=0; i<32; i+=2)
+ {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[95-i];
+
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+
+ ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Electronic Codebook Mode Triple-DES encryption/decryption of data
+ * according to 'mode'. Sometimes this mode is named 'EDE' mode
+ * (Encryption-Decryption-Encryption).
+ */
+static int
+tripledes_ecb_crypt (struct _tripledes_ctx *ctx, const byte * from,
+ byte * to, int mode)
+{
+ u32 left, right, work;
+ u32 *keys;
+
+ keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
+
+ READ_64BIT_DATA (from, left, right)
+ INITIAL_PERMUTATION (left, work, right)
+
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+ DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
+
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+ DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
+
+ FINAL_PERMUTATION (right, work, left)
+ WRITE_64BIT_DATA (to, right, left)
+
+ return 0;
+}
+
+
+
+
+
+/*
+ * Check whether the 8 byte key is weak.
+ * Does not check the parity bits of the key but simple ignore them.
+ */
+static int
+is_weak_key ( const byte *key )
+{
+ byte work[8];
+ int i, left, right, middle, cmp_result;
+
+ /* clear parity bits */
+ for(i=0; i<8; ++i)
+ work[i] = key[i] & 0xfe;
+
+ /* binary search in the weak key table */
+ left = 0;
+ right = 63;
+ while(left <= right)
+ {
+ middle = (left + right) / 2;
+
+ if ( !(cmp_result=working_memcmp(work, weak_keys[middle], 8)) )
+ return -1;
+
+ if ( cmp_result > 0 )
+ left = middle + 1;
+ else
+ right = middle - 1;
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * Performs a selftest of this DES/Triple-DES implementation.
+ * Returns an string with the error text on failure.
+ * Returns NULL if all is ok.
+ */
+static const char *
+selftest (void)
+{
+ /*
+ * Check if 'u32' is really 32 bits wide. This DES / 3DES implementation
+ * need this.
+ */
+ if (sizeof (u32) != 4)
+ return "Wrong word size for DES configured.";
+
+ /*
+ * DES Maintenance Test
+ */
+ {
+ int i;
+ byte key[8] =
+ {0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+ byte input[8] =
+ {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ byte result[8] =
+ {0x24, 0x6e, 0x9d, 0xb9, 0xc5, 0x50, 0x38, 0x1a};
+ byte temp1[8], temp2[8], temp3[8];
+ des_ctx des;
+
+ for (i = 0; i < 64; ++i)
+ {
+ des_setkey (des, key);
+ des_ecb_encrypt (des, input, temp1);
+ des_ecb_encrypt (des, temp1, temp2);
+ des_setkey (des, temp2);
+ des_ecb_decrypt (des, temp1, temp3);
+ memcpy (key, temp3, 8);
+ memcpy (input, temp1, 8);
+ }
+ if (memcmp (temp3, result, 8))
+ return "DES maintenance test failed.";
+ }
+
+
+ /*
+ * Self made Triple-DES test (Does somebody know an official test?)
+ */
+ {
+ int i;
+ byte input[8] =
+ {0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10};
+ byte key1[8] =
+ {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
+ byte key2[8] =
+ {0x11, 0x22, 0x33, 0x44, 0xff, 0xaa, 0xcc, 0xdd};
+ byte result[8] =
+ {0x7b, 0x38, 0x3b, 0x23, 0xa2, 0x7d, 0x26, 0xd3};
+
+ tripledes_ctx des3;
+
+ for (i = 0; i < 16; ++i)
+ {
+ tripledes_set2keys (des3, key1, key2);
+ tripledes_ecb_encrypt (des3, input, key1);
+ tripledes_ecb_decrypt (des3, input, key2);
+ tripledes_set3keys (des3, key1, input, key2);
+ tripledes_ecb_encrypt (des3, input, input);
+ }
+ if (memcmp (input, result, 8))
+ return "Triple-DES test failed.";
+ }
+
+ /*
+ * More Triple-DES test. These are testvectors as used by SSLeay,
+ * thanks to Jeroen C. van Gelderen.
+ */
+ {
+ struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
+ { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },
+ { 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00 },
+ { 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
+ },
+
+ { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },
+ { 0x9D,0x64,0x55,0x5A,0x9A,0x10,0xB8,0x52, },
+ { 0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x00 }
+ },
+ { { 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
+ 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,
+ 0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E },
+ { 0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A },
+ { 0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A }
+ },
+ { { 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
+ 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,
+ 0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6 },
+ { 0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2 },
+ { 0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95 }
+ },
+ { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
+ { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 },
+ { 0x3D,0x12,0x4F,0xE2,0x19,0x8B,0xA3,0x18 }
+ },
+ { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF },
+ { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 },
+ { 0xFB,0xAB,0xA1,0xFF,0x9D,0x05,0xE9,0xB1 }
+ },
+ { { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
+ 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
+ 0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10 },
+ { 0x73,0x6F,0x6D,0x65,0x64,0x61,0x74,0x61 },
+ { 0x18,0xd7,0x48,0xe5,0x63,0x62,0x05,0x72 }
+ },
+ { { 0x03,0x52,0x02,0x07,0x67,0x20,0x82,0x17,
+ 0x86,0x02,0x87,0x66,0x59,0x08,0x21,0x98,
+ 0x64,0x05,0x6A,0xBD,0xFE,0xA9,0x34,0x57 },
+ { 0x73,0x71,0x75,0x69,0x67,0x67,0x6C,0x65 },
+ { 0xc0,0x7d,0x2a,0x0f,0xa5,0x66,0xfa,0x30 }
+ },
+ { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x80,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
+ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02 },
+ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
+ { 0xe6,0xe6,0xdd,0x5b,0x7e,0x72,0x29,0x74 }
+ },
+ { { 0x10,0x46,0x10,0x34,0x89,0x98,0x80,0x20,
+ 0x91,0x07,0xD0,0x15,0x89,0x19,0x01,0x01,
+ 0x19,0x07,0x92,0x10,0x98,0x1A,0x01,0x01 },
+ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
+ { 0xe1,0xef,0x62,0xc3,0x32,0xfe,0x82,0x5b }
+ }
+ };
+
+ byte result[8];
+ int i;
+ tripledes_ctx des3;
+
+ for (i=0; i<sizeof(testdata)/sizeof(*testdata); ++i)
+ {
+ tripledes_set3keys (des3, testdata[i].key,
+ testdata[i].key + 8, testdata[i].key + 16);
+
+ tripledes_ecb_encrypt (des3, testdata[i].plain, result);
+ if (memcmp (testdata[i].cipher, result, 8))
+ return "Triple-DES SSLeay test failed on encryption.";
+
+ tripledes_ecb_decrypt (des3, testdata[i].cipher, result);
+ if (memcmp (testdata[i].plain, result, 8))
+ return "Triple-DES SSLeay test failed on decryption.";;
+ }
+ }
+
+ /*
+ * Check the weak key detection. We simply assume that the table
+ * with weak keys is ok and check every key in the table if it is
+ * detected... (This test is a little bit stupid).
+ */
+ {
+ int i;
+ unsigned char *p;
+ gcry_md_hd_t h;
+
+ if (_gcry_md_open (&h, GCRY_MD_SHA1, 0))
+ return "SHA1 not available";
+
+ for (i = 0; i < 64; ++i)
+ _gcry_md_write (h, weak_keys[i], 8);
+ p = _gcry_md_read (h, GCRY_MD_SHA1);
+ i = memcmp (p, weak_keys_chksum, 20);
+ _gcry_md_close (h);
+ if (i)
+ return "weak key table defect";
+
+ for (i = 0; i < 64; ++i)
+ if (!is_weak_key(weak_keys[i]))
+ return "DES weak key detection failed";
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+do_tripledes_setkey ( void *context, const byte *key, unsigned keylen )
+{
+ struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+ if( keylen != 24 )
+ return GPG_ERR_INV_KEYLEN;
+
+ tripledes_set3keys ( ctx, key, key+8, key+16);
+
+ if (ctx->flags.no_weak_key)
+ ; /* Detection has been disabled. */
+ else if (is_weak_key (key) || is_weak_key (key+8) || is_weak_key (key+16))
+ {
+ _gcry_burn_stack (64);
+ return GPG_ERR_WEAK_KEY;
+ }
+ _gcry_burn_stack (64);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+do_tripledes_set_extra_info (void *context, int what,
+ const void *buffer, size_t buflen)
+{
+ struct _tripledes_ctx *ctx = (struct _tripledes_ctx *)context;
+ gpg_err_code_t ec = 0;
+
+ (void)buffer;
+ (void)buflen;
+
+ switch (what)
+ {
+ case CIPHER_INFO_NO_WEAK_KEY:
+ ctx->flags.no_weak_key = 1;
+ break;
+
+ default:
+ ec = GPG_ERR_INV_OP;
+ break;
+ }
+ return ec;
+}
+
+
+static void
+do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+ struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+
+ tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
+ _gcry_burn_stack (32);
+}
+
+static void
+do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+ struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
+ tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
+ _gcry_burn_stack (32);
+}
+
+static gcry_err_code_t
+do_des_setkey (void *context, const byte *key, unsigned keylen)
+{
+ struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+ if (keylen != 8)
+ return GPG_ERR_INV_KEYLEN;
+
+ des_setkey (ctx, key);
+
+ if (is_weak_key (key)) {
+ _gcry_burn_stack (64);
+ return GPG_ERR_WEAK_KEY;
+ }
+ _gcry_burn_stack (64);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static void
+do_des_encrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+ struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+ des_ecb_encrypt ( ctx, inbuf, outbuf );
+ _gcry_burn_stack (32);
+}
+
+static void
+do_des_decrypt( void *context, byte *outbuf, const byte *inbuf )
+{
+ struct _des_ctx *ctx = (struct _des_ctx *) context;
+
+ des_ecb_decrypt ( ctx, inbuf, outbuf );
+ _gcry_burn_stack (32);
+}
+
+
+
+\f
+/*
+ Self-test section.
+ */
+
+
+/* Selftest for TripleDES. */
+static gpg_err_code_t
+selftest_fips (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ (void)extended; /* No extended tests available. */
+
+ what = "low-level";
+ errtxt = selftest ();
+ if (errtxt)
+ goto failed;
+
+ /* The low-level self-tests are quite extensive and thus we can do
+ without high level tests. This is also justified because we have
+ no custom block code implementation for 3des but always use the
+ standard high level block code. */
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_3DES, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_CIPHER_3DES:
+ ec = selftest_fips (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_CIPHER_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+\f
+gcry_cipher_spec_t _gcry_cipher_spec_des =
+ {
+ "DES", NULL, NULL, 8, 64, sizeof (struct _des_ctx),
+ do_des_setkey, do_des_encrypt, do_des_decrypt
+ };
+
+static gcry_cipher_oid_spec_t oids_tripledes[] =
+ {
+ { "1.2.840.113549.3.7", GCRY_CIPHER_MODE_CBC },
+ /* Teletrust specific OID for 3DES. */
+ { "1.3.36.3.1.3.2.1", GCRY_CIPHER_MODE_CBC },
+ /* pbeWithSHAAnd3_KeyTripleDES_CBC */
+ { "1.2.840.113549.1.12.1.3", GCRY_CIPHER_MODE_CBC },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_tripledes =
+ {
+ "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx),
+ do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
+ };
+
+cipher_extra_spec_t _gcry_cipher_extraspec_tripledes =
+ {
+ run_selftests,
+ do_tripledes_set_extra_info
+ };
--- /dev/null
+/* dsa.c - DSA signature algorithm
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2006, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+} DSA_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* secret exponent */
+} DSA_secret_key;
+
+
+/* A structure used to hold domain parameters. */
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t q; /* group order */
+ gcry_mpi_t g; /* group generator */
+} dsa_domain_t;
+
+
+/* A sample 1024 bit DSA key used for the selftests. */
+static const char sample_secret_key[] =
+"(private-key"
+" (dsa"
+" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
+" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
+/* A sample 1024 bit DSA key used for the selftests (public only). */
+static const char sample_public_key[] =
+"(public-key"
+" (dsa"
+" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)"
+" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)"
+" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)"
+" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))";
+
+
+
+\f
+static gcry_mpi_t gen_k (gcry_mpi_t q);
+static int test_keys (DSA_secret_key *sk, unsigned int qbits);
+static int check_secret_key (DSA_secret_key *sk);
+static gpg_err_code_t generate (DSA_secret_key *sk,
+ unsigned int nbits,
+ unsigned int qbits,
+ int transient_key,
+ dsa_domain_t *domain,
+ gcry_mpi_t **ret_factors);
+static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+ DSA_secret_key *skey);
+static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+ DSA_public_key *pkey);
+
+static void (*progress_cb) (void *,const char *, int, int, int );
+static void *progress_cb_data;
+
+
+void
+_gcry_register_pk_dsa_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, "pk_dsa", c, 0, 0);
+}
+
+
+/*
+ * Generate a random secret exponent k less than q.
+ */
+static gcry_mpi_t
+gen_k( gcry_mpi_t q )
+{
+ gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
+ unsigned int nbits = mpi_get_nbits(q);
+ unsigned int nbytes = (nbits+7)/8;
+ char *rndbuf = NULL;
+
+ /* To learn why we don't use mpi_mod to get the requested bit size,
+ read the paper: "The Insecurity of the Digital Signature
+ Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
+ Journal of Cryptology, New York. Vol 15, nr 3 (2003) */
+
+ if ( DBG_CIPHER )
+ log_debug("choosing a random k ");
+ for (;;)
+ {
+ if( DBG_CIPHER )
+ progress('.');
+
+ if ( !rndbuf || nbits < 32 )
+ {
+ gcry_free(rndbuf);
+ rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
+ }
+ else
+ { /* Change only some of the higher bits. We could improve
+ this by directly requesting more memory at the first call
+ to get_random_bytes() and use these extra bytes here.
+ However the required management code is more complex and
+ thus we better use this simple method. */
+ char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+ memcpy( rndbuf,pp, 4 );
+ gcry_free(pp);
+ }
+ _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+
+ /* Make sure we have the requested number of bits. This code
+ looks a bit funny but it is easy to understand if you
+ consider that mpi_set_highbit clears all higher bits. We
+ don't have a clear_highbit, thus we first set the high bit
+ and then clear it again. */
+ if ( mpi_test_bit( k, nbits-1 ) )
+ mpi_set_highbit( k, nbits-1 );
+ else
+ {
+ mpi_set_highbit( k, nbits-1 );
+ mpi_clear_bit( k, nbits-1 );
+ }
+
+ if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
+ {
+ if( DBG_CIPHER )
+ progress('+');
+ continue; /* no */
+ }
+ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
+ {
+ if( DBG_CIPHER )
+ progress('-');
+ continue; /* no */
+ }
+ break; /* okay */
+ }
+ gcry_free(rndbuf);
+ if( DBG_CIPHER )
+ progress('\n');
+
+ return k;
+}
+
+
+/* Check that a freshly generated key actually works. Returns 0 on success. */
+static int
+test_keys (DSA_secret_key *sk, unsigned int qbits)
+{
+ int result = -1; /* Default to failure. */
+ DSA_public_key pk;
+ gcry_mpi_t data = gcry_mpi_new (qbits);
+ gcry_mpi_t sig_a = gcry_mpi_new (qbits);
+ gcry_mpi_t sig_b = gcry_mpi_new (qbits);
+
+ /* Put the relevant parameters into a public key structure. */
+ pk.p = sk->p;
+ pk.q = sk->q;
+ pk.g = sk->g;
+ pk.y = sk->y;
+
+ /* Create a random plaintext. */
+ gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
+
+ /* Sign DATA using the secret key. */
+ sign (sig_a, sig_b, data, sk);
+
+ /* Verify the signature using the public key. */
+ if ( !verify (sig_a, sig_b, data, &pk) )
+ goto leave; /* Signature does not match. */
+
+ /* Modify the data and check that the signing fails. */
+ gcry_mpi_add_ui (data, data, 1);
+ if ( verify (sig_a, sig_b, data, &pk) )
+ goto leave; /* Signature matches but should not. */
+
+ result = 0; /* The test succeeded. */
+
+ leave:
+ gcry_mpi_release (sig_b);
+ gcry_mpi_release (sig_a);
+ gcry_mpi_release (data);
+ return result;
+}
+
+
+
+/*
+ Generate a DSA key pair with a key of size NBITS. If transient_key
+ is true the key is generated using the standard RNG and not the
+ very secure one.
+
+ Returns: 2 structures filled with all needed values
+ and an array with the n-1 factors of (p-1)
+ */
+static gpg_err_code_t
+generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+ int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
+{
+ gcry_mpi_t p; /* the prime */
+ gcry_mpi_t q; /* the 160 bit prime factor */
+ gcry_mpi_t g; /* the generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* the secret exponent */
+ gcry_mpi_t h, e; /* helper */
+ unsigned char *rndbuf;
+ gcry_random_level_t random_level;
+
+ if (qbits)
+ ; /* Caller supplied qbits. Use this value. */
+ else if ( nbits >= 512 && nbits <= 1024 )
+ qbits = 160;
+ else if ( nbits == 2048 )
+ qbits = 224;
+ else if ( nbits == 3072 )
+ qbits = 256;
+ else if ( nbits == 7680 )
+ qbits = 384;
+ else if ( nbits == 15360 )
+ qbits = 512;
+ else
+ return GPG_ERR_INV_VALUE;
+
+ if (qbits < 160 || qbits > 512 || (qbits%8) )
+ return GPG_ERR_INV_VALUE;
+ if (nbits < 2*qbits || nbits > 15360)
+ return GPG_ERR_INV_VALUE;
+
+ if (fips_mode ())
+ {
+ if (nbits < 1024)
+ return GPG_ERR_INV_VALUE;
+ if (transient_key)
+ return GPG_ERR_INV_VALUE;
+ }
+
+ if (domain->p && domain->q && domain->g)
+ {
+ /* Domain parameters are given; use them. */
+ p = mpi_copy (domain->p);
+ q = mpi_copy (domain->q);
+ g = mpi_copy (domain->g);
+ gcry_assert (mpi_get_nbits (p) == nbits);
+ gcry_assert (mpi_get_nbits (q) == qbits);
+ h = mpi_alloc (0);
+ e = NULL;
+ }
+ else
+ {
+ /* Generate new domain parameters. */
+ p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
+ /* Get q out of factors. */
+ q = mpi_copy ((*ret_factors)[0]);
+ gcry_assert (mpi_get_nbits (q) == qbits);
+
+ /* Find a generator g (h and e are helpers).
+ e = (p-1)/q */
+ e = mpi_alloc (mpi_get_nlimbs (p));
+ mpi_sub_ui (e, p, 1);
+ mpi_fdiv_q (e, e, q);
+ g = mpi_alloc (mpi_get_nlimbs (p));
+ h = mpi_alloc_set_ui (1); /* (We start with 2.) */
+ do
+ {
+ mpi_add_ui (h, h, 1);
+ /* g = h^e mod p */
+ gcry_mpi_powm (g, h, e, p);
+ }
+ while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
+ }
+
+ /* Select a random number X with the property:
+ * 0 < x < q-1
+ * This must be a very good random number because this is the secret
+ * part. The random quality depends on the transient_key flag. */
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+ if (DBG_CIPHER)
+ log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
+ gcry_assert( qbits >= 160 );
+ x = mpi_alloc_secure( mpi_get_nlimbs(q) );
+ mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
+ rndbuf = NULL;
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ if( !rndbuf )
+ rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
+ else
+ { /* Change only some of the higher bits (= 2 bytes)*/
+ char *r = gcry_random_bytes_secure (2, random_level);
+ memcpy(rndbuf, r, 2 );
+ gcry_free(r);
+ }
+
+ _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
+ mpi_clear_highbit( x, qbits+1 );
+ }
+ while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
+ gcry_free(rndbuf);
+ mpi_free( e );
+ mpi_free( h );
+
+ /* y = g^x mod p */
+ y = mpi_alloc( mpi_get_nlimbs(p) );
+ gcry_mpi_powm( y, g, x, p );
+
+ if( DBG_CIPHER )
+ {
+ progress('\n');
+ log_mpidump("dsa p", p );
+ log_mpidump("dsa q", q );
+ log_mpidump("dsa g", g );
+ log_mpidump("dsa y", y );
+ log_mpidump("dsa x", x );
+ }
+
+ /* Copy the stuff to the key structures. */
+ sk->p = p;
+ sk->q = q;
+ sk->g = g;
+ sk->y = y;
+ sk->x = x;
+
+ /* Now we can test our keys (this should never fail!). */
+ if ( test_keys (sk, qbits) )
+ {
+ gcry_mpi_release (sk->p); sk->p = NULL;
+ gcry_mpi_release (sk->q); sk->q = NULL;
+ gcry_mpi_release (sk->g); sk->g = NULL;
+ gcry_mpi_release (sk->y); sk->y = NULL;
+ gcry_mpi_release (sk->x); sk->x = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+ return 0;
+}
+
+
+/* Generate a DSA key pair with a key of size NBITS using the
+ algorithm given in FIPS-186-3. If USE_FIPS186_2 is true,
+ FIPS-186-2 is used and thus the length is restricted to 1024/160.
+ If DERIVEPARMS is not NULL it may contain a seed value. If domain
+ parameters are specified in DOMAIN, DERIVEPARMS may not be given
+ and NBITS and QBITS must match the specified domain parameters. */
+static gpg_err_code_t
+generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
+ gcry_sexp_t deriveparms, int use_fips186_2,
+ dsa_domain_t *domain,
+ int *r_counter, void **r_seed, size_t *r_seedlen,
+ gcry_mpi_t *r_h)
+{
+ gpg_err_code_t ec;
+ struct {
+ gcry_sexp_t sexp;
+ const void *seed;
+ size_t seedlen;
+ } initial_seed = { NULL, NULL, 0 };
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+ gcry_mpi_t value_g = NULL; /* The generator. */
+ gcry_mpi_t value_y = NULL; /* g^x mod p */
+ gcry_mpi_t value_x = NULL; /* The secret exponent. */
+ gcry_mpi_t value_h = NULL; /* Helper. */
+ gcry_mpi_t value_e = NULL; /* Helper. */
+
+ /* Preset return values. */
+ *r_counter = 0;
+ *r_seed = NULL;
+ *r_seedlen = 0;
+ *r_h = NULL;
+
+ /* Derive QBITS from NBITS if requested */
+ if (!qbits)
+ {
+ if (nbits == 1024)
+ qbits = 160;
+ else if (nbits == 2048)
+ qbits = 224;
+ else if (nbits == 3072)
+ qbits = 256;
+ }
+
+ /* Check that QBITS and NBITS match the standard. Note that FIPS
+ 186-3 uses N for QBITS and L for NBITS. */
+ if (nbits == 1024 && qbits == 160)
+ ;
+ else if (nbits == 2048 && qbits == 224)
+ ;
+ else if (nbits == 2048 && qbits == 256)
+ ;
+ else if (nbits == 3072 && qbits == 256)
+ ;
+ else
+ return GPG_ERR_INV_VALUE;
+
+ if (domain->p && domain->q && domain->g)
+ {
+ /* Domain parameters are given; use them. */
+ prime_p = mpi_copy (domain->p);
+ prime_q = mpi_copy (domain->q);
+ value_g = mpi_copy (domain->g);
+ gcry_assert (mpi_get_nbits (prime_p) == nbits);
+ gcry_assert (mpi_get_nbits (prime_q) == qbits);
+ gcry_assert (!deriveparms);
+ ec = 0;
+ }
+ else
+ {
+ /* Generate new domain parameters. */
+
+ /* Get an initial seed value. */
+ if (deriveparms)
+ {
+ initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
+ if (initial_seed.sexp)
+ initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
+ &initial_seed.seedlen);
+ }
+
+ /* Fixme: Enable 186-3 after it has been approved and after fixing
+ the generation function. */
+ /* if (use_fips186_2) */
+ (void)use_fips186_2;
+ ec = _gcry_generate_fips186_2_prime (nbits, qbits,
+ initial_seed.seed,
+ initial_seed.seedlen,
+ &prime_q, &prime_p,
+ r_counter,
+ r_seed, r_seedlen);
+ /* else */
+ /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */
+ /* &prime_q, &prime_p, */
+ /* r_counter, */
+ /* r_seed, r_seedlen, NULL); */
+ gcry_sexp_release (initial_seed.sexp);
+ if (ec)
+ goto leave;
+
+ /* Find a generator g (h and e are helpers).
+ e = (p-1)/q */
+ value_e = mpi_alloc_like (prime_p);
+ mpi_sub_ui (value_e, prime_p, 1);
+ mpi_fdiv_q (value_e, value_e, prime_q );
+ value_g = mpi_alloc_like (prime_p);
+ value_h = mpi_alloc_set_ui (1);
+ do
+ {
+ mpi_add_ui (value_h, value_h, 1);
+ /* g = h^e mod p */
+ mpi_powm (value_g, value_h, value_e, prime_p);
+ }
+ while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
+ }
+
+
+ /* Select a random number x with: 0 < x < q */
+ value_x = gcry_mpi_snew (qbits);
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
+ mpi_clear_highbit (value_x, qbits+1);
+ }
+ while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
+
+ /* y = g^x mod p */
+ value_y = mpi_alloc_like (prime_p);
+ gcry_mpi_powm (value_y, value_g, value_x, prime_p);
+
+ if (DBG_CIPHER)
+ {
+ progress('\n');
+ log_mpidump("dsa p", prime_p );
+ log_mpidump("dsa q", prime_q );
+ log_mpidump("dsa g", value_g );
+ log_mpidump("dsa y", value_y );
+ log_mpidump("dsa x", value_x );
+ log_mpidump("dsa h", value_h );
+ }
+
+ /* Copy the stuff to the key structures. */
+ sk->p = prime_p; prime_p = NULL;
+ sk->q = prime_q; prime_q = NULL;
+ sk->g = value_g; value_g = NULL;
+ sk->y = value_y; value_y = NULL;
+ sk->x = value_x; value_x = NULL;
+ *r_h = value_h; value_h = NULL;
+
+ leave:
+ gcry_mpi_release (prime_p);
+ gcry_mpi_release (prime_q);
+ gcry_mpi_release (value_g);
+ gcry_mpi_release (value_y);
+ gcry_mpi_release (value_x);
+ gcry_mpi_release (value_h);
+ gcry_mpi_release (value_e);
+
+ /* As a last step test this keys (this should never fail of course). */
+ if (!ec && test_keys (sk, qbits) )
+ {
+ gcry_mpi_release (sk->p); sk->p = NULL;
+ gcry_mpi_release (sk->q); sk->q = NULL;
+ gcry_mpi_release (sk->g); sk->g = NULL;
+ gcry_mpi_release (sk->y); sk->y = NULL;
+ gcry_mpi_release (sk->x); sk->x = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ ec = GPG_ERR_SELFTEST_FAILED;
+ }
+
+ if (ec)
+ {
+ *r_counter = 0;
+ gcry_free (*r_seed); *r_seed = NULL;
+ *r_seedlen = 0;
+ gcry_mpi_release (*r_h); *r_h = NULL;
+ }
+
+ return ec;
+}
+
+
+
+/*
+ Test whether the secret key is valid.
+ Returns: if this is a valid key.
+ */
+static int
+check_secret_key( DSA_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+ gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+ rc = !mpi_cmp( y, sk->y );
+ mpi_free( y );
+ return rc;
+}
+
+
+
+/*
+ Make a DSA signature from HASH and put it into r and s.
+ */
+static void
+sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
+{
+ gcry_mpi_t k;
+ gcry_mpi_t kinv;
+ gcry_mpi_t tmp;
+
+ /* Select a random k with 0 < k < q */
+ k = gen_k( skey->q );
+
+ /* r = (a^k mod p) mod q */
+ gcry_mpi_powm( r, skey->g, k, skey->p );
+ mpi_fdiv_r( r, r, skey->q );
+
+ /* kinv = k^(-1) mod q */
+ kinv = mpi_alloc( mpi_get_nlimbs(k) );
+ mpi_invm(kinv, k, skey->q );
+
+ /* s = (kinv * ( hash + x * r)) mod q */
+ tmp = mpi_alloc( mpi_get_nlimbs(skey->p) );
+ mpi_mul( tmp, skey->x, r );
+ mpi_add( tmp, tmp, hash );
+ mpi_mulm( s , kinv, tmp, skey->q );
+
+ mpi_free(k);
+ mpi_free(kinv);
+ mpi_free(tmp);
+}
+
+
+/*
+ Returns true if the signature composed from R and S is valid.
+ */
+static int
+verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
+{
+ int rc;
+ gcry_mpi_t w, u1, u2, v;
+ gcry_mpi_t base[3];
+ gcry_mpi_t ex[3];
+
+ if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
+ return 0; /* assertion 0 < r < q failed */
+ if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
+ return 0; /* assertion 0 < s < q failed */
+
+ w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ u2 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
+ v = mpi_alloc( mpi_get_nlimbs(pkey->p) );
+
+ /* w = s^(-1) mod q */
+ mpi_invm( w, s, pkey->q );
+
+ /* u1 = (hash * w) mod q */
+ mpi_mulm( u1, hash, w, pkey->q );
+
+ /* u2 = r * w mod q */
+ mpi_mulm( u2, r, w, pkey->q );
+
+ /* v = g^u1 * y^u2 mod p mod q */
+ base[0] = pkey->g; ex[0] = u1;
+ base[1] = pkey->y; ex[1] = u2;
+ base[2] = NULL; ex[2] = NULL;
+ mpi_mulpowm( v, base, ex, pkey->p );
+ mpi_fdiv_r( v, v, pkey->q );
+
+ rc = !mpi_cmp( v, r );
+
+ mpi_free(w);
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(v);
+
+ return rc;
+}
+
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gcry_err_code_t
+dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+ gcry_sexp_t *r_extrainfo)
+{
+ gpg_err_code_t ec;
+ DSA_secret_key sk;
+ gcry_sexp_t l1;
+ unsigned int qbits = 0;
+ gcry_sexp_t deriveparms = NULL;
+ gcry_sexp_t seedinfo = NULL;
+ int transient_key = 0;
+ int use_fips186_2 = 0;
+ int use_fips186 = 0;
+ dsa_domain_t domain;
+
+ (void)algo; /* No need to check it. */
+ (void)evalue; /* Not required for DSA. */
+
+ memset (&domain, 0, sizeof domain);
+
+ if (genparms)
+ {
+ gcry_sexp_t domainsexp;
+
+ /* Parse the optional qbits element. */
+ l1 = gcry_sexp_find_token (genparms, "qbits", 0);
+ if (l1)
+ {
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ s = gcry_sexp_nth_data (l1, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ gcry_sexp_release (l1);
+ return GPG_ERR_INV_OBJ; /* No value or value too large. */
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ qbits = (unsigned int)strtoul (buf, NULL, 0);
+ gcry_sexp_release (l1);
+ }
+
+ /* Parse the optional transient-key flag. */
+ l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ transient_key = 1;
+ gcry_sexp_release (l1);
+ }
+
+ /* Get the optional derive parameters. */
+ deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
+
+ /* Parse the optional "use-fips186" flags. */
+ l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
+ if (l1)
+ {
+ use_fips186 = 1;
+ gcry_sexp_release (l1);
+ }
+ l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
+ if (l1)
+ {
+ use_fips186_2 = 1;
+ gcry_sexp_release (l1);
+ }
+
+ /* Check whether domain parameters are given. */
+ domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
+ if (domainsexp)
+ {
+ /* DERIVEPARMS can't be used together with domain
+ parameters. NBITS abnd QBITS may not be specified
+ because there values are derived from the domain
+ parameters. */
+ if (deriveparms || qbits || nbits)
+ {
+ gcry_sexp_release (domainsexp);
+ gcry_sexp_release (deriveparms);
+ return GPG_ERR_INV_VALUE;
+ }
+
+ /* Put all domain parameters into the domain object. */
+ l1 = gcry_sexp_find_token (domainsexp, "p", 0);
+ domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ l1 = gcry_sexp_find_token (domainsexp, "q", 0);
+ domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ l1 = gcry_sexp_find_token (domainsexp, "g", 0);
+ domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ gcry_sexp_release (domainsexp);
+
+ /* Check that all domain parameters are available. */
+ if (!domain.p || !domain.q || !domain.g)
+ {
+ gcry_mpi_release (domain.p);
+ gcry_mpi_release (domain.q);
+ gcry_mpi_release (domain.g);
+ gcry_sexp_release (deriveparms);
+ return GPG_ERR_MISSING_VALUE;
+ }
+
+ /* Get NBITS and QBITS from the domain parameters. */
+ nbits = mpi_get_nbits (domain.p);
+ qbits = mpi_get_nbits (domain.q);
+ }
+ }
+
+ if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
+ {
+ int counter;
+ void *seed;
+ size_t seedlen;
+ gcry_mpi_t h_value;
+
+ ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
+ &domain,
+ &counter, &seed, &seedlen, &h_value);
+ gcry_sexp_release (deriveparms);
+ if (!ec && h_value)
+ {
+ /* Format the seed-values unless domain parameters are used
+ for which a H_VALUE of NULL is an indication. */
+ ec = gpg_err_code (gcry_sexp_build
+ (&seedinfo, NULL,
+ "(seed-values(counter %d)(seed %b)(h %m))",
+ counter, (int)seedlen, seed, h_value));
+ if (ec)
+ {
+ gcry_mpi_release (sk.p); sk.p = NULL;
+ gcry_mpi_release (sk.q); sk.q = NULL;
+ gcry_mpi_release (sk.g); sk.g = NULL;
+ gcry_mpi_release (sk.y); sk.y = NULL;
+ gcry_mpi_release (sk.x); sk.x = NULL;
+ }
+ gcry_free (seed);
+ gcry_mpi_release (h_value);
+ }
+ }
+ else
+ {
+ ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
+ }
+
+ gcry_mpi_release (domain.p);
+ gcry_mpi_release (domain.q);
+ gcry_mpi_release (domain.g);
+
+ if (!ec)
+ {
+ skey[0] = sk.p;
+ skey[1] = sk.q;
+ skey[2] = sk.g;
+ skey[3] = sk.y;
+ skey[4] = sk.x;
+
+ if (!r_extrainfo)
+ {
+ /* Old style interface - return the factors - if any - at
+ retfactors. */
+ }
+ else if (!*retfactors && !seedinfo)
+ {
+ /* No factors and no seedinfo, thus there is nothing to return. */
+ *r_extrainfo = NULL;
+ }
+ else
+ {
+ /* Put the factors into extrainfo and set retfactors to NULL
+ to make use of the new interface. Note that the factors
+ are not confidential thus we can store them in standard
+ memory. */
+ int nfactors, i, j;
+ char *p;
+ char *format = NULL;
+ void **arg_list = NULL;
+
+ for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
+ ;
+ /* Allocate space for the format string:
+ "(misc-key-info%S(pm1-factors%m))"
+ with one "%m" for each factor and construct it. */
+ format = gcry_malloc (50 + 2*nfactors);
+ if (!format)
+ ec = gpg_err_code_from_syserror ();
+ else
+ {
+ p = stpcpy (format, "(misc-key-info");
+ if (seedinfo)
+ p = stpcpy (p, "%S");
+ if (nfactors)
+ {
+ p = stpcpy (p, "(pm1-factors");
+ for (i=0; i < nfactors; i++)
+ p = stpcpy (p, "%m");
+ p = stpcpy (p, ")");
+ }
+ p = stpcpy (p, ")");
+
+ /* Allocate space for the list of factors plus one for
+ an S-expression plus an extra NULL entry for safety
+ and fill it with the factors. */
+ arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
+ if (!arg_list)
+ ec = gpg_err_code_from_syserror ();
+ else
+ {
+ i = 0;
+ if (seedinfo)
+ arg_list[i++] = &seedinfo;
+ for (j=0; j < nfactors; j++)
+ arg_list[i++] = (*retfactors) + j;
+ arg_list[i] = NULL;
+
+ ec = gpg_err_code (gcry_sexp_build_array
+ (r_extrainfo, NULL, format, arg_list));
+ }
+ }
+
+ gcry_free (arg_list);
+ gcry_free (format);
+ for (i=0; i < nfactors; i++)
+ {
+ gcry_mpi_release ((*retfactors)[i]);
+ (*retfactors)[i] = NULL;
+ }
+ gcry_free (*retfactors);
+ *retfactors = NULL;
+ if (ec)
+ {
+ for (i=0; i < 5; i++)
+ {
+ gcry_mpi_release (skey[i]);
+ skey[i] = NULL;
+ }
+ }
+ }
+ }
+
+ gcry_sexp_release (seedinfo);
+ return ec;
+}
+
+
+static gcry_err_code_t
+dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+ (void)evalue;
+ return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+}
+
+
+
+static gcry_err_code_t
+dsa_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ DSA_secret_key sk;
+
+ (void)algo;
+
+ if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ sk.p = skey[0];
+ sk.q = skey[1];
+ sk.g = skey[2];
+ sk.y = skey[3];
+ sk.x = skey[4];
+ if (! check_secret_key (&sk))
+ err = GPG_ERR_BAD_SECKEY;
+ }
+
+ return err;
+}
+
+
+static gcry_err_code_t
+dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ DSA_secret_key sk;
+
+ (void)algo;
+
+ if ((! data)
+ || (! skey[0]) || (! skey[1]) || (! skey[2])
+ || (! skey[3]) || (! skey[4]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ sk.p = skey[0];
+ sk.q = skey[1];
+ sk.g = skey[2];
+ sk.y = skey[3];
+ sk.x = skey[4];
+ resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
+ resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
+ sign (resarr[0], resarr[1], data, &sk);
+ }
+ return err;
+}
+
+static gcry_err_code_t
+dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ DSA_public_key pk;
+
+ (void)algo;
+ (void)cmp;
+ (void)opaquev;
+
+ if ((! data[0]) || (! data[1]) || (! hash)
+ || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ pk.p = pkey[0];
+ pk.q = pkey[1];
+ pk.g = pkey[2];
+ pk.y = pkey[3];
+ if (! verify (data[0], data[1], hash, &pk))
+ err = GPG_ERR_BAD_SIGNATURE;
+ }
+ return err;
+}
+
+
+static unsigned int
+dsa_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+ (void)algo;
+
+ return mpi_get_nbits (pkey[0]);
+}
+
+
+\f
+/*
+ Self-test section.
+ */
+
+static const char *
+selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ static const char sample_data[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
+ static const char sample_data_bad[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
+
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t data_bad = NULL;
+ gcry_sexp_t sig = NULL;
+
+ err = gcry_sexp_sscan (&data, NULL,
+ sample_data, strlen (sample_data));
+ if (!err)
+ err = gcry_sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ err = gcry_pk_sign (&sig, data, skey);
+ if (err)
+ {
+ errtxt = "signing failed";
+ goto leave;
+ }
+ err = gcry_pk_verify (sig, data, pkey);
+ if (err)
+ {
+ errtxt = "verify failed";
+ goto leave;
+ }
+ err = gcry_pk_verify (sig, data_bad, pkey);
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+ {
+ errtxt = "bad signature not detected";
+ goto leave;
+ }
+
+
+ leave:
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data_bad);
+ gcry_sexp_release (data);
+ return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_dsa (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ gcry_error_t err;
+ gcry_sexp_t skey = NULL;
+ gcry_sexp_t pkey = NULL;
+
+ /* Convert the S-expressions into the internal representation. */
+ what = "convert";
+ err = gcry_sexp_sscan (&skey, NULL,
+ sample_secret_key, strlen (sample_secret_key));
+ if (!err)
+ err = gcry_sexp_sscan (&pkey, NULL,
+ sample_public_key, strlen (sample_public_key));
+ if (err)
+ {
+ errtxt = gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "key consistency";
+ err = gcry_pk_testkey (skey);
+ if (err)
+ {
+ errtxt = gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "sign";
+ errtxt = selftest_sign_1024 (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ return 0; /* Succeeded. */
+
+ failed:
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ if (report)
+ report ("pubkey", GCRY_PK_DSA, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ (void)extended;
+
+ switch (algo)
+ {
+ case GCRY_PK_DSA:
+ ec = selftests_dsa (report);
+ break;
+ default:
+ ec = GPG_ERR_PUBKEY_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static const char *dsa_names[] =
+ {
+ "dsa",
+ "openpgp-dsa",
+ NULL,
+ };
+
+gcry_pk_spec_t _gcry_pubkey_spec_dsa =
+ {
+ "DSA", dsa_names,
+ "pqgy", "pqgyx", "", "rs", "pqgy",
+ GCRY_PK_USAGE_SIGN,
+ dsa_generate,
+ dsa_check_secret_key,
+ NULL,
+ NULL,
+ dsa_sign,
+ dsa_verify,
+ dsa_get_nbits
+ };
+pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
+ {
+ run_selftests,
+ dsa_generate_ext
+ };
--- /dev/null
+/* ecc.c - Elliptic Curve Cryptography
+ Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* This code is originally based on the Patch 0.1.6 for the gnupg
+ 1.4.x branch as retrieved on 2007-03-21 from
+ http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2
+ The original authors are:
+ Written by
+ Sergi Blanch i Torne <d4372211 at alumnes.eup.udl.es>,
+ Ramiro Moreno Chiral <ramiro at eup.udl.es>
+ Maintainers
+ Sergi Blanch i Torne
+ Ramiro Moreno Chiral
+ Mikael Mylnikov (mmr)
+ For use in Libgcrypt the code has been heavily modified and cleaned
+ up. In fact there is not much left of the orginally code except for
+ some variable names and the text book implementaion of the sign and
+ verification algorithms. The arithmetic functions have entirely
+ been rewritten and moved to mpi/ec.c.
+
+ ECDH encrypt and decrypt code written by Andrey Jivsov,
+*/
+
+
+/* TODO:
+
+ - If we support point compression we need to uncompress before
+ computing the keygrip
+
+ - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
+ special case in mpi_powm or check whether mpi_mulm is faster.
+
+ - Decide whether we should hide the mpi_point_t definition.
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+/* Definition of a curve. */
+typedef struct
+{
+ gcry_mpi_t p; /* Prime specifying the field GF(p). */
+ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+ gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */
+ mpi_point_t G; /* Base point (generator). */
+ gcry_mpi_t n; /* Order of G. */
+ const char *name; /* Name of curve or NULL. */
+} elliptic_curve_t;
+
+
+typedef struct
+{
+ elliptic_curve_t E;
+ mpi_point_t Q; /* Q = [d]G */
+} ECC_public_key;
+
+typedef struct
+{
+ elliptic_curve_t E;
+ mpi_point_t Q;
+ gcry_mpi_t d;
+} ECC_secret_key;
+
+
+/* This tables defines aliases for curve names. */
+static const struct
+{
+ const char *name; /* Our name. */
+ const char *other; /* Other name. */
+} curve_aliases[] =
+ {
+ { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */
+ { "NIST P-192", "prime192v1" }, /* X9.62 name. */
+ { "NIST P-192", "secp192r1" }, /* SECP name. */
+
+ { "NIST P-224", "secp224r1" },
+ { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */
+
+ { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */
+ { "NIST P-256", "prime256v1" },
+ { "NIST P-256", "secp256r1" },
+
+ { "NIST P-384", "secp384r1" },
+ { "NIST P-384", "1.3.132.0.34" },
+
+ { "NIST P-521", "secp521r1" },
+ { "NIST P-521", "1.3.132.0.35" },
+
+ { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
+ { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
+ { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
+ { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
+ { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
+ { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
+ { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
+
+ { NULL, NULL}
+ };
+
+typedef struct {
+ const char *desc; /* Description of the curve. */
+ unsigned int nbits; /* Number of bits. */
+ unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */
+ const char *p; /* Order of the prime field. */
+ const char *a, *b; /* The coefficients. */
+ const char *n; /* The order of the base point. */
+ const char *g_x, *g_y; /* Base point. */
+} ecc_domain_parms_t;
+
+/* This static table defines all available curves. */
+static const ecc_domain_parms_t domain_parms[] =
+ {
+ {
+ "NIST P-192", 192, 1,
+ "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+ "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+ "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+ "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+ "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+ },
+ {
+ "NIST P-224", 224, 1,
+ "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+ "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+ "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+ "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+ "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+ "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+ },
+ {
+ "NIST P-256", 256, 1,
+ "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+ "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+ "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+ "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+ "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+ "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+ },
+ {
+ "NIST P-384", 384, 1,
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000ffffffff",
+ "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+ "ffffffff0000000000000000fffffffc",
+ "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+ "c656398d8a2ed19d2a85c8edd3ec2aef",
+ "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+ "581a0db248b0a77aecec196accc52973",
+
+ "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+ "5502f25dbf55296c3a545e3872760ab7",
+ "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+ "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+ },
+ {
+ "NIST P-521", 521, 1,
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+ "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+ "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+ "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+ "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
+ "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+ "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
+ "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+ },
+
+ { "brainpoolP160r1", 160, 0,
+ "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
+ "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
+ "0x1e589a8595423412134faa2dbdec95c8d8675e58",
+ "0xe95e4a5f737059dc60df5991d45029409e60fc09",
+ "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
+ "0x1667cb477a1a8ec338f94741669c976316da6321"
+ },
+
+ { "brainpoolP192r1", 192, 0,
+ "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
+ "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
+ "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
+ "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
+ "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
+ "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
+ },
+
+ { "brainpoolP224r1", 224, 0,
+ "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
+ "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
+ "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
+ "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
+ "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
+ "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
+ },
+
+ { "brainpoolP256r1", 256, 0,
+ "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
+ "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
+ "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
+ "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
+ "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
+ "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
+ },
+
+ { "brainpoolP320r1", 320, 0,
+ "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
+ "fcd412b1f1b32e27",
+ "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
+ "92f375a97d860eb4",
+ "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
+ "6f5eb4ac8fb1f1a6",
+ "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
+ "8691555b44c59311",
+ "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
+ "10af8d0d39e20611",
+ "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
+ "d35245d1692e8ee1"
+ },
+
+ { "brainpoolP384r1", 384, 0,
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
+ "acd3a729901d1a71874700133107ec53",
+ "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
+ "8aa5814a503ad4eb04a8c7dd22ce2826",
+ "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
+ "7cb4390295dbc9943ab78696fa504c11",
+ "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
+ "cf3ab6af6b7fc3103b883202e9046565",
+ "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
+ "e826e03436d646aaef87b2e247d4af1e",
+ "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
+ "0e4646217791811142820341263c5315"
+ },
+
+ { "brainpoolP512r1", 512, 0,
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
+ "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
+ "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
+ "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
+ "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
+ "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
+ "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
+ "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
+ "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
+ "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
+ "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
+ "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
+ },
+
+ { NULL, 0, 0, NULL, NULL, NULL, NULL }
+ };
+
+
+/* Registered progress function and its callback value. */
+static void (*progress_cb) (void *, const char*, int, int, int);
+static void *progress_cb_data;
+
+
+#define point_init(a) _gcry_mpi_ec_point_init ((a))
+#define point_free(a) _gcry_mpi_ec_point_free ((a))
+
+
+\f
+/* Local prototypes. */
+static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
+static void test_keys (ECC_secret_key * sk, unsigned int nbits);
+static int check_secret_key (ECC_secret_key * sk);
+static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
+ gcry_mpi_t r, gcry_mpi_t s);
+static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
+ gcry_mpi_t r, gcry_mpi_t s);
+
+
+static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
+
+
+
+\f
+void
+_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+/* static void */
+/* progress (int c) */
+/* { */
+/* if (progress_cb) */
+/* progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */
+/* } */
+
+
+\f
+
+/* Set the value from S into D. */
+static void
+point_set (mpi_point_t *d, mpi_point_t *s)
+{
+ mpi_set (d->x, s->x);
+ mpi_set (d->y, s->y);
+ mpi_set (d->z, s->z);
+}
+
+
+/*
+ * Release a curve object.
+ */
+static void
+curve_free (elliptic_curve_t *E)
+{
+ mpi_free (E->p); E->p = NULL;
+ mpi_free (E->a); E->a = NULL;
+ mpi_free (E->b); E->b = NULL;
+ point_free (&E->G);
+ mpi_free (E->n); E->n = NULL;
+}
+
+
+/*
+ * Return a copy of a curve object.
+ */
+static elliptic_curve_t
+curve_copy (elliptic_curve_t E)
+{
+ elliptic_curve_t R;
+
+ R.p = mpi_copy (E.p);
+ R.a = mpi_copy (E.a);
+ R.b = mpi_copy (E.b);
+ point_init (&R.G);
+ point_set (&R.G, &E.G);
+ R.n = mpi_copy (E.n);
+
+ return R;
+}
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t val;
+
+ err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
+ return val;
+}
+
+
+
+\f
+
+/****************
+ * Solve the right side of the equation that defines a curve.
+ */
+static gcry_mpi_t
+gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
+{
+ gcry_mpi_t three, x_3, axb, y;
+
+ three = mpi_alloc_set_ui (3);
+ x_3 = mpi_new (0);
+ axb = mpi_new (0);
+ y = mpi_new (0);
+
+ mpi_powm (x_3, x, three, base->p);
+ mpi_mulm (axb, base->a, x, base->p);
+ mpi_addm (axb, axb, base->b, base->p);
+ mpi_addm (y, x_3, axb, base->p);
+
+ mpi_free (x_3);
+ mpi_free (axb);
+ mpi_free (three);
+ return y; /* The quadratic value of the coordinate if it exist. */
+}
+
+
+/* Generate a random secret scalar k with an order of p
+
+ At the beginning this was identical to the code is in elgamal.c.
+ Later imporved by mmr. Further simplified by wk. */
+static gcry_mpi_t
+gen_k (gcry_mpi_t p, int security_level)
+{
+ gcry_mpi_t k;
+ unsigned int nbits;
+
+ nbits = mpi_get_nbits (p);
+ k = mpi_snew (nbits);
+ if (DBG_CIPHER)
+ log_debug ("choosing a random k of %u bits at seclevel %d\n",
+ nbits, security_level);
+
+ gcry_mpi_randomize (k, nbits, security_level);
+
+ mpi_mod (k, k, p); /* k = k mod p */
+
+ return k;
+}
+
+
+/* Generate the crypto system setup. This function takes the NAME of
+ a curve or the desired number of bits and stores at R_CURVE the
+ parameters of the named curve or those of a suitable curve. The
+ chosen number of bits is stored on R_NBITS. */
+static gpg_err_code_t
+fill_in_curve (unsigned int nbits, const char *name,
+ elliptic_curve_t *curve, unsigned int *r_nbits)
+{
+ int idx, aliasno;
+ const char *resname = NULL; /* Set to a found curve name. */
+
+ if (name)
+ {
+ /* First check our native curves. */
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (!strcmp (name, domain_parms[idx].desc))
+ {
+ resname = domain_parms[idx].desc;
+ break;
+ }
+ /* If not found consult the alias table. */
+ if (!domain_parms[idx].desc)
+ {
+ for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
+ if (!strcmp (name, curve_aliases[aliasno].other))
+ break;
+ if (curve_aliases[aliasno].name)
+ {
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (!strcmp (curve_aliases[aliasno].name,
+ domain_parms[idx].desc))
+ {
+ resname = domain_parms[idx].desc;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ if (nbits == domain_parms[idx].nbits)
+ break;
+ }
+ if (!domain_parms[idx].desc)
+ return GPG_ERR_INV_VALUE;
+
+ /* In fips mode we only support NIST curves. Note that it is
+ possible to bypass this check by specifying the curve parameters
+ directly. */
+ if (fips_mode () && !domain_parms[idx].fips )
+ return GPG_ERR_NOT_SUPPORTED;
+
+ *r_nbits = domain_parms[idx].nbits;
+ curve->p = scanval (domain_parms[idx].p);
+ curve->a = scanval (domain_parms[idx].a);
+ curve->b = scanval (domain_parms[idx].b);
+ curve->n = scanval (domain_parms[idx].n);
+ curve->G.x = scanval (domain_parms[idx].g_x);
+ curve->G.y = scanval (domain_parms[idx].g_y);
+ curve->G.z = mpi_alloc_set_ui (1);
+ curve->name = resname;
+
+ return 0;
+}
+
+
+/*
+ * First obtain the setup. Over the finite field randomize an scalar
+ * secret value, and calculate the public point.
+ */
+static gpg_err_code_t
+generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
+ int transient_key,
+ gcry_mpi_t g_x, gcry_mpi_t g_y,
+ gcry_mpi_t q_x, gcry_mpi_t q_y,
+ const char **r_usedcurve)
+{
+ gpg_err_code_t err;
+ elliptic_curve_t E;
+ gcry_mpi_t d;
+ mpi_point_t Q;
+ mpi_ec_t ctx;
+ gcry_random_level_t random_level;
+
+ *r_usedcurve = NULL;
+
+ err = fill_in_curve (nbits, name, &E, &nbits);
+ if (err)
+ return err;
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecgen curve p", E.p);
+ log_mpidump ("ecgen curve a", E.a);
+ log_mpidump ("ecgen curve b", E.b);
+ log_mpidump ("ecgen curve n", E.n);
+ log_mpidump ("ecgen curve Gx", E.G.x);
+ log_mpidump ("ecgen curve Gy", E.G.y);
+ log_mpidump ("ecgen curve Gz", E.G.z);
+ if (E.name)
+ log_debug ("ecgen curve used: %s\n", E.name);
+ }
+
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+ d = gen_k (E.n, random_level);
+
+ /* Compute Q. */
+ point_init (&Q);
+ ctx = _gcry_mpi_ec_init (E.p, E.a);
+ _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
+
+ /* Copy the stuff to the key structures. */
+ sk->E.p = mpi_copy (E.p);
+ sk->E.a = mpi_copy (E.a);
+ sk->E.b = mpi_copy (E.b);
+ point_init (&sk->E.G);
+ point_set (&sk->E.G, &E.G);
+ sk->E.n = mpi_copy (E.n);
+ point_init (&sk->Q);
+ point_set (&sk->Q, &Q);
+ sk->d = mpi_copy (d);
+ /* We also return copies of G and Q in affine coordinates if
+ requested. */
+ if (g_x && g_y)
+ {
+ if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
+ log_fatal ("ecgen: Failed to get affine coordinates\n");
+ }
+ if (q_x && q_y)
+ {
+ if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
+ log_fatal ("ecgen: Failed to get affine coordinates\n");
+ }
+ _gcry_mpi_ec_free (ctx);
+
+ point_free (&Q);
+ mpi_free (d);
+
+ *r_usedcurve = E.name;
+ curve_free (&E);
+
+ /* Now we can test our keys (this should never fail!). */
+ test_keys (sk, nbits - 64);
+
+ return 0;
+}
+
+
+/*
+ * To verify correct skey it use a random information.
+ * First, encrypt and decrypt this dummy value,
+ * test if the information is recuperated.
+ * Second, test with the sign and verify functions.
+ */
+static void
+test_keys (ECC_secret_key *sk, unsigned int nbits)
+{
+ ECC_public_key pk;
+ gcry_mpi_t test = mpi_new (nbits);
+ mpi_point_t R_;
+ gcry_mpi_t c = mpi_new (nbits);
+ gcry_mpi_t out = mpi_new (nbits);
+ gcry_mpi_t r = mpi_new (nbits);
+ gcry_mpi_t s = mpi_new (nbits);
+
+ if (DBG_CIPHER)
+ log_debug ("Testing key.\n");
+
+ point_init (&R_);
+
+ pk.E = curve_copy (sk->E);
+ point_init (&pk.Q);
+ point_set (&pk.Q, &sk->Q);
+
+ gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+
+ if (sign (test, sk, r, s) )
+ log_fatal ("ECDSA operation: sign failed\n");
+
+ if (verify (test, &pk, r, s))
+ {
+ log_fatal ("ECDSA operation: sign, verify failed\n");
+ }
+
+ if (DBG_CIPHER)
+ log_debug ("ECDSA operation: sign, verify ok.\n");
+
+ point_free (&pk.Q);
+ curve_free (&pk.E);
+
+ point_free (&R_);
+ mpi_free (s);
+ mpi_free (r);
+ mpi_free (out);
+ mpi_free (c);
+ mpi_free (test);
+}
+
+
+/*
+ * To check the validity of the value, recalculate the correspondence
+ * between the public value and the secret one.
+ */
+static int
+check_secret_key (ECC_secret_key * sk)
+{
+ mpi_point_t Q;
+ gcry_mpi_t y_2, y2 = mpi_alloc (0);
+ mpi_ec_t ctx;
+
+ /* ?primarity test of 'p' */
+ /* (...) //!! */
+ /* G in E(F_p) */
+ y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */
+ mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */
+ if (mpi_cmp (y_2, y2))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
+ return (1);
+ }
+ /* G != PaI */
+ if (!mpi_cmp_ui (sk->E.G.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
+ return (1);
+ }
+
+ point_init (&Q);
+ ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
+ _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
+ if (mpi_cmp_ui (Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("check_secret_key: E is not a curve of order n\n");
+ point_free (&Q);
+ _gcry_mpi_ec_free (ctx);
+ return 1;
+ }
+ /* pubkey cannot be PaI */
+ if (!mpi_cmp_ui (sk->Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+ _gcry_mpi_ec_free (ctx);
+ return (1);
+ }
+ /* pubkey = [d]G over E */
+ _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
+ if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
+ {
+ if (DBG_CIPHER)
+ log_debug
+ ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+ _gcry_mpi_ec_free (ctx);
+ return (1);
+ }
+ _gcry_mpi_ec_free (ctx);
+ point_free (&Q);
+ return 0;
+}
+
+
+/*
+ * Return the signature struct (r,s) from the message hash. The caller
+ * must have allocated R and S.
+ */
+static gpg_err_code_t
+sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t err = 0;
+ gcry_mpi_t k, dr, sum, k_1, x;
+ mpi_point_t I;
+ mpi_ec_t ctx;
+
+ if (DBG_CIPHER)
+ log_mpidump ("ecdsa sign hash ", input );
+
+ k = NULL;
+ dr = mpi_alloc (0);
+ sum = mpi_alloc (0);
+ k_1 = mpi_alloc (0);
+ x = mpi_alloc (0);
+ point_init (&I);
+
+ mpi_set_ui (s, 0);
+ mpi_set_ui (r, 0);
+
+ ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a);
+
+ while (!mpi_cmp_ui (s, 0)) /* s == 0 */
+ {
+ while (!mpi_cmp_ui (r, 0)) /* r == 0 */
+ {
+ /* Note, that we are guaranteed to enter this loop at least
+ once because r has been intialized to 0. We can't use a
+ do_while because we want to keep the value of R even if S
+ has to be recomputed. */
+ mpi_free (k);
+ k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
+ _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
+ if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc sign: Failed to get affine coordinates\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (r, x, skey->E.n); /* r = x mod n */
+ }
+ mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */
+ mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n */
+ mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */
+ mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */
+ }
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecdsa sign result r ", r);
+ log_mpidump ("ecdsa sign result s ", s);
+ }
+
+ leave:
+ _gcry_mpi_ec_free (ctx);
+ point_free (&I);
+ mpi_free (x);
+ mpi_free (k_1);
+ mpi_free (sum);
+ mpi_free (dr);
+ mpi_free (k);
+
+ return err;
+}
+
+
+/*
+ * Check if R and S verifies INPUT.
+ */
+static gpg_err_code_t
+verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
+{
+ gpg_err_code_t err = 0;
+ gcry_mpi_t h, h1, h2, x, y;
+ mpi_point_t Q, Q1, Q2;
+ mpi_ec_t ctx;
+
+ if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
+ if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
+
+ h = mpi_alloc (0);
+ h1 = mpi_alloc (0);
+ h2 = mpi_alloc (0);
+ x = mpi_alloc (0);
+ y = mpi_alloc (0);
+ point_init (&Q);
+ point_init (&Q1);
+ point_init (&Q2);
+
+ ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);
+
+ /* h = s^(-1) (mod n) */
+ mpi_invm (h, s, pkey->E.n);
+/* log_mpidump (" h", h); */
+ /* h1 = hash * s^(-1) (mod n) */
+ mpi_mulm (h1, input, h, pkey->E.n);
+/* log_mpidump (" h1", h1); */
+ /* Q1 = [ hash * s^(-1) ]G */
+ _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
+/* log_mpidump ("Q1.x", Q1.x); */
+/* log_mpidump ("Q1.y", Q1.y); */
+/* log_mpidump ("Q1.z", Q1.z); */
+ /* h2 = r * s^(-1) (mod n) */
+ mpi_mulm (h2, r, h, pkey->E.n);
+/* log_mpidump (" h2", h2); */
+ /* Q2 = [ r * s^(-1) ]Q */
+ _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
+/* log_mpidump ("Q2.x", Q2.x); */
+/* log_mpidump ("Q2.y", Q2.y); */
+/* log_mpidump ("Q2.z", Q2.z); */
+ /* Q = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
+ _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
+/* log_mpidump (" Q.x", Q.x); */
+/* log_mpidump (" Q.y", Q.y); */
+/* log_mpidump (" Q.z", Q.z); */
+
+ if (!mpi_cmp_ui (Q.z, 0))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Rejected\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
+ {
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Failed to get affine coordinates\n");
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
+ if (mpi_cmp (x, r)) /* x != r */
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" x", x);
+ log_mpidump (" y", y);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ log_debug ("ecc verify: Not verified\n");
+ }
+ err = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+ if (DBG_CIPHER)
+ log_debug ("ecc verify: Accepted\n");
+
+ leave:
+ _gcry_mpi_ec_free (ctx);
+ point_free (&Q2);
+ point_free (&Q1);
+ point_free (&Q);
+ mpi_free (y);
+ mpi_free (x);
+ mpi_free (h2);
+ mpi_free (h1);
+ mpi_free (h);
+ return err;
+}
+
+
+\f
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+static gcry_mpi_t
+ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
+{
+ gpg_error_t err;
+ int pbytes = (mpi_get_nbits (p)+7)/8;
+ size_t n;
+ unsigned char *buf, *ptr;
+ gcry_mpi_t result;
+
+ buf = gcry_xmalloc ( 1 + 2*pbytes );
+ *buf = 04; /* Uncompressed point. */
+ ptr = buf+1;
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
+ if (err)
+ log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
+ if (n < pbytes)
+ {
+ memmove (ptr+(pbytes-n), ptr, n);
+ memset (ptr, 0, (pbytes-n));
+ }
+ ptr += pbytes;
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
+ if (err)
+ log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
+ if (n < pbytes)
+ {
+ memmove (ptr+(pbytes-n), ptr, n);
+ memset (ptr, 0, (pbytes-n));
+ }
+
+ err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
+ if (err)
+ log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
+ gcry_free (buf);
+
+ return result;
+}
+
+
+/* RESULT must have been initialized and is set on success to the
+ point given by VALUE. */
+static gcry_error_t
+os2ec (mpi_point_t *result, gcry_mpi_t value)
+{
+ gcry_error_t err;
+ size_t n;
+ unsigned char *buf;
+ gcry_mpi_t x, y;
+
+ n = (mpi_get_nbits (value)+7)/8;
+ buf = gcry_xmalloc (n);
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
+ if (err)
+ {
+ gcry_free (buf);
+ return err;
+ }
+ if (n < 1)
+ {
+ gcry_free (buf);
+ return GPG_ERR_INV_OBJ;
+ }
+ if (*buf != 4)
+ {
+ gcry_free (buf);
+ return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */
+ }
+ if ( ((n-1)%2) )
+ {
+ gcry_free (buf);
+ return GPG_ERR_INV_OBJ;
+ }
+ n = (n-1)/2;
+ err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
+ if (err)
+ {
+ gcry_free (buf);
+ return err;
+ }
+ err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
+ gcry_free (buf);
+ if (err)
+ {
+ mpi_free (x);
+ return err;
+ }
+
+ mpi_set (result->x, x);
+ mpi_set (result->y, y);
+ mpi_set_ui (result->z, 1);
+
+ mpi_free (x);
+ mpi_free (y);
+
+ return 0;
+}
+
+
+/* Extended version of ecc_generate. */
+static gcry_err_code_t
+ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+ gcry_sexp_t *r_extrainfo)
+{
+ gpg_err_code_t ec;
+ ECC_secret_key sk;
+ gcry_mpi_t g_x, g_y, q_x, q_y;
+ char *curve_name = NULL;
+ gcry_sexp_t l1;
+ int transient_key = 0;
+ const char *usedcurve = NULL;
+
+ (void)algo;
+ (void)evalue;
+
+ if (genparms)
+ {
+ /* Parse the optional "curve" parameter. */
+ l1 = gcry_sexp_find_token (genparms, "curve", 0);
+ if (l1)
+ {
+ curve_name = _gcry_sexp_nth_string (l1, 1);
+ gcry_sexp_release (l1);
+ if (!curve_name)
+ return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
+ }
+
+ /* Parse the optional transient-key flag. */
+ l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ transient_key = 1;
+ gcry_sexp_release (l1);
+ }
+ }
+
+ /* NBITS is required if no curve name has been given. */
+ if (!nbits && !curve_name)
+ return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
+
+ g_x = mpi_new (0);
+ g_y = mpi_new (0);
+ q_x = mpi_new (0);
+ q_y = mpi_new (0);
+ ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
+ &usedcurve);
+ gcry_free (curve_name);
+ if (ec)
+ return ec;
+ if (usedcurve) /* Fixme: No error return checking. */
+ gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
+
+ skey[0] = sk.E.p;
+ skey[1] = sk.E.a;
+ skey[2] = sk.E.b;
+ skey[3] = ec2os (g_x, g_y, sk.E.p);
+ skey[4] = sk.E.n;
+ skey[5] = ec2os (q_x, q_y, sk.E.p);
+ skey[6] = sk.d;
+
+ mpi_free (g_x);
+ mpi_free (g_y);
+ mpi_free (q_x);
+ mpi_free (q_y);
+
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+
+ /* Make an empty list of factors. */
+ *retfactors = gcry_calloc ( 1, sizeof **retfactors );
+ if (!*retfactors)
+ return gpg_err_code_from_syserror (); /* Fixme: relase mem? */
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecgen result p", skey[0]);
+ log_mpidump ("ecgen result a", skey[1]);
+ log_mpidump ("ecgen result b", skey[2]);
+ log_mpidump ("ecgen result G", skey[3]);
+ log_mpidump ("ecgen result n", skey[4]);
+ log_mpidump ("ecgen result Q", skey[5]);
+ log_mpidump ("ecgen result d", skey[6]);
+ }
+
+ return 0;
+}
+
+
+static gcry_err_code_t
+ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+ (void)evalue;
+ return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+}
+
+
+/* Return the parameters of the curve NAME in an MPI array. */
+static gcry_err_code_t
+ecc_get_param (const char *name, gcry_mpi_t *pkey)
+{
+ gpg_err_code_t err;
+ unsigned int nbits;
+ elliptic_curve_t E;
+ mpi_ec_t ctx;
+ gcry_mpi_t g_x, g_y;
+
+ err = fill_in_curve (0, name, &E, &nbits);
+ if (err)
+ return err;
+
+ g_x = mpi_new (0);
+ g_y = mpi_new (0);
+ ctx = _gcry_mpi_ec_init (E.p, E.a);
+ if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
+ log_fatal ("ecc get param: Failed to get affine coordinates\n");
+ _gcry_mpi_ec_free (ctx);
+ point_free (&E.G);
+
+ pkey[0] = E.p;
+ pkey[1] = E.a;
+ pkey[2] = E.b;
+ pkey[3] = ec2os (g_x, g_y, E.p);
+ pkey[4] = E.n;
+ pkey[5] = NULL;
+
+ mpi_free (g_x);
+ mpi_free (g_y);
+
+ return 0;
+}
+
+
+/* Return the parameters of the curve NAME as an S-expression. */
+static gcry_sexp_t
+ecc_get_param_sexp (const char *name)
+{
+ gcry_mpi_t pkey[6];
+ gcry_sexp_t result;
+ int i;
+
+ if (ecc_get_param (name, pkey))
+ return NULL;
+
+ if (gcry_sexp_build (&result, NULL,
+ "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
+ pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
+ result = NULL;
+
+ for (i=0; pkey[i]; i++)
+ gcry_mpi_release (pkey[i]);
+
+ return result;
+}
+
+
+/* Return the name matching the parameters in PKEY. */
+static const char *
+ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits)
+{
+ gpg_err_code_t err;
+ elliptic_curve_t E;
+ int idx;
+ gcry_mpi_t tmp;
+ const char *result = NULL;
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ if (!pkey)
+ {
+ idx = iterator;
+ if (idx >= 0 && idx < DIM (domain_parms))
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ }
+ return result;
+ }
+
+ if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4])
+ return NULL;
+
+ E.p = pkey[0];
+ E.a = pkey[1];
+ E.b = pkey[2];
+ point_init (&E.G);
+ err = os2ec (&E.G, pkey[3]);
+ if (err)
+ {
+ point_free (&E.G);
+ return NULL;
+ }
+ E.n = pkey[4];
+
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ {
+ tmp = scanval (domain_parms[idx].p);
+ if (!mpi_cmp (tmp, E.p))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].a);
+ if (!mpi_cmp (tmp, E.a))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].b);
+ if (!mpi_cmp (tmp, E.b))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].n);
+ if (!mpi_cmp (tmp, E.n))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_x);
+ if (!mpi_cmp (tmp, E.G.x))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_y);
+ if (!mpi_cmp (tmp, E.G.y))
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ mpi_free (tmp);
+ }
+
+ point_free (&E.G);
+
+ return result;
+}
+
+
+static gcry_err_code_t
+ecc_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+ gpg_err_code_t err;
+ ECC_secret_key sk;
+
+ (void)algo;
+
+ /* FIXME: This check looks a bit fishy: Now long is the array? */
+ if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
+ || !skey[6])
+ return GPG_ERR_BAD_MPI;
+
+ sk.E.p = skey[0];
+ sk.E.a = skey[1];
+ sk.E.b = skey[2];
+ point_init (&sk.E.G);
+ err = os2ec (&sk.E.G, skey[3]);
+ if (err)
+ {
+ point_free (&sk.E.G);
+ return err;
+ }
+ sk.E.n = skey[4];
+ point_init (&sk.Q);
+ err = os2ec (&sk.Q, skey[5]);
+ if (err)
+ {
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return err;
+ }
+
+ sk.d = skey[6];
+
+ if (check_secret_key (&sk))
+ {
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return GPG_ERR_BAD_SECKEY;
+ }
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return 0;
+}
+
+
+static gcry_err_code_t
+ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+ gpg_err_code_t err;
+ ECC_secret_key sk;
+
+ (void)algo;
+
+ if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
+ || !skey[5] || !skey[6] )
+ return GPG_ERR_BAD_MPI;
+
+ sk.E.p = skey[0];
+ sk.E.a = skey[1];
+ sk.E.b = skey[2];
+ point_init (&sk.E.G);
+ err = os2ec (&sk.E.G, skey[3]);
+ if (err)
+ {
+ point_free (&sk.E.G);
+ return err;
+ }
+ sk.E.n = skey[4];
+ point_init (&sk.Q);
+ err = os2ec (&sk.Q, skey[5]);
+ if (err)
+ {
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return err;
+ }
+ sk.d = skey[6];
+
+ resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
+ resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
+ err = sign (data, &sk, resarr[0], resarr[1]);
+ if (err)
+ {
+ mpi_free (resarr[0]);
+ mpi_free (resarr[1]);
+ resarr[0] = NULL; /* Mark array as released. */
+ }
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return err;
+}
+
+
+static gcry_err_code_t
+ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+ int (*cmp)(void *, gcry_mpi_t), void *opaquev)
+{
+ gpg_err_code_t err;
+ ECC_public_key pk;
+
+ (void)algo;
+ (void)cmp;
+ (void)opaquev;
+
+ if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
+ || !pkey[3] || !pkey[4] || !pkey[5] )
+ return GPG_ERR_BAD_MPI;
+
+ pk.E.p = pkey[0];
+ pk.E.a = pkey[1];
+ pk.E.b = pkey[2];
+ point_init (&pk.E.G);
+ err = os2ec (&pk.E.G, pkey[3]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ return err;
+ }
+ pk.E.n = pkey[4];
+ point_init (&pk.Q);
+ err = os2ec (&pk.Q, pkey[5]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+ return err;
+ }
+
+ err = verify (hash, &pk, data[0], data[1]);
+
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+ return err;
+}
+
+
+/* ecdh raw is classic 2-round DH protocol published in 1976.
+ *
+ * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
+ *
+ * As with any PK operation, encrypt version uses a public key and
+ * decrypt -- private.
+ *
+ * Symbols used below:
+ * G - field generator point
+ * d - private long-term scalar
+ * dG - public long-term key
+ * k - ephemeral scalar
+ * kG - ephemeral public key
+ * dkG - shared secret
+ *
+ * ecc_encrypt_raw description:
+ * input:
+ * data[0] : private scalar (k)
+ * output:
+ * result[0] : shared point (kdG)
+ * result[1] : generated ephemeral public key (kG)
+ *
+ * ecc_decrypt_raw description:
+ * input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * result[0] : shared point (kdG)
+ */
+static gcry_err_code_t
+ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
+ gcry_mpi_t *pkey, int flags)
+{
+ ECC_public_key pk;
+ mpi_ec_t ctx;
+ gcry_mpi_t result[2];
+ int err;
+
+ (void)algo;
+ (void)flags;
+
+ if (!k
+ || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
+ return GPG_ERR_BAD_MPI;
+
+ pk.E.p = pkey[0];
+ pk.E.a = pkey[1];
+ pk.E.b = pkey[2];
+ point_init (&pk.E.G);
+ err = os2ec (&pk.E.G, pkey[3]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ return err;
+ }
+ pk.E.n = pkey[4];
+ point_init (&pk.Q);
+ err = os2ec (&pk.Q, pkey[5]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+ return err;
+ }
+
+ ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a);
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
+ {
+ mpi_point_t R; /* Result that we return. */
+ gcry_mpi_t x, y;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+
+ point_init (&R);
+
+ /* R = kQ <=> R = kdG */
+ _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
+
+ result[0] = ec2os (x, y, pk.E.p);
+
+ /* R = kG */
+ _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
+
+ result[1] = ec2os (x, y, pk.E.p);
+
+ mpi_free (x);
+ mpi_free (y);
+
+ point_free (&R);
+ }
+
+ _gcry_mpi_ec_free (ctx);
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+
+ if (!result[0] || !result[1])
+ {
+ mpi_free (result[0]);
+ mpi_free (result[1]);
+ return GPG_ERR_ENOMEM;
+ }
+
+ /* Success. */
+ resarr[0] = result[0];
+ resarr[1] = result[1];
+
+ return 0;
+}
+
+/* input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * resaddr[0] : shared point kdG
+ *
+ * see ecc_encrypt_raw for details.
+ */
+static gcry_err_code_t
+ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags)
+{
+ ECC_secret_key sk;
+ mpi_point_t R; /* Result that we return. */
+ mpi_point_t kG;
+ mpi_ec_t ctx;
+ gcry_mpi_t r;
+ int err;
+
+ (void)algo;
+ (void)flags;
+
+ *result = NULL;
+
+ if (!data || !data[0]
+ || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
+ || !skey[5] || !skey[6] )
+ return GPG_ERR_BAD_MPI;
+
+ point_init (&kG);
+ err = os2ec (&kG, data[0]);
+ if (err)
+ {
+ point_free (&kG);
+ return err;
+ }
+
+
+ sk.E.p = skey[0];
+ sk.E.a = skey[1];
+ sk.E.b = skey[2];
+ point_init (&sk.E.G);
+ err = os2ec (&sk.E.G, skey[3]);
+ if (err)
+ {
+ point_free (&kG);
+ point_free (&sk.E.G);
+ return err;
+ }
+ sk.E.n = skey[4];
+ point_init (&sk.Q);
+ err = os2ec (&sk.Q, skey[5]);
+ if (err)
+ {
+ point_free (&kG);
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return err;
+ }
+ sk.d = skey[6];
+
+ ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
+
+ /* R = dkG */
+ point_init (&R);
+ _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
+
+ point_free (&kG);
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */
+ {
+ gcry_mpi_t x, y;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates\n");
+
+ r = ec2os (x, y, sk.E.p);
+ mpi_free (x);
+ mpi_free (y);
+ }
+
+ point_free (&R);
+ _gcry_mpi_ec_free (ctx);
+ point_free (&kG);
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+
+ if (!r)
+ return GPG_ERR_ENOMEM;
+
+ /* Success. */
+
+ *result = r;
+
+ return 0;
+}
+
+
+static unsigned int
+ecc_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+ (void)algo;
+
+ return mpi_get_nbits (pkey[0]);
+}
+
+
+/* See rsa.c for a description of this function. */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+{
+#define N_COMPONENTS 6
+ static const char names[N_COMPONENTS+1] = "pabgnq";
+ gpg_err_code_t ec = 0;
+ gcry_sexp_t l1;
+ gcry_mpi_t values[N_COMPONENTS];
+ int idx;
+
+ /* Clear the values for easier error cleanup. */
+ for (idx=0; idx < N_COMPONENTS; idx++)
+ values[idx] = NULL;
+
+ /* Fill values with all provided parameters. */
+ for (idx=0; idx < N_COMPONENTS; idx++)
+ {
+ l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
+ if (l1)
+ {
+ values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ if (!values[idx])
+ {
+ ec = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ }
+ }
+
+ /* Check whether a curve parameter is available and use that to fill
+ in missing values. */
+ l1 = gcry_sexp_find_token (keyparam, "curve", 5);
+ if (l1)
+ {
+ char *curve;
+ gcry_mpi_t tmpvalues[N_COMPONENTS];
+
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ tmpvalues[idx] = NULL;
+
+ curve = _gcry_sexp_nth_string (l1, 1);
+ gcry_sexp_release (l1);
+ if (!curve)
+ {
+ ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
+ goto leave;
+ }
+ ec = ecc_get_param (curve, tmpvalues);
+ gcry_free (curve);
+ if (ec)
+ goto leave;
+
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ {
+ if (!values[idx])
+ values[idx] = tmpvalues[idx];
+ else
+ mpi_free (tmpvalues[idx]);
+ }
+ }
+
+ /* Check that all parameters are known and normalize all MPIs (that
+ should not be required but we use an internal function later and
+ thus we better make 100% sure that they are normalized). */
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ if (!values[idx])
+ {
+ ec = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ else
+ _gcry_mpi_normalize (values[idx]);
+
+ /* Hash them all. */
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ {
+ char buf[30];
+ unsigned char *rawmpi;
+ unsigned int rawmpilen;
+
+ rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
+ if (!rawmpi)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
+ gcry_md_write (md, buf, strlen (buf));
+ gcry_md_write (md, rawmpi, rawmpilen);
+ gcry_md_write (md, ")", 1);
+ gcry_free (rawmpi);
+ }
+
+ leave:
+ for (idx = 0; idx < N_COMPONENTS; idx++)
+ _gcry_mpi_release (values[idx]);
+
+ return ec;
+#undef N_COMPONENTS
+}
+
+
+
+
+\f
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_ecdsa (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "low-level";
+ errtxt = NULL; /*selftest ();*/
+ if (errtxt)
+ goto failed;
+
+ /* FIXME: need more tests. */
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ (void)extended;
+
+ switch (algo)
+ {
+ case GCRY_PK_ECDSA:
+ ec = selftests_ecdsa (report);
+ break;
+ default:
+ ec = GPG_ERR_PUBKEY_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static const char *ecdsa_names[] =
+ {
+ "ecdsa",
+ "ecc",
+ NULL,
+ };
+static const char *ecdh_names[] =
+ {
+ "ecdh",
+ "ecc",
+ NULL,
+ };
+
+gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
+ {
+ "ECDSA", ecdsa_names,
+ "pabgnq", "pabgnqd", "", "rs", "pabgnq",
+ GCRY_PK_USAGE_SIGN,
+ ecc_generate,
+ ecc_check_secret_key,
+ NULL,
+ NULL,
+ ecc_sign,
+ ecc_verify,
+ ecc_get_nbits
+ };
+
+gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
+ {
+ "ECDH", ecdh_names,
+ "pabgnq", "pabgnqd", "se", "", "pabgnq",
+ GCRY_PK_USAGE_ENCR,
+ ecc_generate,
+ ecc_check_secret_key,
+ ecc_encrypt_raw,
+ ecc_decrypt_raw,
+ NULL,
+ NULL,
+ ecc_get_nbits
+ };
+
+
+pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
+ {
+ run_selftests,
+ ecc_generate_ext,
+ compute_keygrip,
+ ecc_get_param,
+ ecc_get_curve,
+ ecc_get_param_sexp
+ };
--- /dev/null
+/* Elgamal.c - Elgamal Public Key encryption
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * For a description of the algorithm, see:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9. Pages 476 ff.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+} ELG_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t p; /* prime */
+ gcry_mpi_t g; /* group generator */
+ gcry_mpi_t y; /* g^x mod p */
+ gcry_mpi_t x; /* secret exponent */
+} ELG_secret_key;
+
+
+static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
+static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
+static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
+static int check_secret_key (ELG_secret_key *sk);
+static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_public_key *pkey);
+static void decrypt (gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b,
+ ELG_secret_key *skey);
+static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_secret_key *skey);
+static int verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
+ ELG_public_key *pkey);
+
+
+static void (*progress_cb) (void *, const char *, int, int, int);
+static void *progress_cb_data;
+
+void
+_gcry_register_pk_elg_progress (void (*cb) (void *, const char *,
+ int, int, int),
+ void *cb_data)
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress (int c)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, "pk_elg", c, 0, 0);
+}
+
+
+/****************
+ * Michael Wiener's table on subgroup sizes to match field sizes.
+ * (floating around somewhere, probably based on the paper from
+ * Eurocrypt 96, page 332)
+ */
+static unsigned int
+wiener_map( unsigned int n )
+{
+ static struct { unsigned int p_n, q_n; } t[] =
+ { /* p q attack cost */
+ { 512, 119 }, /* 9 x 10^17 */
+ { 768, 145 }, /* 6 x 10^21 */
+ { 1024, 165 }, /* 7 x 10^24 */
+ { 1280, 183 }, /* 3 x 10^27 */
+ { 1536, 198 }, /* 7 x 10^29 */
+ { 1792, 212 }, /* 9 x 10^31 */
+ { 2048, 225 }, /* 8 x 10^33 */
+ { 2304, 237 }, /* 5 x 10^35 */
+ { 2560, 249 }, /* 3 x 10^37 */
+ { 2816, 259 }, /* 1 x 10^39 */
+ { 3072, 269 }, /* 3 x 10^40 */
+ { 3328, 279 }, /* 8 x 10^41 */
+ { 3584, 288 }, /* 2 x 10^43 */
+ { 3840, 296 }, /* 4 x 10^44 */
+ { 4096, 305 }, /* 7 x 10^45 */
+ { 4352, 313 }, /* 1 x 10^47 */
+ { 4608, 320 }, /* 2 x 10^48 */
+ { 4864, 328 }, /* 2 x 10^49 */
+ { 5120, 335 }, /* 3 x 10^50 */
+ { 0, 0 }
+ };
+ int i;
+
+ for(i=0; t[i].p_n; i++ )
+ {
+ if( n <= t[i].p_n )
+ return t[i].q_n;
+ }
+ /* Not in table - use an arbitrary high number. */
+ return n / 8 + 200;
+}
+
+static int
+test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
+{
+ ELG_public_key pk;
+ gcry_mpi_t test = gcry_mpi_new ( 0 );
+ gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
+ gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
+ gcry_mpi_t out2 = gcry_mpi_new ( nbits );
+ int failed = 0;
+
+ pk.p = sk->p;
+ pk.g = sk->g;
+ pk.y = sk->y;
+
+ gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
+
+ do_encrypt ( out1_a, out1_b, test, &pk );
+ decrypt ( out2, out1_a, out1_b, sk );
+ if ( mpi_cmp( test, out2 ) )
+ failed |= 1;
+
+ sign ( out1_a, out1_b, test, sk );
+ if ( !verify( out1_a, out1_b, test, &pk ) )
+ failed |= 2;
+
+ gcry_mpi_release ( test );
+ gcry_mpi_release ( out1_a );
+ gcry_mpi_release ( out1_b );
+ gcry_mpi_release ( out2 );
+
+ if (failed && !nodie)
+ log_fatal ("Elgamal test key for %s %s failed\n",
+ (failed & 1)? "encrypt+decrypt":"",
+ (failed & 2)? "sign+verify":"");
+ if (failed && DBG_CIPHER)
+ log_debug ("Elgamal test key for %s %s failed\n",
+ (failed & 1)? "encrypt+decrypt":"",
+ (failed & 2)? "sign+verify":"");
+
+ return failed;
+}
+
+
+/****************
+ * Generate a random secret exponent k from prime p, so that k is
+ * relatively prime to p-1. With SMALL_K set, k will be selected for
+ * better encryption performance - this must never be used signing!
+ */
+static gcry_mpi_t
+gen_k( gcry_mpi_t p, int small_k )
+{
+ gcry_mpi_t k = mpi_alloc_secure( 0 );
+ gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) );
+ gcry_mpi_t p_1 = mpi_copy(p);
+ unsigned int orig_nbits = mpi_get_nbits(p);
+ unsigned int nbits, nbytes;
+ char *rndbuf = NULL;
+
+ if (small_k)
+ {
+ /* Using a k much lesser than p is sufficient for encryption and
+ * it greatly improves the encryption performance. We use
+ * Wiener's table and add a large safety margin. */
+ nbits = wiener_map( orig_nbits ) * 3 / 2;
+ if( nbits >= orig_nbits )
+ BUG();
+ }
+ else
+ nbits = orig_nbits;
+
+
+ nbytes = (nbits+7)/8;
+ if( DBG_CIPHER )
+ log_debug("choosing a random k ");
+ mpi_sub_ui( p_1, p, 1);
+ for(;;)
+ {
+ if( !rndbuf || nbits < 32 )
+ {
+ gcry_free(rndbuf);
+ rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
+ }
+ else
+ {
+ /* Change only some of the higher bits. We could improve
+ this by directly requesting more memory at the first call
+ to get_random_bytes() and use this the here maybe it is
+ easier to do this directly in random.c Anyway, it is
+ highly inlikely that we will ever reach this code. */
+ char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+ memcpy( rndbuf, pp, 4 );
+ gcry_free(pp);
+ }
+ _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+
+ for(;;)
+ {
+ if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
+ {
+ if( DBG_CIPHER )
+ progress('+');
+ break; /* no */
+ }
+ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
+ {
+ if( DBG_CIPHER )
+ progress('-');
+ break; /* no */
+ }
+ if (gcry_mpi_gcd( temp, k, p_1 ))
+ goto found; /* okay, k is relative prime to (p-1) */
+ mpi_add_ui( k, k, 1 );
+ if( DBG_CIPHER )
+ progress('.');
+ }
+ }
+ found:
+ gcry_free(rndbuf);
+ if( DBG_CIPHER )
+ progress('\n');
+ mpi_free(p_1);
+ mpi_free(temp);
+
+ return k;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS
+ * Returns: 2 structures filled with all needed values
+ * and an array with n-1 factors of (p-1)
+ */
+static void
+generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
+{
+ gcry_mpi_t p; /* the prime */
+ gcry_mpi_t p_min1;
+ gcry_mpi_t g;
+ gcry_mpi_t x; /* the secret exponent */
+ gcry_mpi_t y;
+ unsigned int qbits;
+ unsigned int xbits;
+ byte *rndbuf;
+
+ p_min1 = gcry_mpi_new ( nbits );
+ qbits = wiener_map( nbits );
+ if( qbits & 1 ) /* better have a even one */
+ qbits++;
+ g = mpi_alloc(1);
+ p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors );
+ mpi_sub_ui(p_min1, p, 1);
+
+
+ /* Select a random number which has these properties:
+ * 0 < x < p-1
+ * This must be a very good random number because this is the
+ * secret part. The prime is public and may be shared anyway,
+ * so a random generator level of 1 is used for the prime.
+ *
+ * I don't see a reason to have a x of about the same size
+ * as the p. It should be sufficient to have one about the size
+ * of q or the later used k plus a large safety margin. Decryption
+ * will be much faster with such an x.
+ */
+ xbits = qbits * 3 / 2;
+ if( xbits >= nbits )
+ BUG();
+ x = gcry_mpi_snew ( xbits );
+ if( DBG_CIPHER )
+ log_debug("choosing a random x of size %u", xbits );
+ rndbuf = NULL;
+ do
+ {
+ if( DBG_CIPHER )
+ progress('.');
+ if( rndbuf )
+ { /* Change only some of the higher bits */
+ if( xbits < 16 ) /* should never happen ... */
+ {
+ gcry_free(rndbuf);
+ rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
+ GCRY_VERY_STRONG_RANDOM );
+ }
+ else
+ {
+ char *r = gcry_random_bytes_secure( 2,
+ GCRY_VERY_STRONG_RANDOM );
+ memcpy(rndbuf, r, 2 );
+ gcry_free(r);
+ }
+ }
+ else
+ {
+ rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
+ GCRY_VERY_STRONG_RANDOM );
+ }
+ _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
+ mpi_clear_highbit( x, xbits+1 );
+ }
+ while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
+ gcry_free(rndbuf);
+
+ y = gcry_mpi_new (nbits);
+ gcry_mpi_powm( y, g, x, p );
+
+ if( DBG_CIPHER )
+ {
+ progress('\n');
+ log_mpidump("elg p= ", p );
+ log_mpidump("elg g= ", g );
+ log_mpidump("elg y= ", y );
+ log_mpidump("elg x= ", x );
+ }
+
+ /* Copy the stuff to the key structures */
+ sk->p = p;
+ sk->g = g;
+ sk->y = y;
+ sk->x = x;
+
+ gcry_mpi_release ( p_min1 );
+
+ /* Now we can test our keys (this should never fail!) */
+ test_keys ( sk, nbits - 64, 0 );
+}
+
+
+/* Generate a key pair with a key of size NBITS not using a random
+ value for the secret key but the one given as X. This is useful to
+ implement a passphrase based decryption for a public key based
+ encryption. It has appliactions in backup systems.
+
+ Returns: A structure filled with all needed values and an array
+ with n-1 factors of (p-1). */
+static gcry_err_code_t
+generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
+ gcry_mpi_t **ret_factors )
+{
+ gcry_mpi_t p; /* The prime. */
+ gcry_mpi_t p_min1; /* The prime minus 1. */
+ gcry_mpi_t g; /* The generator. */
+ gcry_mpi_t y; /* g^x mod p. */
+ unsigned int qbits;
+ unsigned int xbits;
+
+ sk->p = NULL;
+ sk->g = NULL;
+ sk->y = NULL;
+ sk->x = NULL;
+
+ /* Do a quick check to see whether X is suitable. */
+ xbits = mpi_get_nbits (x);
+ if ( xbits < 64 || xbits >= nbits )
+ return GPG_ERR_INV_VALUE;
+
+ p_min1 = gcry_mpi_new ( nbits );
+ qbits = wiener_map ( nbits );
+ if ( (qbits & 1) ) /* Better have an even one. */
+ qbits++;
+ g = mpi_alloc (1);
+ p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors );
+ mpi_sub_ui (p_min1, p, 1);
+
+ if (DBG_CIPHER)
+ log_debug ("using a supplied x of size %u", xbits );
+ if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
+ {
+ gcry_mpi_release ( p_min1 );
+ gcry_mpi_release ( p );
+ gcry_mpi_release ( g );
+ return GPG_ERR_INV_VALUE;
+ }
+
+ y = gcry_mpi_new (nbits);
+ gcry_mpi_powm ( y, g, x, p );
+
+ if ( DBG_CIPHER )
+ {
+ progress ('\n');
+ log_mpidump ("elg p= ", p );
+ log_mpidump ("elg g= ", g );
+ log_mpidump ("elg y= ", y );
+ log_mpidump ("elg x= ", x );
+ }
+
+ /* Copy the stuff to the key structures */
+ sk->p = p;
+ sk->g = g;
+ sk->y = y;
+ sk->x = gcry_mpi_copy (x);
+
+ gcry_mpi_release ( p_min1 );
+
+ /* Now we can test our keys. */
+ if ( test_keys ( sk, nbits - 64, 1 ) )
+ {
+ gcry_mpi_release ( sk->p ); sk->p = NULL;
+ gcry_mpi_release ( sk->g ); sk->g = NULL;
+ gcry_mpi_release ( sk->y ); sk->y = NULL;
+ gcry_mpi_release ( sk->x ); sk->x = NULL;
+ return GPG_ERR_BAD_SECKEY;
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Test whether the secret key is valid.
+ * Returns: if this is a valid key.
+ */
+static int
+check_secret_key( ELG_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
+
+ gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+ rc = !mpi_cmp( y, sk->y );
+ mpi_free( y );
+ return rc;
+}
+
+
+static void
+do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+ gcry_mpi_t k;
+
+ /* Note: maybe we should change the interface, so that it
+ * is possible to check that input is < p and return an
+ * error code.
+ */
+
+ k = gen_k( pkey->p, 1 );
+ gcry_mpi_powm( a, pkey->g, k, pkey->p );
+ /* b = (y^k * input) mod p
+ * = ((y^k mod p) * (input mod p)) mod p
+ * and because input is < p
+ * = ((y^k mod p) * input) mod p
+ */
+ gcry_mpi_powm( b, pkey->y, k, pkey->p );
+ gcry_mpi_mulm( b, b, input, pkey->p );
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump("elg encrypted y= ", pkey->y);
+ log_mpidump("elg encrypted p= ", pkey->p);
+ log_mpidump("elg encrypted k= ", k);
+ log_mpidump("elg encrypted M= ", input);
+ log_mpidump("elg encrypted a= ", a);
+ log_mpidump("elg encrypted b= ", b);
+ }
+#endif
+ mpi_free(k);
+}
+
+
+
+
+static void
+decrypt(gcry_mpi_t output, gcry_mpi_t a, gcry_mpi_t b, ELG_secret_key *skey )
+{
+ gcry_mpi_t t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
+
+ /* output = b/(a^x) mod p */
+ gcry_mpi_powm( t1, a, skey->x, skey->p );
+ mpi_invm( t1, t1, skey->p );
+ mpi_mulm( output, b, t1, skey->p );
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump("elg decrypted x= ", skey->x);
+ log_mpidump("elg decrypted p= ", skey->p);
+ log_mpidump("elg decrypted a= ", a);
+ log_mpidump("elg decrypted b= ", b);
+ log_mpidump("elg decrypted M= ", output);
+ }
+#endif
+ mpi_free(t1);
+}
+
+
+/****************
+ * Make an Elgamal signature out of INPUT
+ */
+
+static void
+sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
+{
+ gcry_mpi_t k;
+ gcry_mpi_t t = mpi_alloc( mpi_get_nlimbs(a) );
+ gcry_mpi_t inv = mpi_alloc( mpi_get_nlimbs(a) );
+ gcry_mpi_t p_1 = mpi_copy(skey->p);
+
+ /*
+ * b = (t * inv) mod (p-1)
+ * b = (t * inv(k,(p-1),(p-1)) mod (p-1)
+ * b = (((M-x*a) mod (p-1)) * inv(k,(p-1),(p-1))) mod (p-1)
+ *
+ */
+ mpi_sub_ui(p_1, p_1, 1);
+ k = gen_k( skey->p, 0 /* no small K ! */ );
+ gcry_mpi_powm( a, skey->g, k, skey->p );
+ mpi_mul(t, skey->x, a );
+ mpi_subm(t, input, t, p_1 );
+ mpi_invm(inv, k, p_1 );
+ mpi_mulm(b, t, inv, p_1 );
+
+#if 0
+ if( DBG_CIPHER )
+ {
+ log_mpidump("elg sign p= ", skey->p);
+ log_mpidump("elg sign g= ", skey->g);
+ log_mpidump("elg sign y= ", skey->y);
+ log_mpidump("elg sign x= ", skey->x);
+ log_mpidump("elg sign k= ", k);
+ log_mpidump("elg sign M= ", input);
+ log_mpidump("elg sign a= ", a);
+ log_mpidump("elg sign b= ", b);
+ }
+#endif
+ mpi_free(k);
+ mpi_free(t);
+ mpi_free(inv);
+ mpi_free(p_1);
+}
+
+
+/****************
+ * Returns true if the signature composed of A and B is valid.
+ */
+static int
+verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
+{
+ int rc;
+ gcry_mpi_t t1;
+ gcry_mpi_t t2;
+ gcry_mpi_t base[4];
+ gcry_mpi_t ex[4];
+
+ if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
+ return 0; /* assertion 0 < a < p failed */
+
+ t1 = mpi_alloc( mpi_get_nlimbs(a) );
+ t2 = mpi_alloc( mpi_get_nlimbs(a) );
+
+#if 0
+ /* t1 = (y^a mod p) * (a^b mod p) mod p */
+ gcry_mpi_powm( t1, pkey->y, a, pkey->p );
+ gcry_mpi_powm( t2, a, b, pkey->p );
+ mpi_mulm( t1, t1, t2, pkey->p );
+
+ /* t2 = g ^ input mod p */
+ gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+ rc = !mpi_cmp( t1, t2 );
+#elif 0
+ /* t1 = (y^a mod p) * (a^b mod p) mod p */
+ base[0] = pkey->y; ex[0] = a;
+ base[1] = a; ex[1] = b;
+ base[2] = NULL; ex[2] = NULL;
+ mpi_mulpowm( t1, base, ex, pkey->p );
+
+ /* t2 = g ^ input mod p */
+ gcry_mpi_powm( t2, pkey->g, input, pkey->p );
+
+ rc = !mpi_cmp( t1, t2 );
+#else
+ /* t1 = g ^ - input * y ^ a * a ^ b mod p */
+ mpi_invm(t2, pkey->g, pkey->p );
+ base[0] = t2 ; ex[0] = input;
+ base[1] = pkey->y; ex[1] = a;
+ base[2] = a; ex[2] = b;
+ base[3] = NULL; ex[3] = NULL;
+ mpi_mulpowm( t1, base, ex, pkey->p );
+ rc = !mpi_cmp_ui( t1, 1 );
+
+#endif
+
+ mpi_free(t1);
+ mpi_free(t2);
+ return rc;
+}
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gpg_err_code_t
+elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+ gcry_sexp_t *r_extrainfo)
+{
+ gpg_err_code_t ec;
+ ELG_secret_key sk;
+ gcry_mpi_t xvalue = NULL;
+ gcry_sexp_t l1;
+
+ (void)algo;
+ (void)evalue;
+ (void)r_extrainfo;
+
+ if (genparms)
+ {
+ /* Parse the optional xvalue element. */
+ l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
+ if (l1)
+ {
+ xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
+ gcry_sexp_release (l1);
+ if (!xvalue)
+ return GPG_ERR_BAD_MPI;
+ }
+ }
+
+ if (xvalue)
+ ec = generate_using_x (&sk, nbits, xvalue, retfactors);
+ else
+ {
+ generate (&sk, nbits, retfactors);
+ ec = 0;
+ }
+
+ skey[0] = sk.p;
+ skey[1] = sk.g;
+ skey[2] = sk.y;
+ skey[3] = sk.x;
+
+ return ec;
+}
+
+
+static gcry_err_code_t
+elg_generate (int algo, unsigned int nbits, unsigned long evalue,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+ ELG_secret_key sk;
+
+ (void)algo;
+ (void)evalue;
+
+ generate (&sk, nbits, retfactors);
+ skey[0] = sk.p;
+ skey[1] = sk.g;
+ skey[2] = sk.y;
+ skey[3] = sk.x;
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+elg_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ ELG_secret_key sk;
+
+ (void)algo;
+
+ if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ sk.p = skey[0];
+ sk.g = skey[1];
+ sk.y = skey[2];
+ sk.x = skey[3];
+
+ if (! check_secret_key (&sk))
+ err = GPG_ERR_BAD_SECKEY;
+ }
+
+ return err;
+}
+
+
+static gcry_err_code_t
+elg_encrypt (int algo, gcry_mpi_t *resarr,
+ gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ ELG_public_key pk;
+
+ (void)algo;
+ (void)flags;
+
+ if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ pk.p = pkey[0];
+ pk.g = pkey[1];
+ pk.y = pkey[2];
+ resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
+ resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
+ do_encrypt (resarr[0], resarr[1], data, &pk);
+ }
+ return err;
+}
+
+
+static gcry_err_code_t
+elg_decrypt (int algo, gcry_mpi_t *result,
+ gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ ELG_secret_key sk;
+
+ (void)algo;
+ (void)flags;
+
+ if ((! data[0]) || (! data[1])
+ || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ sk.p = skey[0];
+ sk.g = skey[1];
+ sk.y = skey[2];
+ sk.x = skey[3];
+ *result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
+ decrypt (*result, data[0], data[1], &sk);
+ }
+ return err;
+}
+
+
+static gcry_err_code_t
+elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ ELG_secret_key sk;
+
+ (void)algo;
+
+ if ((! data)
+ || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ sk.p = skey[0];
+ sk.g = skey[1];
+ sk.y = skey[2];
+ sk.x = skey[3];
+ resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
+ resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
+ sign (resarr[0], resarr[1], data, &sk);
+ }
+
+ return err;
+}
+
+
+static gcry_err_code_t
+elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ ELG_public_key pk;
+
+ (void)algo;
+ (void)cmp;
+ (void)opaquev;
+
+ if ((! data[0]) || (! data[1]) || (! hash)
+ || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
+ err = GPG_ERR_BAD_MPI;
+ else
+ {
+ pk.p = pkey[0];
+ pk.g = pkey[1];
+ pk.y = pkey[2];
+ if (! verify (data[0], data[1], hash, &pk))
+ err = GPG_ERR_BAD_SIGNATURE;
+ }
+
+ return err;
+}
+
+
+static unsigned int
+elg_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+ (void)algo;
+
+ return mpi_get_nbits (pkey[0]);
+}
+
+
+static const char *elg_names[] =
+ {
+ "elg",
+ "openpgp-elg",
+ "openpgp-elg-sig",
+ NULL,
+ };
+
+
+gcry_pk_spec_t _gcry_pubkey_spec_elg =
+ {
+ "ELG", elg_names,
+ "pgy", "pgyx", "ab", "rs", "pgy",
+ GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+ elg_generate,
+ elg_check_secret_key,
+ elg_encrypt,
+ elg_decrypt,
+ elg_sign,
+ elg_verify,
+ elg_get_nbits
+ };
+
+pk_extra_spec_t _gcry_pubkey_extraspec_elg =
+ {
+ NULL,
+ elg_generate_ext,
+ NULL
+ };
--- /dev/null
+/* hash-common.c - Common code for hash algorithms
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "hash-common.h"
+
+
+/* Run a selftest for hash algorithm ALGO. If the resulting digest
+ matches EXPECT/EXPECTLEN and everything else is fine as well,
+ return NULL. If an error occurs, return a static text string
+ describing the error.
+
+ DATAMODE controls what will be hashed according to this table:
+
+ 0 - Hash the supplied DATA of DATALEN.
+ 1 - Hash one million times a 'a'. DATA and DATALEN are ignored.
+
+*/
+const char *
+_gcry_hash_selftest_check_one (int algo,
+ int datamode, const void *data, size_t datalen,
+ const void *expect, size_t expectlen)
+{
+ const char *result = NULL;
+ gcry_error_t err = 0;
+ gcry_md_hd_t hd;
+ unsigned char *digest;
+
+ if (_gcry_md_get_algo_dlen (algo) != expectlen)
+ return "digest size does not match expected size";
+
+ err = _gcry_md_open (&hd, algo, 0);
+ if (err)
+ return "gcry_md_open failed";
+
+ switch (datamode)
+ {
+ case 0:
+ _gcry_md_write (hd, data, datalen);
+ break;
+
+ case 1: /* Hash one million times an "a". */
+ {
+ char aaa[1000];
+ int i;
+
+ /* Write in odd size chunks so that we test the buffering. */
+ memset (aaa, 'a', 1000);
+ for (i = 0; i < 1000; i++)
+ _gcry_md_write (hd, aaa, 1000);
+ }
+ break;
+
+ default:
+ result = "invalid DATAMODE";
+ }
+
+ if (!result)
+ {
+ digest = _gcry_md_read (hd, algo);
+
+ if ( memcmp (digest, expect, expectlen) )
+ result = "digest mismatch";
+ }
+
+ _gcry_md_close (hd);
+
+ return result;
+}
--- /dev/null
+/* hash-common.h - Declarations of common code for hash algorithms.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_HASH_COMMON_H
+#define GCRY_HASH_COMMON_H
+
+
+const char * _gcry_hash_selftest_check_one
+/**/ (int algo,
+ int datamode, const void *data, size_t datalen,
+ const void *expect, size_t expectlen);
+
+
+
+
+
+#endif /*GCRY_HASH_COMMON_H*/
--- /dev/null
+/* hmac-tests.c - HMAC selftests.
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ Although algorithm self-tests are usually implemented in the module
+ implementing the algorithm, the case for HMAC is different because
+ HMAC is implemnetd on a higher level using a special feature of the
+ gcry_md_ functions. It would be possible to do this also in the
+ digest algorithm modules, but that would blow up the code too much
+ and spread the hmac tests over several modules.
+
+ Thus we implement all HMAC tests in this test module and provide a
+ function to run the tests.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "hmac256.h"
+
+/* Check one HMAC with digest ALGO using the regualr HAMC
+ API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key
+ and (EXPECT,EXPECTLEN) the expected result. Returns NULL on
+ succdess or a string describing the failure. */
+static const char *
+check_one (int algo,
+ const void *data, size_t datalen,
+ const void *key, size_t keylen,
+ const void *expect, size_t expectlen)
+{
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+
+/* printf ("HMAC algo %d\n", algo); */
+ if (_gcry_md_get_algo_dlen (algo) != expectlen)
+ return "invalid tests data";
+ if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC))
+ return "gcry_md_open failed";
+ if (_gcry_md_setkey (hd, key, keylen))
+ {
+ _gcry_md_close (hd);
+ return "gcry_md_setkey failed";
+ }
+ _gcry_md_write (hd, data, datalen);
+ digest = _gcry_md_read (hd, algo);
+ if (!digest)
+ {
+ _gcry_md_close (hd);
+ return "gcry_md_read failed";
+ }
+ if (memcmp (digest, expect, expectlen))
+ {
+/* int i; */
+
+/* fputs (" {", stdout); */
+/* for (i=0; i < expectlen-1; i++) */
+/* { */
+/* if (i && !(i % 8)) */
+/* fputs ("\n ", stdout); */
+/* printf (" 0x%02x,", digest[i]); */
+/* } */
+/* printf (" 0x%02x } },\n", digest[i]); */
+
+ _gcry_md_close (hd);
+ return "does not match";
+ }
+ _gcry_md_close (hd);
+ return NULL;
+}
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ unsigned char key[128];
+ int i, j;
+
+ what = "FIPS-198a, A.1";
+ for (i=0; i < 64; i++)
+ key[i] = i;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #1", 9,
+ key, 64,
+ "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+ "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "FIPS-198a, A.2";
+ for (i=0, j=0x30; i < 20; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #2", 9,
+ key, 20,
+ "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
+ "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
+ if (errtxt)
+ goto failed;
+
+ what = "FIPS-198a, A.3";
+ for (i=0, j=0x50; i < 100; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #3", 9,
+ key, 100,
+ "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
+ "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
+ if (errtxt)
+ goto failed;
+
+ what = "FIPS-198a, A.4";
+ for (i=0, j=0x70; i < 49; i++)
+ key[i] = j++;
+ errtxt = check_one (GCRY_MD_SHA1,
+ "Sample #4", 9,
+ key, 49,
+ "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
+ "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 );
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA1, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[28];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
+ 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
+ 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00,
+ 0x8f, 0xd0, 0x5e, 0x44 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19,
+ 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f,
+ 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f,
+ 0x53, 0x68, 0x4b, 0x22 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6,
+ 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64,
+ 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1,
+ 0xec, 0x83, 0x33, 0xea } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac,
+ 0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c,
+ 0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d,
+ 0xe7, 0xaf, 0xec, 0x5a } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad,
+ 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2,
+ 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27,
+ 0x3f, 0xa6, 0x87, 0x0e } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02,
+ 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd,
+ 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9,
+ 0xf6, 0xf5, 0x65, 0xd1 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA224,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect) );
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA224, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[32];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ hmac256_context_t hmachd;
+ const unsigned char *digest;
+ size_t dlen;
+
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA256,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect) );
+ if (errtxt)
+ goto failed;
+
+ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+ if (!hmachd)
+ {
+ errtxt = "_gcry_hmac256_new failed";
+ goto failed;
+ }
+ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+ digest = _gcry_hmac256_finalize (hmachd, &dlen);
+ if (!digest)
+ {
+ errtxt = "_gcry_hmac256_finalize failed";
+ _gcry_hmac256_release (hmachd);
+ goto failed;
+ }
+ if (dlen != DIM (tv[tvidx].expect)
+ || memcmp (digest, tv[tvidx].expect, DIM (tv[tvidx].expect)))
+ {
+ errtxt = "does not match in second implementation";
+ _gcry_hmac256_release (hmachd);
+ goto failed;
+ }
+ _gcry_hmac256_release (hmachd);
+
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA256, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[48];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
+ 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
+ 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47,
+ 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e,
+ 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7,
+ 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
+ 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
+ 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
+ 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
+ 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
+ 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a,
+ 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f,
+ 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb,
+ 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b,
+ 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9,
+ 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85,
+ 0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7,
+ 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c,
+ 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e,
+ 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79,
+ 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90,
+ 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4,
+ 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f,
+ 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6,
+ 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82,
+ 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d,
+ 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c,
+ 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a,
+ 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5,
+ 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d,
+ 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA384,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect) );
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA384, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const char expect[64];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
+ 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
+ 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6,
+ 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54,
+ 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a,
+ 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd,
+ 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b,
+ 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
+ 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
+ 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
+ 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
+ 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
+ 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
+ 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
+ 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84,
+ 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9,
+ 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36,
+ 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39,
+ 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8,
+ 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07,
+ 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26,
+ 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69,
+ 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7,
+ 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d,
+ 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb,
+ 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4,
+ 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63,
+ 0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d,
+ 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb,
+ 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4,
+ 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1,
+ 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52,
+ 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98,
+ 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52,
+ 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec,
+ 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba,
+ 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd,
+ 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86,
+ 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44,
+ 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1,
+ 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15,
+ 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60,
+ 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } },
+
+ { NULL }
+ };
+ const char *what;
+ const char *errtxt;
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ what = tv[tvidx].desc;
+ errtxt = check_one (GCRY_MD_SHA512,
+ tv[tvidx].data, strlen (tv[tvidx].data),
+ tv[tvidx].key, strlen (tv[tvidx].key),
+ tv[tvidx].expect, DIM (tv[tvidx].expect) );
+ if (errtxt)
+ goto failed;
+ if (!extended)
+ break;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("hmac", GCRY_MD_SHA512, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA1:
+ ec = selftests_sha1 (extended, report);
+ break;
+ case GCRY_MD_SHA224:
+ ec = selftests_sha224 (extended, report);
+ break;
+ case GCRY_MD_SHA256:
+ ec = selftests_sha256 (extended, report);
+ break;
+ case GCRY_MD_SHA384:
+ ec = selftests_sha384 (extended, report);
+ break;
+ case GCRY_MD_SHA512:
+ ec = selftests_sha512 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+ }
+ return ec;
+}
+
+
+
+
+/* Run the selftests for HMAC with digest algorithm ALGO with optional
+ reporting function REPORT. */
+gpg_error_t
+_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_err_code_t ec = 0;
+
+ if (!gcry_md_test_algo (algo))
+ {
+ ec = run_selftests (algo, extended, report);
+ }
+ else
+ {
+ ec = GPG_ERR_DIGEST_ALGO;
+ if (report)
+ report ("hmac", algo, "module", "algorithm not available");
+ }
+ return gpg_error (ec);
+}
--- /dev/null
+/* kdf.c - Key Derivation Functions
+ * Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide an HASHALGO, a valid ALGO and depending on that algo a
+ SALT of 8 bytes and the number of ITERATIONS. Code taken from
+ gnupg/agent/protect.c:hash_passphrase. */
+gpg_err_code_t
+openpgp_s2k (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ char *key = keybuffer;
+ int pass, i;
+ int used = 0;
+ int secmode;
+
+ if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ && (!salt || saltlen != 8))
+ return GPG_ERR_INV_VALUE;
+
+ secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+
+ ec = gpg_err_code (gcry_md_open (&md, hashalgo,
+ secmode? GCRY_MD_FLAG_SECURE : 0));
+ if (ec)
+ return ec;
+
+ for (pass=0; used < keysize; pass++)
+ {
+ if (pass)
+ {
+ gcry_md_reset (md);
+ for (i=0; i < pass; i++) /* Preset the hash context. */
+ gcry_md_putc (md, 0);
+ }
+
+ if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ int len2 = passphraselen + 8;
+ unsigned long count = len2;
+
+ if (algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ count = iterations;
+ if (count < len2)
+ count = len2;
+ }
+
+ while (count > len2)
+ {
+ gcry_md_write (md, salt, saltlen);
+ gcry_md_write (md, passphrase, passphraselen);
+ count -= len2;
+ }
+ if (count < saltlen)
+ gcry_md_write (md, salt, count);
+ else
+ {
+ gcry_md_write (md, salt, saltlen);
+ count -= saltlen;
+ gcry_md_write (md, passphrase, count);
+ }
+ }
+ else
+ gcry_md_write (md, passphrase, passphraselen);
+
+ gcry_md_final (md);
+ i = gcry_md_get_algo_dlen (hashalgo);
+ if (i > keysize - used)
+ i = keysize - used;
+ memcpy (key+used, gcry_md_read (md, hashalgo), i);
+ used += i;
+ }
+ gcry_md_close (md);
+ return 0;
+}
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide PRFALGO which indicates the pseudorandom function to
+ use: This shall be the algorithms id of a hash algorithm; it is
+ used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS
+ gives the number of iterations. */
+gpg_err_code_t
+pkdf2 (const void *passphrase, size_t passphraselen,
+ int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ int secmode;
+ unsigned int dklen = keysize;
+ char *dk = keybuffer;
+ unsigned int hlen; /* Output length of the digest function. */
+ unsigned int l; /* Rounded up number of blocks. */
+ unsigned int r; /* Number of octets in the last block. */
+ char *sbuf; /* Malloced buffer to concatenate salt and iter
+ as well as space to hold TBUF and UBUF. */
+ char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */
+ char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */
+ unsigned int lidx; /* Current block number. */
+ unsigned long iter; /* Current iteration number. */
+ unsigned int i;
+
+ if (!salt || !saltlen || !iterations || !dklen)
+ return GPG_ERR_INV_VALUE;
+
+ hlen = gcry_md_get_algo_dlen (hashalgo);
+ if (!hlen)
+ return GPG_ERR_DIGEST_ALGO;
+
+ secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+
+ /* We ignore step 1 from pksc5v2.1 which demands a check that dklen
+ is not larger that 0xffffffff * hlen. */
+
+ /* Step 2 */
+ l = ((dklen - 1)/ hlen) + 1;
+ r = dklen - (l - 1) * hlen;
+
+ /* Setup buffers and prepare a hash context. */
+ sbuf = (secmode
+ ? gcry_malloc_secure (saltlen + 4 + hlen + hlen)
+ : gcry_malloc (saltlen + 4 + hlen + hlen));
+ if (!sbuf)
+ return gpg_err_code_from_syserror ();
+ tbuf = sbuf + saltlen + 4;
+ ubuf = tbuf + hlen;
+
+ ec = gpg_err_code (gcry_md_open (&md, hashalgo,
+ (GCRY_MD_FLAG_HMAC
+ | (secmode?GCRY_MD_FLAG_SECURE:0))));
+ if (ec)
+ {
+ gcry_free (sbuf);
+ return ec;
+ }
+
+ /* Step 3 and 4. */
+ memcpy (sbuf, salt, saltlen);
+ for (lidx = 1; lidx <= l; lidx++)
+ {
+ for (iter = 0; iter < iterations; iter++)
+ {
+ ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen));
+ if (ec)
+ {
+ gcry_md_close (md);
+ gcry_free (sbuf);
+ return ec;
+ }
+ if (!iter) /* Compute U_1: */
+ {
+ sbuf[saltlen] = (lidx >> 24);
+ sbuf[saltlen + 1] = (lidx >> 16);
+ sbuf[saltlen + 2] = (lidx >> 8);
+ sbuf[saltlen + 3] = lidx;
+ gcry_md_write (md, sbuf, saltlen + 4);
+ memcpy (ubuf, gcry_md_read (md, 0), hlen);
+ memcpy (tbuf, ubuf, hlen);
+ }
+ else /* Compute U_(2..c): */
+ {
+ gcry_md_write (md, ubuf, hlen);
+ memcpy (ubuf, gcry_md_read (md, 0), hlen);
+ for (i=0; i < hlen; i++)
+ tbuf[i] ^= ubuf[i];
+ }
+ }
+ if (lidx == l) /* Last block. */
+ memcpy (dk, tbuf, r);
+ else
+ {
+ memcpy (dk, tbuf, hlen);
+ dk += hlen;
+ }
+ }
+
+ gcry_md_close (md);
+ gcry_free (sbuf);
+ return 0;
+}
+
+
+/* Derive a key from a passphrase. KEYSIZE gives the requested size
+ of the keys in octets. KEYBUFFER is a caller provided buffer
+ filled on success with the derived key. The input passphrase is
+ taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory
+ buffer. ALGO specifies the KDF algorithm to use; these are the
+ constants GCRY_KDF_*. SUBALGO specifies an algorithm used
+ internally by the KDF algorithms; this is usually a hash algorithm
+ but certain KDF algorithm may use it differently. {SALT,SALTLEN}
+ is a salt as needed by most KDF algorithms. ITERATIONS is a
+ positive integer parameter to most KDFs. 0 is returned on success,
+ or an error code on failure. */
+gpg_error_t
+gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+
+ if (!passphrase || !passphraselen)
+ {
+ ec = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+ if (!keybuffer || !keysize)
+ {
+ ec = GPG_ERR_INV_VALUE;
+ goto leave;
+ }
+
+
+ switch (algo)
+ {
+ case GCRY_KDF_SIMPLE_S2K:
+ case GCRY_KDF_SALTED_S2K:
+ case GCRY_KDF_ITERSALTED_S2K:
+ ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ case GCRY_KDF_PBKDF1:
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+ break;
+
+ case GCRY_KDF_PBKDF2:
+ ec = pkdf2 (passphrase, passphraselen, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ default:
+ ec = GPG_ERR_UNKNOWN_ALGORITHM;
+ break;
+ }
+
+ leave:
+ return gpg_error (ec);
+}
--- /dev/null
+/* md.c - message digest dispatcher
+ * Copyright (C) 1998, 1999, 2002, 2003, 2006,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+#include "rmd.h"
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+ field from the module specification against NULL and instead
+ directly test the respective fields of extraspecs. */
+static md_extra_spec_t dummy_extra_spec;
+
+
+/* This is the list of the digest implementations included in
+ libgcrypt. */
+static struct digest_table_entry
+{
+ gcry_md_spec_t *digest;
+ md_extra_spec_t *extraspec;
+ unsigned int algorithm;
+ int fips_allowed;
+} digest_table[] =
+ {
+#if USE_CRC
+ /* We allow the CRC algorithms even in FIPS mode because they are
+ actually no cryptographic primitives. */
+ { &_gcry_digest_spec_crc32,
+ &dummy_extra_spec, GCRY_MD_CRC32, 1 },
+ { &_gcry_digest_spec_crc32_rfc1510,
+ &dummy_extra_spec, GCRY_MD_CRC32_RFC1510, 1 },
+ { &_gcry_digest_spec_crc24_rfc2440,
+ &dummy_extra_spec, GCRY_MD_CRC24_RFC2440, 1 },
+#endif
+#if USE_MD4
+ { &_gcry_digest_spec_md4,
+ &dummy_extra_spec, GCRY_MD_MD4 },
+#endif
+#if USE_MD5
+ { &_gcry_digest_spec_md5,
+ &dummy_extra_spec, GCRY_MD_MD5, 1 },
+#endif
+#if USE_RMD160
+ { &_gcry_digest_spec_rmd160,
+ &dummy_extra_spec, GCRY_MD_RMD160 },
+#endif
+#if USE_SHA1
+ { &_gcry_digest_spec_sha1,
+ &_gcry_digest_extraspec_sha1, GCRY_MD_SHA1, 1 },
+#endif
+#if USE_SHA256
+ { &_gcry_digest_spec_sha256,
+ &_gcry_digest_extraspec_sha256, GCRY_MD_SHA256, 1 },
+ { &_gcry_digest_spec_sha224,
+ &_gcry_digest_extraspec_sha224, GCRY_MD_SHA224, 1 },
+#endif
+#if USE_SHA512
+ { &_gcry_digest_spec_sha512,
+ &_gcry_digest_extraspec_sha512, GCRY_MD_SHA512, 1 },
+ { &_gcry_digest_spec_sha384,
+ &_gcry_digest_extraspec_sha384, GCRY_MD_SHA384, 1 },
+#endif
+#if USE_TIGER
+ { &_gcry_digest_spec_tiger,
+ &dummy_extra_spec, GCRY_MD_TIGER },
+ { &_gcry_digest_spec_tiger1,
+ &dummy_extra_spec, GCRY_MD_TIGER1 },
+ { &_gcry_digest_spec_tiger2,
+ &dummy_extra_spec, GCRY_MD_TIGER2 },
+#endif
+#if USE_WHIRLPOOL
+ { &_gcry_digest_spec_whirlpool,
+ &dummy_extra_spec, GCRY_MD_WHIRLPOOL },
+#endif
+ { NULL },
+ };
+
+/* List of registered digests. */
+static gcry_module_t digests_registered;
+
+/* This is the lock protecting DIGESTS_REGISTERED. */
+static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
+
+/* Flag to check whether the default ciphers have already been
+ registered. */
+static int default_digests_registered;
+
+typedef struct gcry_md_list
+{
+ gcry_md_spec_t *digest;
+ gcry_module_t module;
+ struct gcry_md_list *next;
+ size_t actual_struct_size; /* Allocated size of this structure. */
+ PROPERLY_ALIGNED_TYPE context;
+} GcryDigestEntry;
+
+/* this structure is put right after the gcry_md_hd_t buffer, so that
+ * only one memory block is needed. */
+struct gcry_md_context
+{
+ int magic;
+ size_t actual_handle_size; /* Allocated size of this handle. */
+ int secure;
+ FILE *debug;
+ int finalized;
+ GcryDigestEntry *list;
+ byte *macpads;
+ int macpads_Bsize; /* Blocksize as used for the HMAC pads. */
+};
+
+
+#define CTX_MAGIC_NORMAL 0x11071961
+#define CTX_MAGIC_SECURE 0x16917011
+
+/* Convenient macro for registering the default digests. */
+#define REGISTER_DEFAULT_DIGESTS \
+ do \
+ { \
+ ath_mutex_lock (&digests_registered_lock); \
+ if (! default_digests_registered) \
+ { \
+ md_register_default (); \
+ default_digests_registered = 1; \
+ } \
+ ath_mutex_unlock (&digests_registered_lock); \
+ } \
+ while (0)
+
+
+static const char * digest_algo_to_string( int algo );
+static gcry_err_code_t check_digest_algo (int algo);
+static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
+ int secure, int hmac);
+static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
+static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
+static void md_close (gcry_md_hd_t a);
+static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
+static void md_final(gcry_md_hd_t a);
+static byte *md_read( gcry_md_hd_t a, int algo );
+static int md_get_algo( gcry_md_hd_t a );
+static int md_digest_length( int algo );
+static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
+static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
+static void md_stop_debug ( gcry_md_hd_t a );
+
+
+
+
+/* Internal function. Register all the ciphers included in
+ CIPHER_TABLE. Returns zero on success or an error code. */
+static void
+md_register_default (void)
+{
+ gcry_err_code_t err = 0;
+ int i;
+
+ for (i = 0; !err && digest_table[i].digest; i++)
+ {
+ if ( fips_mode ())
+ {
+ if (!digest_table[i].fips_allowed)
+ continue;
+ if (digest_table[i].algorithm == GCRY_MD_MD5
+ && _gcry_enforced_fips_mode () )
+ continue; /* Do not register in enforced fips mode. */
+ }
+
+ err = _gcry_module_add (&digests_registered,
+ digest_table[i].algorithm,
+ (void *) digest_table[i].digest,
+ (void *) digest_table[i].extraspec,
+ NULL);
+ }
+
+ if (err)
+ BUG ();
+}
+
+/* Internal callback function. */
+static int
+gcry_md_lookup_func_name (void *spec, void *data)
+{
+ gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
+ char *name = (char *) data;
+
+ return (! stricmp (digest->name, name));
+}
+
+/* Internal callback function. Used via _gcry_module_lookup. */
+static int
+gcry_md_lookup_func_oid (void *spec, void *data)
+{
+ gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
+ char *oid = (char *) data;
+ gcry_md_oid_spec_t *oid_specs = digest->oids;
+ int ret = 0, i;
+
+ if (oid_specs)
+ {
+ for (i = 0; oid_specs[i].oidstring && (! ret); i++)
+ if (! stricmp (oid, oid_specs[i].oidstring))
+ ret = 1;
+ }
+
+ return ret;
+}
+
+/* Internal function. Lookup a digest entry by it's name. */
+static gcry_module_t
+gcry_md_lookup_name (const char *name)
+{
+ gcry_module_t digest;
+
+ digest = _gcry_module_lookup (digests_registered, (void *) name,
+ gcry_md_lookup_func_name);
+
+ return digest;
+}
+
+/* Internal function. Lookup a cipher entry by it's oid. */
+static gcry_module_t
+gcry_md_lookup_oid (const char *oid)
+{
+ gcry_module_t digest;
+
+ digest = _gcry_module_lookup (digests_registered, (void *) oid,
+ gcry_md_lookup_func_oid);
+
+ return digest;
+}
+
+/* Register a new digest module whose specification can be found in
+ DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t
+_gcry_md_register (gcry_md_spec_t *digest,
+ md_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ gcry_err_code_t err = 0;
+ gcry_module_t mod;
+
+ /* We do not support module loading in fips mode. */
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ ath_mutex_lock (&digests_registered_lock);
+ err = _gcry_module_add (&digests_registered, 0,
+ (void *) digest,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
+ &mod);
+ ath_mutex_unlock (&digests_registered_lock);
+
+ if (! err)
+ {
+ *module = mod;
+ *algorithm_id = mod->mod_id;
+ }
+
+ return gcry_error (err);
+}
+
+/* Unregister the digest identified by ID, which must have been
+ registered with gcry_digest_register. */
+void
+gcry_md_unregister (gcry_module_t module)
+{
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&digests_registered_lock);
+}
+
+
+static int
+search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
+{
+ gcry_module_t module;
+ int ret = 0;
+
+ if (oid && ((! strncmp (oid, "oid.", 4))
+ || (! strncmp (oid, "OID.", 4))))
+ oid += 4;
+
+ module = gcry_md_lookup_oid (oid);
+ if (module)
+ {
+ gcry_md_spec_t *digest = module->spec;
+ int i;
+
+ for (i = 0; digest->oids[i].oidstring && !ret; i++)
+ if (! stricmp (oid, digest->oids[i].oidstring))
+ {
+ if (algorithm)
+ *algorithm = module->mod_id;
+ if (oid_spec)
+ *oid_spec = digest->oids[i];
+ ret = 1;
+ }
+ _gcry_module_release (module);
+ }
+
+ return ret;
+}
+
+/****************
+ * Map a string to the digest algo
+ */
+int
+gcry_md_map_name (const char *string)
+{
+ gcry_module_t digest;
+ int ret, algorithm = 0;
+
+ if (! string)
+ return 0;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ /* If the string starts with a digit (optionally prefixed with
+ either "OID." or "oid."), we first look into our table of ASN.1
+ object identifiers to figure out the algorithm */
+
+ ath_mutex_lock (&digests_registered_lock);
+
+ ret = search_oid (string, &algorithm, NULL);
+ if (! ret)
+ {
+ /* Not found, search a matching digest name. */
+ digest = gcry_md_lookup_name (string);
+ if (digest)
+ {
+ algorithm = digest->mod_id;
+ _gcry_module_release (digest);
+ }
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return algorithm;
+}
+
+
+/****************
+ * Map a digest algo to a string
+ */
+static const char *
+digest_algo_to_string (int algorithm)
+{
+ const char *name = NULL;
+ gcry_module_t digest;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = _gcry_module_lookup_id (digests_registered, algorithm);
+ if (digest)
+ {
+ name = ((gcry_md_spec_t *) digest->spec)->name;
+ _gcry_module_release (digest);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return name;
+}
+
+/****************
+ * This function simply returns the name of the algorithm or some constant
+ * string when there is no algo. It will never return NULL.
+ * Use the macro gcry_md_test_algo() to check whether the algorithm
+ * is valid.
+ */
+const char *
+gcry_md_algo_name (int algorithm)
+{
+ const char *s = digest_algo_to_string (algorithm);
+ return s ? s : "?";
+}
+
+
+static gcry_err_code_t
+check_digest_algo (int algorithm)
+{
+ gcry_err_code_t rc = 0;
+ gcry_module_t digest;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = _gcry_module_lookup_id (digests_registered, algorithm);
+ if (digest)
+ _gcry_module_release (digest);
+ else
+ rc = GPG_ERR_DIGEST_ALGO;
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return rc;
+}
+
+
+
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ * More algorithms may be added by md_enable(). The initial algorithm
+ * may be 0.
+ */
+static gcry_err_code_t
+md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ int bufsize = secure ? 512 : 1024;
+ struct gcry_md_context *ctx;
+ gcry_md_hd_t hd;
+ size_t n;
+
+ /* Allocate a memory area to hold the caller visible buffer with it's
+ * control information and the data required by this module. Set the
+ * context pointer at the beginning to this area.
+ * We have to use this strange scheme because we want to hide the
+ * internal data but have a variable sized buffer.
+ *
+ * +---+------+---........------+-------------+
+ * !ctx! bctl ! buffer ! private !
+ * +---+------+---........------+-------------+
+ * ! ^
+ * !---------------------------!
+ *
+ * We have to make sure that private is well aligned.
+ */
+ n = sizeof (struct gcry_md_handle) + bufsize;
+ n = ((n + sizeof (PROPERLY_ALIGNED_TYPE) - 1)
+ / sizeof (PROPERLY_ALIGNED_TYPE)) * sizeof (PROPERLY_ALIGNED_TYPE);
+
+ /* Allocate and set the Context pointer to the private data */
+ if (secure)
+ hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+ else
+ hd = gcry_malloc (n + sizeof (struct gcry_md_context));
+
+ if (! hd)
+ err = gpg_err_code_from_errno (errno);
+
+ if (! err)
+ {
+ hd->ctx = ctx = (struct gcry_md_context *) ((char *) hd + n);
+ /* Setup the globally visible data (bctl in the diagram).*/
+ hd->bufsize = n - sizeof (struct gcry_md_handle) + 1;
+ hd->bufpos = 0;
+
+ /* Initialize the private data. */
+ memset (hd->ctx, 0, sizeof *hd->ctx);
+ ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+ ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
+ ctx->secure = secure;
+
+ if (hmac)
+ {
+ switch (algo)
+ {
+ case GCRY_MD_SHA384:
+ case GCRY_MD_SHA512:
+ ctx->macpads_Bsize = 128;
+ break;
+ default:
+ ctx->macpads_Bsize = 64;
+ break;
+ }
+ ctx->macpads = gcry_malloc_secure (2*(ctx->macpads_Bsize));
+ if (!ctx->macpads)
+ {
+ err = gpg_err_code_from_errno (errno);
+ md_close (hd);
+ }
+ }
+ }
+
+ if (! err)
+ {
+ /* Hmmm, should we really do that? - yes [-wk] */
+ _gcry_fast_random_poll ();
+
+ if (algo)
+ {
+ err = md_enable (hd, algo);
+ if (err)
+ md_close (hd);
+ }
+ }
+
+ if (! err)
+ *h = hd;
+
+ return err;
+}
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. H is guaranteed to be a valid handle or NULL on
+ error. */
+gcry_error_t
+gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_md_hd_t hd;
+
+ if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
+ err = GPG_ERR_INV_ARG;
+ else
+ {
+ err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
+ (flags & GCRY_MD_FLAG_HMAC));
+ }
+
+ *h = err? NULL : hd;
+ return gcry_error (err);
+}
+
+
+
+static gcry_err_code_t
+md_enable (gcry_md_hd_t hd, int algorithm)
+{
+ struct gcry_md_context *h = hd->ctx;
+ gcry_md_spec_t *digest = NULL;
+ GcryDigestEntry *entry;
+ gcry_module_t module;
+ gcry_err_code_t err = 0;
+
+ for (entry = h->list; entry; entry = entry->next)
+ if (entry->module->mod_id == algorithm)
+ return err; /* already enabled */
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ module = _gcry_module_lookup_id (digests_registered, algorithm);
+ ath_mutex_unlock (&digests_registered_lock);
+ if (! module)
+ {
+ log_debug ("md_enable: algorithm %d not available\n", algorithm);
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+ else
+ digest = (gcry_md_spec_t *) module->spec;
+
+
+ if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
+ {
+ _gcry_inactivate_fips_mode ("MD5 used");
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* We should never get to here because we do not register
+ MD5 in enforced fips mode. But better throw an error. */
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+ }
+
+ if (!err)
+ {
+ size_t size = (sizeof (*entry)
+ + digest->contextsize
+ - sizeof (entry->context));
+
+ /* And allocate a new list entry. */
+ if (h->secure)
+ entry = gcry_malloc_secure (size);
+ else
+ entry = gcry_malloc (size);
+
+ if (! entry)
+ err = gpg_err_code_from_errno (errno);
+ else
+ {
+ entry->digest = digest;
+ entry->module = module;
+ entry->next = h->list;
+ entry->actual_struct_size = size;
+ h->list = entry;
+
+ /* And init this instance. */
+ entry->digest->init (&entry->context.c);
+ }
+ }
+
+ if (err)
+ {
+ if (module)
+ {
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&digests_registered_lock);
+ }
+ }
+
+ return err;
+}
+
+
+gcry_error_t
+gcry_md_enable (gcry_md_hd_t hd, int algorithm)
+{
+ return gcry_error (md_enable (hd, algorithm));
+}
+
+static gcry_err_code_t
+md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ struct gcry_md_context *a = ahd->ctx;
+ struct gcry_md_context *b;
+ GcryDigestEntry *ar, *br;
+ gcry_md_hd_t bhd;
+ size_t n;
+
+ if (ahd->bufpos)
+ md_write (ahd, NULL, 0);
+
+ n = (char *) ahd->ctx - (char *) ahd;
+ if (a->secure)
+ bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+ else
+ bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
+
+ if (! bhd)
+ err = gpg_err_code_from_errno (errno);
+
+ if (! err)
+ {
+ bhd->ctx = b = (struct gcry_md_context *) ((char *) bhd + n);
+ /* No need to copy the buffer due to the write above. */
+ gcry_assert (ahd->bufsize == (n - sizeof (struct gcry_md_handle) + 1));
+ bhd->bufsize = ahd->bufsize;
+ bhd->bufpos = 0;
+ gcry_assert (! ahd->bufpos);
+ memcpy (b, a, sizeof *a);
+ b->list = NULL;
+ b->debug = NULL;
+ if (a->macpads)
+ {
+ b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
+ if (! b->macpads)
+ {
+ err = gpg_err_code_from_errno (errno);
+ md_close (bhd);
+ }
+ else
+ memcpy (b->macpads, a->macpads, (2*(a->macpads_Bsize)));
+ }
+ }
+
+ /* Copy the complete list of algorithms. The copied list is
+ reversed, but that doesn't matter. */
+ if (!err)
+ {
+ for (ar = a->list; ar; ar = ar->next)
+ {
+ if (a->secure)
+ br = gcry_malloc_secure (sizeof *br
+ + ar->digest->contextsize
+ - sizeof(ar->context));
+ else
+ br = gcry_malloc (sizeof *br
+ + ar->digest->contextsize
+ - sizeof (ar->context));
+ if (!br)
+ {
+ err = gpg_err_code_from_errno (errno);
+ md_close (bhd);
+ break;
+ }
+
+ memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
+ - sizeof (ar->context)));
+ br->next = b->list;
+ b->list = br;
+
+ /* Add a reference to the module. */
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_use (br->module);
+ ath_mutex_unlock (&digests_registered_lock);
+ }
+ }
+
+ if (a->debug && !err)
+ md_start_debug (bhd, "unknown");
+
+ if (!err)
+ *b_hd = bhd;
+
+ return err;
+}
+
+gcry_error_t
+gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
+{
+ gcry_err_code_t err;
+
+ err = md_copy (hd, handle);
+ if (err)
+ *handle = NULL;
+ return gcry_error (err);
+}
+
+/*
+ * Reset all contexts and discard any buffered stuff. This may be used
+ * instead of a md_close(); md_open().
+ */
+void
+gcry_md_reset (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r;
+
+ /* Note: We allow this even in fips non operational mode. */
+
+ a->bufpos = a->ctx->finalized = 0;
+
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ memset (r->context.c, 0, r->digest->contextsize);
+ (*r->digest->init) (&r->context.c);
+ }
+ if (a->ctx->macpads)
+ md_write (a, a->ctx->macpads, a->ctx->macpads_Bsize); /* inner pad */
+}
+
+static void
+md_close (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r, *r2;
+
+ if (! a)
+ return;
+ if (a->ctx->debug)
+ md_stop_debug (a);
+ for (r = a->ctx->list; r; r = r2)
+ {
+ r2 = r->next;
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_release (r->module);
+ ath_mutex_unlock (&digests_registered_lock);
+ wipememory (r, r->actual_struct_size);
+ gcry_free (r);
+ }
+
+ if (a->ctx->macpads)
+ {
+ wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
+ gcry_free(a->ctx->macpads);
+ }
+
+ wipememory (a, a->ctx->actual_handle_size);
+ gcry_free(a);
+}
+
+void
+gcry_md_close (gcry_md_hd_t hd)
+{
+ /* Note: We allow this even in fips non operational mode. */
+ md_close (hd);
+}
+
+static void
+md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
+{
+ GcryDigestEntry *r;
+
+ if (a->ctx->debug)
+ {
+ if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
+ BUG();
+ if (inlen && fwrite (inbuf, inlen, 1, a->ctx->debug) != 1)
+ BUG();
+ }
+
+ for (r = a->ctx->list; r; r = r->next)
+ {
+ if (a->bufpos)
+ (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
+ (*r->digest->write) (&r->context.c, inbuf, inlen);
+ }
+ a->bufpos = 0;
+}
+
+void
+gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
+{
+ md_write (hd, inbuf, inlen);
+}
+
+static void
+md_final (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r;
+
+ if (a->ctx->finalized)
+ return;
+
+ if (a->bufpos)
+ md_write (a, NULL, 0);
+
+ for (r = a->ctx->list; r; r = r->next)
+ (*r->digest->final) (&r->context.c);
+
+ a->ctx->finalized = 1;
+
+ if (a->ctx->macpads)
+ {
+ /* Finish the hmac. */
+ int algo = md_get_algo (a);
+ byte *p = md_read (a, algo);
+ size_t dlen = md_digest_length (algo);
+ gcry_md_hd_t om;
+ gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
+
+ if (err)
+ _gcry_fatal_error (err, NULL);
+ md_write (om,
+ (a->ctx->macpads)+(a->ctx->macpads_Bsize),
+ a->ctx->macpads_Bsize);
+ md_write (om, p, dlen);
+ md_final (om);
+ /* Replace our digest with the mac (they have the same size). */
+ memcpy (p, md_read (om, algo), dlen);
+ md_close (om);
+ }
+}
+
+static gcry_err_code_t
+prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
+{
+ int i;
+ int algo = md_get_algo (hd);
+ unsigned char *helpkey = NULL;
+ unsigned char *ipad, *opad;
+
+ if (!algo)
+ return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
+
+ if ( keylen > hd->ctx->macpads_Bsize )
+ {
+ helpkey = gcry_malloc_secure (md_digest_length (algo));
+ if (!helpkey)
+ return gpg_err_code_from_errno (errno);
+ gcry_md_hash_buffer (algo, helpkey, key, keylen);
+ key = helpkey;
+ keylen = md_digest_length (algo);
+ gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
+ }
+
+ memset ( hd->ctx->macpads, 0, 2*(hd->ctx->macpads_Bsize) );
+ ipad = hd->ctx->macpads;
+ opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
+ memcpy ( ipad, key, keylen );
+ memcpy ( opad, key, keylen );
+ for (i=0; i < hd->ctx->macpads_Bsize; i++ )
+ {
+ ipad[i] ^= 0x36;
+ opad[i] ^= 0x5c;
+ }
+ gcry_free (helpkey);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+gcry_error_t
+gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t rc = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_FINALIZE:
+ md_final (hd);
+ break;
+ case GCRYCTL_SET_KEY:
+ rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
+ break;
+ case GCRYCTL_START_DUMP:
+ md_start_debug (hd, buffer);
+ break;
+ case GCRYCTL_STOP_DUMP:
+ md_stop_debug ( hd );
+ break;
+ default:
+ rc = GPG_ERR_INV_OP;
+ }
+ return gcry_error (rc);
+}
+
+gcry_error_t
+gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+ gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+
+ if (!hd->ctx->macpads)
+ rc = GPG_ERR_CONFLICT;
+ else
+ {
+ rc = prepare_macpads (hd, key, keylen);
+ if (! rc)
+ gcry_md_reset (hd);
+ }
+
+ return gcry_error (rc);
+}
+
+/* The new debug interface. If SUFFIX is a string it creates an debug
+ file for the context HD. IF suffix is NULL, the file is closed and
+ debugging is stopped. */
+void
+gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+ if (suffix)
+ md_start_debug (hd, suffix);
+ else
+ md_stop_debug (hd);
+}
+
+
+
+/****************
+ * if ALGO is null get the digest for the used algo (which should be only one)
+ */
+static byte *
+md_read( gcry_md_hd_t a, int algo )
+{
+ GcryDigestEntry *r = a->ctx->list;
+
+ if (! algo)
+ {
+ /* Return the first algorithm */
+ if (r)
+ {
+ if (r->next)
+ log_debug ("more than one algorithm in md_read(0)\n");
+ return r->digest->read (&r->context.c);
+ }
+ }
+ else
+ {
+ for (r = a->ctx->list; r; r = r->next)
+ if (r->module->mod_id == algo)
+ return r->digest->read (&r->context.c);
+ }
+ BUG();
+ return NULL;
+}
+
+/*
+ * Read out the complete digest, this function implictly finalizes
+ * the hash.
+ */
+byte *
+gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+ /* This function is expected to always return a digest, thus we
+ can't return an error which we actually should do in
+ non-operational state. */
+ gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+ return md_read (hd, algo);
+}
+
+
+/*
+ * Read out an intermediate digest. Not yet functional.
+ */
+gcry_err_code_t
+gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
+{
+ (void)hd;
+ (void)algo;
+ (void)buffer;
+ (void)buflen;
+
+ /*md_digest ... */
+ fips_signal_error ("unimplemented function called");
+ return GPG_ERR_INTERNAL;
+}
+
+
+/*
+ * Shortcut function to hash a buffer with a given algo. The only
+ * guaranteed supported algorithms are RIPE-MD160 and SHA-1. The
+ * supplied digest buffer must be large enough to store the resulting
+ * hash. No error is returned, the function will abort on an invalid
+ * algo. DISABLED_ALGOS are ignored here. */
+void
+gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length)
+{
+ if (algo == GCRY_MD_SHA1)
+ _gcry_sha1_hash_buffer (digest, buffer, length);
+ else if (algo == GCRY_MD_RMD160 && !fips_mode () )
+ _gcry_rmd160_hash_buffer (digest, buffer, length);
+ else
+ {
+ /* For the others we do not have a fast function, so we use the
+ normal functions. */
+ gcry_md_hd_t h;
+ gpg_err_code_t err;
+
+ if (algo == GCRY_MD_MD5 && fips_mode ())
+ {
+ _gcry_inactivate_fips_mode ("MD5 used");
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* We should never get to here because we do not register
+ MD5 in enforced fips mode. */
+ _gcry_fips_noreturn ();
+ }
+ }
+
+ err = md_open (&h, algo, 0, 0);
+ if (err)
+ log_bug ("gcry_md_open failed for algo %d: %s",
+ algo, gpg_strerror (gcry_error(err)));
+ md_write (h, (byte *) buffer, length);
+ md_final (h);
+ memcpy (digest, md_read (h, algo), md_digest_length (algo));
+ md_close (h);
+ }
+}
+
+static int
+md_get_algo (gcry_md_hd_t a)
+{
+ GcryDigestEntry *r = a->ctx->list;
+
+ if (r && r->next)
+ {
+ fips_signal_error ("possible usage error");
+ log_error ("WARNING: more than one algorithm in md_get_algo()\n");
+ }
+ return r ? r->module->mod_id : 0;
+}
+
+int
+gcry_md_get_algo (gcry_md_hd_t hd)
+{
+ return md_get_algo (hd);
+}
+
+
+/****************
+ * Return the length of the digest
+ */
+static int
+md_digest_length (int algorithm)
+{
+ gcry_module_t digest;
+ int mdlen = 0;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = _gcry_module_lookup_id (digests_registered, algorithm);
+ if (digest)
+ {
+ mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
+ _gcry_module_release (digest);
+ }
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return mdlen;
+}
+
+/****************
+ * Return the length of the digest in bytes.
+ * This function will return 0 in case of errors.
+ */
+unsigned int
+gcry_md_get_algo_dlen (int algorithm)
+{
+ return md_digest_length (algorithm);
+}
+
+
+/* Hmmm: add a mode to enumerate the OIDs
+ * to make g10/sig-check.c more portable */
+static const byte *
+md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
+{
+ const byte *asnoid = NULL;
+ gcry_module_t digest;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ digest = _gcry_module_lookup_id (digests_registered, algorithm);
+ if (digest)
+ {
+ if (asnlen)
+ *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
+ if (mdlen)
+ *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
+ asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
+ _gcry_module_release (digest);
+ }
+ else
+ log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return asnoid;
+}
+
+
+
+/****************
+ * Return information about the given cipher algorithm
+ * WHAT select the kind of information returned:
+ * GCRYCTL_TEST_ALGO:
+ * Returns 0 when the specified algorithm is available for use.
+ * buffer and nbytes must be zero.
+ * GCRYCTL_GET_ASNOID:
+ * Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
+ * the required length is returned.
+ *
+ * Note: Because this function is in most cases used to return an
+ * integer value, we can make it easier for the caller to just look at
+ * the return value. The caller will in all cases consult the value
+ * and thereby detecting whether a error occurred or not (i.e. while checking
+ * the block size)
+ */
+gcry_error_t
+gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ switch (what)
+ {
+ case GCRYCTL_TEST_ALGO:
+ if (buffer || nbytes)
+ err = GPG_ERR_INV_ARG;
+ else
+ err = check_digest_algo (algo);
+ break;
+
+ case GCRYCTL_GET_ASNOID:
+ /* We need to check that the algo is available because
+ md_asn_oid would otherwise raise an assertion. */
+ err = check_digest_algo (algo);
+ if (!err)
+ {
+ const char unsigned *asn;
+ size_t asnlen;
+
+ asn = md_asn_oid (algo, &asnlen, NULL);
+ if (buffer && (*nbytes >= asnlen))
+ {
+ memcpy (buffer, asn, asnlen);
+ *nbytes = asnlen;
+ }
+ else if (!buffer && nbytes)
+ *nbytes = asnlen;
+ else
+ {
+ if (buffer)
+ err = GPG_ERR_TOO_SHORT;
+ else
+ err = GPG_ERR_INV_ARG;
+ }
+ }
+ break;
+
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+static void
+md_start_debug ( gcry_md_hd_t md, const char *suffix )
+{
+ static int idx=0;
+ char buf[50];
+
+ if (fips_mode ())
+ return;
+
+ if ( md->ctx->debug )
+ {
+ log_debug("Oops: md debug already started\n");
+ return;
+ }
+ idx++;
+ snprintf (buf, DIM(buf)-1, "dbgmd-%05d.%.10s", idx, suffix );
+ md->ctx->debug = fopen(buf, "w");
+ if ( !md->ctx->debug )
+ log_debug("md debug: can't open %s\n", buf );
+}
+
+static void
+md_stop_debug( gcry_md_hd_t md )
+{
+ if ( md->ctx->debug )
+ {
+ if ( md->bufpos )
+ md_write ( md, NULL, 0 );
+ fclose (md->ctx->debug);
+ md->ctx->debug = NULL;
+ }
+
+#ifdef HAVE_U64_TYPEDEF
+ { /* a kludge to pull in the __muldi3 for Solaris */
+ volatile u32 a = (u32)(ulong)md;
+ volatile u64 b = 42;
+ volatile u64 c;
+ c = a * b;
+ (void)c;
+ }
+#endif
+}
+
+
+
+/*
+ * Return information about the digest handle.
+ * GCRYCTL_IS_SECURE:
+ * Returns 1 when the handle works on secured memory
+ * otherwise 0 is returned. There is no error return.
+ * GCRYCTL_IS_ALGO_ENABLED:
+ * Returns 1 if the algo is enabled for that handle.
+ * The algo must be passed as the address of an int.
+ */
+gcry_error_t
+gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ switch (cmd)
+ {
+ case GCRYCTL_IS_SECURE:
+ *nbytes = h->ctx->secure;
+ break;
+
+ case GCRYCTL_IS_ALGO_ENABLED:
+ {
+ GcryDigestEntry *r;
+ int algo;
+
+ if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
+ err = GPG_ERR_INV_ARG;
+ else
+ {
+ algo = *(int*)buffer;
+
+ *nbytes = 0;
+ for(r=h->ctx->list; r; r = r->next ) {
+ if (r->module->mod_id == algo)
+ {
+ *nbytes = 1;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_md_init (void)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ return err;
+}
+
+
+int
+gcry_md_is_secure (gcry_md_hd_t a)
+{
+ size_t value;
+
+ if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
+ value = 1; /* It seems to be better to assume secure memory on
+ error. */
+ return value;
+}
+
+
+int
+gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+{
+ size_t value;
+
+ value = sizeof algo;
+ if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
+ value = 0;
+ return value;
+}
+
+/* Get a list consisting of the IDs of the loaded message digest
+ modules. If LIST is zero, write the number of loaded message
+ digest modules to LIST_LENGTH and return. If LIST is non-zero, the
+ first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+ of according size. In case there are less message digest modules
+ than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+ number. */
+gcry_error_t
+gcry_md_list (int *list, int *list_length)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ ath_mutex_lock (&digests_registered_lock);
+ err = _gcry_module_list (digests_registered, list, list_length);
+ ath_mutex_unlock (&digests_registered_lock);
+
+ return err;
+}
+
+
+/* Run the selftests for digest algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_module_t module = NULL;
+ cipher_extra_spec_t *extraspec = NULL;
+ gcry_err_code_t ec = 0;
+
+ REGISTER_DEFAULT_DIGESTS;
+
+ ath_mutex_lock (&digests_registered_lock);
+ module = _gcry_module_lookup_id (digests_registered, algo);
+ if (module && !(module->flags & FLAG_MODULE_DISABLED))
+ extraspec = module->extraspec;
+ ath_mutex_unlock (&digests_registered_lock);
+ if (extraspec && extraspec->selftest)
+ ec = extraspec->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_DIGEST_ALGO;
+ if (report)
+ report ("digest", algo, "module",
+ module && !(module->flags & FLAG_MODULE_DISABLED)?
+ "no selftest available" :
+ module? "algorithm disabled" : "algorithm not found");
+ }
+
+ if (module)
+ {
+ ath_mutex_lock (&digests_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&digests_registered_lock);
+ }
+ return gpg_error (ec);
+}
--- /dev/null
+/* md4.c - MD4 Message-Digest Algorithm
+ * Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums
+ * using a public domain md4 implementation with the following comments:
+ *
+ * Modified by Wei Dai from Andrew M. Kuchling's md4.c
+ * The original code and all modifications are in the public domain.
+ *
+ * This is the original introductory comment:
+ *
+ * md4.c : MD4 hash algorithm.
+ *
+ * Part of the Python Cryptography Toolkit, version 1.1
+ *
+ * Distribute and use freely; there are no restrictions on further
+ * dissemination and usage except those imposed by the laws of your
+ * country of residence.
+ *
+ */
+
+/* MD4 test suite:
+ * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0
+ * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24
+ * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d
+ * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b
+ * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9
+ * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+ * 043f8582f241db351ce627e153e7f0e4
+ * MD4 ("123456789012345678901234567890123456789012345678901234567890123456
+ * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+
+typedef struct {
+ u32 A,B,C,D; /* chaining variables */
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} MD4_CONTEXT;
+
+
+static void
+md4_init( void *context )
+{
+ MD4_CONTEXT *ctx = context;
+
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+
+/****************
+ * transform 64 bytes
+ */
+static void
+transform ( MD4_CONTEXT *ctx, const unsigned char *data )
+{
+ u32 in[16];
+ register u32 A = ctx->A;
+ register u32 B = ctx->B;
+ register u32 C = ctx->C;
+ register u32 D = ctx->D;
+
+#ifdef WORDS_BIGENDIAN
+ {
+ int i;
+ byte *p2, *p1;
+ for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *p1++;
+ p2[2] = *p1++;
+ p2[1] = *p1++;
+ p2[0] = *p1++;
+ }
+ }
+#else
+ memcpy (in, data, 64);
+#endif
+
+ /* Round 1. */
+#define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 1, 7);
+ function(C,D,A,B, 2,11);
+ function(B,C,D,A, 3,19);
+ function(A,B,C,D, 4, 3);
+ function(D,A,B,C, 5, 7);
+ function(C,D,A,B, 6,11);
+ function(B,C,D,A, 7,19);
+ function(A,B,C,D, 8, 3);
+ function(D,A,B,C, 9, 7);
+ function(C,D,A,B,10,11);
+ function(B,C,D,A,11,19);
+ function(A,B,C,D,12, 3);
+ function(D,A,B,C,13, 7);
+ function(C,D,A,B,14,11);
+ function(B,C,D,A,15,19);
+
+#undef function
+
+ /* Round 2. */
+#define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s);
+
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 4, 5);
+ function(C,D,A,B, 8, 9);
+ function(B,C,D,A,12,13);
+ function(A,B,C,D, 1, 3);
+ function(D,A,B,C, 5, 5);
+ function(C,D,A,B, 9, 9);
+ function(B,C,D,A,13,13);
+ function(A,B,C,D, 2, 3);
+ function(D,A,B,C, 6, 5);
+ function(C,D,A,B,10, 9);
+ function(B,C,D,A,14,13);
+ function(A,B,C,D, 3, 3);
+ function(D,A,B,C, 7, 5);
+ function(C,D,A,B,11, 9);
+ function(B,C,D,A,15,13);
+
+#undef function
+
+ /* Round 3. */
+#define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s);
+
+ function(A,B,C,D, 0, 3);
+ function(D,A,B,C, 8, 9);
+ function(C,D,A,B, 4,11);
+ function(B,C,D,A,12,15);
+ function(A,B,C,D, 2, 3);
+ function(D,A,B,C,10, 9);
+ function(C,D,A,B, 6,11);
+ function(B,C,D,A,14,15);
+ function(A,B,C,D, 1, 3);
+ function(D,A,B,C, 9, 9);
+ function(C,D,A,B, 5,11);
+ function(B,C,D,A,13,15);
+ function(A,B,C,D, 3, 3);
+ function(D,A,B,C,11, 9);
+ function(C,D,A,B, 7,11);
+ function(B,C,D,A,15,15);
+
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+static void
+md4_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ MD4_CONTEXT *hd = context;
+
+ if( hd->count == 64 ) /* flush the buffer */
+ {
+ transform( hd, hd->buf );
+ _gcry_burn_stack (80+6*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+
+ if( hd->count )
+ {
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ md4_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+ _gcry_burn_stack (80+6*sizeof(void*));
+
+ while( inlen >= 64 )
+ {
+ transform( hd, inbuf );
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD4 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md4_final( void *context )
+{
+ MD4_CONTEXT *hd = context;
+ u32 t, msb, lsb;
+ byte *p;
+
+ md4_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) /* enough room */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else /* need one extra block */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ md4_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform( hd, hd->buf );
+ _gcry_burn_stack (80+6*sizeof(void*));
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
+#endif
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+
+}
+
+static byte *
+md4_read (void *context)
+{
+ MD4_CONTEXT *hd = context;
+ return hd->buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
+ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+ 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md4[] =
+ {
+ /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */
+ { "1.2.840.113549.2.4" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_md4 =
+ {
+ "MD4", asn, DIM (asn), oid_spec_md4,16,
+ md4_init, md4_write, md4_final, md4_read,
+ sizeof (MD4_CONTEXT)
+ };
--- /dev/null
+/* md5.c - MD5 Message-Digest Algorithm
+ * Copyright (C) 1995,1996,1998,1999,2001,2002,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * According to the definition of MD5 in RFC 1321 from April 1992.
+ * NOTE: This is *not* the same file as the one from glibc.
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
+ */
+
+/* Test values:
+ * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
+ * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
+ * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
+ * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+
+typedef struct {
+ u32 A,B,C,D; /* chaining variables */
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} MD5_CONTEXT;
+
+
+static void
+md5_init( void *context )
+{
+ MD5_CONTEXT *ctx = context;
+
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
+
+ ctx->nblocks = 0;
+ ctx->count = 0;
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+ and defined in the RFC 1321. The first function is a little bit optimized
+ (as found in Colin Plumbs public domain implementation). */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+
+/****************
+ * transform n*64 bytes
+ */
+static void
+transform ( MD5_CONTEXT *ctx, const unsigned char *data )
+{
+ u32 correct_words[16];
+ register u32 A = ctx->A;
+ register u32 B = ctx->B;
+ register u32 C = ctx->C;
+ register u32 D = ctx->D;
+ u32 *cwp = correct_words;
+
+#ifdef WORDS_BIGENDIAN
+ {
+ int i;
+ byte *p2, *p1;
+ for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *p1++;
+ p2[2] = *p1++;
+ p2[1] = *p1++;
+ p2[0] = *p1++;
+ }
+ }
+#else
+ memcpy( correct_words, data, 64 );
+#endif
+
+
+#define OP(a, b, c, d, s, T) \
+ do \
+ { \
+ a += FF (b, c, d) + (*cwp++) + T; \
+ a = rol(a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Before we start, one word about the strange constants.
+ They are defined in RFC 1321 as
+
+ T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+ */
+
+ /* Round 1. */
+ OP (A, B, C, D, 7, 0xd76aa478);
+ OP (D, A, B, C, 12, 0xe8c7b756);
+ OP (C, D, A, B, 17, 0x242070db);
+ OP (B, C, D, A, 22, 0xc1bdceee);
+ OP (A, B, C, D, 7, 0xf57c0faf);
+ OP (D, A, B, C, 12, 0x4787c62a);
+ OP (C, D, A, B, 17, 0xa8304613);
+ OP (B, C, D, A, 22, 0xfd469501);
+ OP (A, B, C, D, 7, 0x698098d8);
+ OP (D, A, B, C, 12, 0x8b44f7af);
+ OP (C, D, A, B, 17, 0xffff5bb1);
+ OP (B, C, D, A, 22, 0x895cd7be);
+ OP (A, B, C, D, 7, 0x6b901122);
+ OP (D, A, B, C, 12, 0xfd987193);
+ OP (C, D, A, B, 17, 0xa679438e);
+ OP (B, C, D, A, 22, 0x49b40821);
+
+#undef OP
+#define OP(f, a, b, c, d, k, s, T) \
+ do \
+ { \
+ a += f (b, c, d) + correct_words[k] + T; \
+ a = rol(a, s); \
+ a += b; \
+ } \
+ while (0)
+
+ /* Round 2. */
+ OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
+ OP (FG, D, A, B, C, 6, 9, 0xc040b340);
+ OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+ OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
+ OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
+ OP (FG, D, A, B, C, 10, 9, 0x02441453);
+ OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+ OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
+ OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
+ OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
+ OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
+ OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
+ OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
+ OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
+ OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
+ OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+ /* Round 3. */
+ OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
+ OP (FH, D, A, B, C, 8, 11, 0x8771f681);
+ OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+ OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+ OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
+ OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
+ OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
+ OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+ OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
+ OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
+ OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
+ OP (FH, B, C, D, A, 6, 23, 0x04881d05);
+ OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
+ OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+ OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+ OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
+
+ /* Round 4. */
+ OP (FI, A, B, C, D, 0, 6, 0xf4292244);
+ OP (FI, D, A, B, C, 7, 10, 0x432aff97);
+ OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+ OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
+ OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
+ OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
+ OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+ OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
+ OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
+ OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+ OP (FI, C, D, A, B, 6, 15, 0xa3014314);
+ OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+ OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
+ OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+ OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
+ OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
+
+ /* Put checksum in context given as argument. */
+ ctx->A += A;
+ ctx->B += B;
+ ctx->C += C;
+ ctx->D += D;
+}
+
+
+
+/* The routine updates the message-digest context to
+ * account for the presence of each of the characters inBuf[0..inLen-1]
+ * in the message whose digest is being computed.
+ */
+static void
+md5_write( void *context, const void *inbuf_arg , size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ MD5_CONTEXT *hd = context;
+
+ if( hd->count == 64 ) /* flush the buffer */
+ {
+ transform( hd, hd->buf );
+ _gcry_burn_stack (80+6*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+
+ if( hd->count )
+ {
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ md5_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+ _gcry_burn_stack (80+6*sizeof(void*));
+
+ while( inlen >= 64 )
+ {
+ transform( hd, inbuf );
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+
+}
+
+
+
+/* The routine final terminates the message-digest computation and
+ * ends with the desired message digest in mdContext->digest[0...15].
+ * The handle is prepared for a new MD5 cycle.
+ * Returns 16 bytes representing the digest.
+ */
+
+static void
+md5_final( void *context)
+{
+ MD5_CONTEXT *hd = context;
+ u32 t, msb, lsb;
+ byte *p;
+
+ md5_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) /* enough room */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else /* need one extra block */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ md5_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform( hd, hd->buf );
+ _gcry_burn_stack (80+6*sizeof(void*));
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
+#endif
+ X(A);
+ X(B);
+ X(C);
+ X(D);
+#undef X
+
+}
+
+static byte *
+md5_read( void *context )
+{
+ MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
+ return hd->buf;
+}
+
+static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
+ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+ 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+
+static gcry_md_oid_spec_t oid_spec_md5[] =
+ {
+ /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */
+ { "1.2.840.113549.1.1.4" },
+ /* RSADSI digestAlgorithm MD5 */
+ { "1.2.840.113549.2.5" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_md5 =
+ {
+ "MD5", asn, DIM (asn), oid_spec_md5, 16,
+ md5_init, md5_write, md5_final, md5_read,
+ sizeof (MD5_CONTEXT)
+ };
--- /dev/null
+/* primegen.c - prime number generator
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003
+ * 2004, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "ath.h"
+
+static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
+ int (*extra_check)(void *, gcry_mpi_t),
+ void *extra_check_arg);
+static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+ gcry_prime_check_func_t cb_func, void *cb_arg );
+static int is_prime (gcry_mpi_t n, int steps, unsigned int *count);
+static void m_out_of_n( char *array, int m, int n );
+
+static void (*progress_cb) (void *,const char*,int,int, int );
+static void *progress_cb_data;
+
+/* Note: 2 is not included because it can be tested more easily by
+ looking at bit 0. The last entry in this list is marked by a zero */
+static ushort small_prime_numbers[] = {
+ 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
+ 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
+ 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
+ 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
+ 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
+ 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
+ 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
+ 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
+ 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
+ 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
+ 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
+ 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
+ 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
+ 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
+ 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
+ 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
+ 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
+ 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
+ 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
+ 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
+ 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
+ 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
+ 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
+ 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
+ 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
+ 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
+ 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
+ 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
+ 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
+ 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
+ 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
+ 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
+ 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
+ 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
+ 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
+ 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
+ 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
+ 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
+ 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
+ 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
+ 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
+ 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
+ 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
+ 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
+ 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
+ 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
+ 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
+ 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
+ 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
+ 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
+ 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
+ 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
+ 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
+ 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
+ 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
+ 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
+ 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
+ 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
+ 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
+ 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
+ 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
+ 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
+ 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
+ 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
+ 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
+ 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
+ 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
+ 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
+ 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
+ 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
+ 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
+ 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
+ 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
+ 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
+ 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
+ 4957, 4967, 4969, 4973, 4987, 4993, 4999,
+ 0
+};
+static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
+
+
+\f
+/* An object and a list to build up a global pool of primes. See
+ save_pool_prime and get_pool_prime. */
+struct primepool_s
+{
+ struct primepool_s *next;
+ gcry_mpi_t prime; /* If this is NULL the entry is not used. */
+ unsigned int nbits;
+ gcry_random_level_t randomlevel;
+};
+struct primepool_s *primepool;
+/* Mutex used to protect access to the primepool. */
+static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+
+
+
+/* Save PRIME which has been generated at RANDOMLEVEL for later
+ use. Needs to be called while primepool_lock is being hold. Note
+ that PRIME should be considered released after calling this
+ function. */
+static void
+save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
+{
+ struct primepool_s *item, *item2;
+ size_t n;
+
+ for (n=0, item = primepool; item; item = item->next, n++)
+ if (!item->prime)
+ break;
+ if (!item && n > 100)
+ {
+ /* Remove some of the entries. Our strategy is removing
+ the last third from the list. */
+ int i;
+
+ for (i=0, item2 = primepool; item2; item2 = item2->next)
+ {
+ if (i >= n/3*2)
+ {
+ gcry_mpi_release (item2->prime);
+ item2->prime = NULL;
+ if (!item)
+ item = item2;
+ }
+ }
+ }
+ if (!item)
+ {
+ item = gcry_calloc (1, sizeof *item);
+ if (!item)
+ {
+ /* Out of memory. Silently giving up. */
+ gcry_mpi_release (prime);
+ return;
+ }
+ item->next = primepool;
+ primepool = item;
+ }
+ item->prime = prime;
+ item->nbits = mpi_get_nbits (prime);
+ item->randomlevel = randomlevel;
+}
+
+
+/* Return a prime for the prime pool or NULL if none has been found.
+ The prime needs to match NBITS and randomlevel. This function needs
+ to be called why the primepool_look is being hold. */
+static gcry_mpi_t
+get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
+{
+ struct primepool_s *item;
+
+ for (item = primepool; item; item = item->next)
+ if (item->prime
+ && item->nbits == nbits && item->randomlevel == randomlevel)
+ {
+ gcry_mpi_t prime = item->prime;
+ item->prime = NULL;
+ gcry_assert (nbits == mpi_get_nbits (prime));
+ return prime;
+ }
+ return NULL;
+}
+
+
+
+
+
+\f
+void
+_gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
+ void *cb_data )
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+static void
+progress( int c )
+{
+ if ( progress_cb )
+ progress_cb ( progress_cb_data, "primegen", c, 0, 0 );
+}
+
+
+/****************
+ * Generate a prime number (stored in secure memory)
+ */
+gcry_mpi_t
+_gcry_generate_secret_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg)
+{
+ gcry_mpi_t prime;
+
+ prime = gen_prime (nbits, 1, random_level, extra_check, extra_check_arg);
+ progress('\n');
+ return prime;
+}
+
+
+/* Generate a prime number which may be public, i.e. not allocated in
+ secure memory. */
+gcry_mpi_t
+_gcry_generate_public_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg)
+{
+ gcry_mpi_t prime;
+
+ prime = gen_prime (nbits, 0, random_level, extra_check, extra_check_arg);
+ progress('\n');
+ return prime;
+}
+
+
+/* Core prime generation function. The algorithm used to generate
+ practically save primes is due to Lim and Lee as described in the
+ CRYPTO '97 proceedings (ISBN3540633847) page 260.
+
+ NEED_Q_FACTOR: If true make sure that at least one factor is of
+ size qbits. This is for example required for DSA.
+ PRIME_GENERATED: Adresss of a variable where the resulting prime
+ number will be stored.
+ PBITS: Requested size of the prime number. At least 48.
+ QBITS: One factor of the prime needs to be of this size. Maybe 0
+ if this is not required. See also MODE.
+ G: If not NULL an MPI which will receive a generator for the prime
+ for use with Elgamal.
+ RET_FACTORS: if not NULL, an array with all factors are stored at
+ that address.
+ ALL_FACTORS: If set to true all factors of prime-1 are returned.
+ RANDOMLEVEL: How strong should the random numers be.
+ FLAGS: Prime generation bit flags. Currently supported:
+ GCRY_PRIME_FLAG_SECRET - The prime needs to be kept secret.
+ CB_FUNC, CB_ARG: Callback to be used for extra checks.
+
+ */
+static gcry_err_code_t
+prime_generate_internal (int need_q_factor,
+ gcry_mpi_t *prime_generated, unsigned int pbits,
+ unsigned int qbits, gcry_mpi_t g,
+ gcry_mpi_t **ret_factors,
+ gcry_random_level_t randomlevel, unsigned int flags,
+ int all_factors,
+ gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+ gcry_err_code_t err = 0;
+ gcry_mpi_t *factors_new = NULL; /* Factors to return to the
+ caller. */
+ gcry_mpi_t *factors = NULL; /* Current factors. */
+ gcry_random_level_t poolrandomlevel; /* Random level used for pool primes. */
+ gcry_mpi_t *pool = NULL; /* Pool of primes. */
+ int *pool_in_use = NULL; /* Array with currently used POOL elements. */
+ unsigned char *perms = NULL; /* Permutations of POOL. */
+ gcry_mpi_t q_factor = NULL; /* Used if QBITS is non-zero. */
+ unsigned int fbits = 0; /* Length of prime factors. */
+ unsigned int n = 0; /* Number of factors. */
+ unsigned int m = 0; /* Number of primes in pool. */
+ gcry_mpi_t q = NULL; /* First prime factor. */
+ gcry_mpi_t prime = NULL; /* Prime candidate. */
+ unsigned int nprime = 0; /* Bits of PRIME. */
+ unsigned int req_qbits; /* The original QBITS value. */
+ gcry_mpi_t val_2; /* For check_prime(). */
+ int is_locked = 0; /* Flag to help unlocking the primepool. */
+ unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
+ unsigned int count1 = 0, count2 = 0;
+ unsigned int i = 0, j = 0;
+
+ if (pbits < 48)
+ return GPG_ERR_INV_ARG;
+
+ /* We won't use a too strong random elvel for the pooled subprimes. */
+ poolrandomlevel = (randomlevel > GCRY_STRONG_RANDOM?
+ GCRY_STRONG_RANDOM : randomlevel);
+
+
+ /* If QBITS is not given, assume a reasonable value. */
+ if (!qbits)
+ qbits = pbits / 3;
+
+ req_qbits = qbits;
+
+ /* Find number of needed prime factors N. */
+ for (n = 1; (pbits - qbits - 1) / n >= qbits; n++)
+ ;
+ n--;
+
+ val_2 = mpi_alloc_set_ui (2);
+
+ if ((! n) || ((need_q_factor) && (n < 2)))
+ {
+ err = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+
+ if (need_q_factor)
+ {
+ n--; /* Need one factor less because we want a specific Q-FACTOR. */
+ fbits = (pbits - 2 * req_qbits -1) / n;
+ qbits = pbits - req_qbits - n * fbits;
+ }
+ else
+ {
+ fbits = (pbits - req_qbits -1) / n;
+ qbits = pbits - n * fbits;
+ }
+
+ if (DBG_CIPHER)
+ log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
+ pbits, req_qbits, qbits, fbits, n);
+
+ /* Allocate an integer to old the new prime. */
+ prime = gcry_mpi_new (pbits);
+
+ /* Generate first prime factor. */
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+
+ /* Generate a specific Q-Factor if requested. */
+ if (need_q_factor)
+ q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
+
+ /* Allocate an array to hold all factors + 2 for later usage. */
+ factors = gcry_calloc (n + 2, sizeof (*factors));
+ if (!factors)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ /* Allocate an array to track pool usage. */
+ pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
+ if (!pool_in_use)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ for (i=0; i < n; i++)
+ pool_in_use[i] = -1;
+
+ /* Make a pool of 3n+5 primes (this is an arbitrary value). We
+ require at least 30 primes for are useful selection process.
+
+ Fixme: We need to research the best formula for sizing the pool.
+ */
+ m = n * 3 + 5;
+ if (need_q_factor) /* Need some more in this case. */
+ m += 5;
+ if (m < 30)
+ m = 30;
+ pool = gcry_calloc (m , sizeof (*pool));
+ if (! pool)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ /* Permutate over the pool of primes until we find a prime of the
+ requested length. */
+ do
+ {
+ next_try:
+ for (i=0; i < n; i++)
+ pool_in_use[i] = -1;
+
+ if (!perms)
+ {
+ /* Allocate new primes. This is done right at the beginning
+ of the loop and if we have later run out of primes. */
+ for (i = 0; i < m; i++)
+ {
+ mpi_free (pool[i]);
+ pool[i] = NULL;
+ }
+
+ /* Init m_out_of_n(). */
+ perms = gcry_calloc (1, m);
+ if (!perms)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ if (ath_mutex_lock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 1;
+ for (i = 0; i < n; i++)
+ {
+ perms[i] = 1;
+ /* At a maximum we use strong random for the factors.
+ This saves us a lot of entropy. Given that Q and
+ possible Q-factor are also used in the final prime
+ this should be acceptable. We also don't allocate in
+ secure memory to save on that scare resource too. If
+ Q has been allocated in secure memory, the final
+ prime will be saved there anyway. This is because
+ our MPI routines take care of that. GnuPG has worked
+ this way ever since. */
+ pool[i] = NULL;
+ if (is_locked)
+ {
+ pool[i] = get_pool_prime (fbits, poolrandomlevel);
+ if (!pool[i])
+ {
+ if (ath_mutex_unlock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 0;
+ }
+ }
+ if (!pool[i])
+ pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+ pool_in_use[i] = i;
+ factors[i] = pool[i];
+ }
+ if (is_locked && ath_mutex_unlock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 0;
+ }
+ else
+ {
+ /* Get next permutation. */
+ m_out_of_n ( (char*)perms, n, m);
+ if (ath_mutex_lock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 1;
+ for (i = j = 0; (i < m) && (j < n); i++)
+ if (perms[i])
+ {
+ /* If the subprime has not yet beed generated do it now. */
+ if (!pool[i] && is_locked)
+ {
+ pool[i] = get_pool_prime (fbits, poolrandomlevel);
+ if (!pool[i])
+ {
+ if (ath_mutex_unlock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 0;
+ }
+ }
+ if (!pool[i])
+ pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+ pool_in_use[j] = i;
+ factors[j++] = pool[i];
+ }
+ if (is_locked && ath_mutex_unlock (&primepool_lock))
+ {
+ err = GPG_ERR_INTERNAL;
+ goto leave;
+ }
+ is_locked = 0;
+ if (i == n)
+ {
+ /* Ran out of permutations: Allocate new primes. */
+ gcry_free (perms);
+ perms = NULL;
+ progress ('!');
+ goto next_try;
+ }
+ }
+
+ /* Generate next prime candidate:
+ p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1.
+ */
+ mpi_set (prime, q);
+ mpi_mul_ui (prime, prime, 2);
+ if (need_q_factor)
+ mpi_mul (prime, prime, q_factor);
+ for(i = 0; i < n; i++)
+ mpi_mul (prime, prime, factors[i]);
+ mpi_add_ui (prime, prime, 1);
+ nprime = mpi_get_nbits (prime);
+
+ if (nprime < pbits)
+ {
+ if (++count1 > 20)
+ {
+ count1 = 0;
+ qbits++;
+ progress('>');
+ mpi_free (q);
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+ goto next_try;
+ }
+ }
+ else
+ count1 = 0;
+
+ if (nprime > pbits)
+ {
+ if (++count2 > 20)
+ {
+ count2 = 0;
+ qbits--;
+ progress('<');
+ mpi_free (q);
+ q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
+ goto next_try;
+ }
+ }
+ else
+ count2 = 0;
+ }
+ while (! ((nprime == pbits) && check_prime (prime, val_2, 5,
+ cb_func, cb_arg)));
+
+ if (DBG_CIPHER)
+ {
+ progress ('\n');
+ log_mpidump ("prime : ", prime);
+ log_mpidump ("factor q: ", q);
+ if (need_q_factor)
+ log_mpidump ("factor q0: ", q_factor);
+ for (i = 0; i < n; i++)
+ log_mpidump ("factor pi: ", factors[i]);
+ log_debug ("bit sizes: prime=%u, q=%u",
+ mpi_get_nbits (prime), mpi_get_nbits (q));
+ if (need_q_factor)
+ log_debug (", q0=%u", mpi_get_nbits (q_factor));
+ for (i = 0; i < n; i++)
+ log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
+ progress('\n');
+ }
+
+ if (ret_factors)
+ {
+ /* Caller wants the factors. */
+ factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
+ if (! factors_new)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+
+ if (all_factors)
+ {
+ i = 0;
+ factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
+ factors_new[i++] = mpi_copy (q);
+ if (need_q_factor)
+ factors_new[i++] = mpi_copy (q_factor);
+ for(j=0; j < n; j++)
+ factors_new[i++] = mpi_copy (factors[j]);
+ }
+ else
+ {
+ i = 0;
+ if (need_q_factor)
+ {
+ factors_new[i++] = mpi_copy (q_factor);
+ for (; i <= n; i++)
+ factors_new[i] = mpi_copy (factors[i]);
+ }
+ else
+ for (; i < n; i++ )
+ factors_new[i] = mpi_copy (factors[i]);
+ }
+ }
+
+ if (g)
+ {
+ /* Create a generator (start with 3). */
+ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
+ gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
+ gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
+
+ if (need_q_factor)
+ err = GPG_ERR_NOT_IMPLEMENTED;
+ else
+ {
+ factors[n] = q;
+ factors[n + 1] = mpi_alloc_set_ui (2);
+ mpi_sub_ui (pmin1, prime, 1);
+ mpi_set_ui (g, 2);
+ do
+ {
+ mpi_add_ui (g, g, 1);
+ if (DBG_CIPHER)
+ {
+ log_debug ("checking g:");
+ gcry_mpi_dump (g);
+ log_printf ("\n");
+ }
+ else
+ progress('^');
+ for (i = 0; i < n + 2; i++)
+ {
+ mpi_fdiv_q (tmp, pmin1, factors[i]);
+ /* No mpi_pow(), but it is okay to use this with mod
+ prime. */
+ gcry_mpi_powm (b, g, tmp, prime);
+ if (! mpi_cmp_ui (b, 1))
+ break;
+ }
+ if (DBG_CIPHER)
+ progress('\n');
+ }
+ while (i < n + 2);
+
+ mpi_free (factors[n+1]);
+ mpi_free (tmp);
+ mpi_free (b);
+ mpi_free (pmin1);
+ }
+ }
+
+ if (! DBG_CIPHER)
+ progress ('\n');
+
+
+ leave:
+ if (pool)
+ {
+ is_locked = !ath_mutex_lock (&primepool_lock);
+ for(i = 0; i < m; i++)
+ {
+ if (pool[i])
+ {
+ for (j=0; j < n; j++)
+ if (pool_in_use[j] == i)
+ break;
+ if (j == n && is_locked)
+ {
+ /* This pooled subprime has not been used. */
+ save_pool_prime (pool[i], poolrandomlevel);
+ }
+ else
+ mpi_free (pool[i]);
+ }
+ }
+ if (is_locked && ath_mutex_unlock (&primepool_lock))
+ err = GPG_ERR_INTERNAL;
+ is_locked = 0;
+ gcry_free (pool);
+ }
+ gcry_free (pool_in_use);
+ if (factors)
+ gcry_free (factors); /* Factors are shallow copies. */
+ if (perms)
+ gcry_free (perms);
+
+ mpi_free (val_2);
+ mpi_free (q);
+ mpi_free (q_factor);
+
+ if (! err)
+ {
+ *prime_generated = prime;
+ if (ret_factors)
+ *ret_factors = factors_new;
+ }
+ else
+ {
+ if (factors_new)
+ {
+ for (i = 0; factors_new[i]; i++)
+ mpi_free (factors_new[i]);
+ gcry_free (factors_new);
+ }
+ mpi_free (prime);
+ }
+
+ return err;
+}
+
+
+/* Generate a prime used for discrete logarithm algorithms; i.e. this
+ prime will be public and no strong random is required. */
+gcry_mpi_t
+_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
+ gcry_mpi_t g, gcry_mpi_t **ret_factors)
+{
+ gcry_mpi_t prime = NULL;
+
+ if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
+ ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+ NULL, NULL))
+ prime = NULL; /* (Should be NULL in the error case anyway.) */
+
+ return prime;
+}
+
+
+static gcry_mpi_t
+gen_prime (unsigned int nbits, int secret, int randomlevel,
+ int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
+{
+ gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
+ int i;
+ unsigned int x, step;
+ unsigned int count1, count2;
+ int *mods;
+
+/* if ( DBG_CIPHER ) */
+/* log_debug ("generate a prime of %u bits ", nbits ); */
+
+ if (nbits < 16)
+ log_fatal ("can't generate a prime with less than %d bits\n", 16);
+
+ mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
+ /* Make nbits fit into gcry_mpi_t implementation. */
+ val_2 = mpi_alloc_set_ui( 2 );
+ val_3 = mpi_alloc_set_ui( 3);
+ prime = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
+ result = mpi_alloc_like( prime );
+ pminus1= mpi_alloc_like( prime );
+ ptest = mpi_alloc_like( prime );
+ count1 = count2 = 0;
+ for (;;)
+ { /* try forvever */
+ int dotcount=0;
+
+ /* generate a random number */
+ gcry_mpi_randomize( prime, nbits, randomlevel );
+
+ /* Set high order bit to 1, set low order bit to 1. If we are
+ generating a secret prime we are most probably doing that
+ for RSA, to make sure that the modulus does have the
+ requested key size we set the 2 high order bits. */
+ mpi_set_highbit (prime, nbits-1);
+ if (secret)
+ mpi_set_bit (prime, nbits-2);
+ mpi_set_bit(prime, 0);
+
+ /* Calculate all remainders. */
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
+
+ /* Now try some primes starting with prime. */
+ for(step=0; step < 20000; step += 2 )
+ {
+ /* Check against all the small primes we have in mods. */
+ count1++;
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ {
+ while ( mods[i] + step >= x )
+ mods[i] -= x;
+ if ( !(mods[i] + step) )
+ break;
+ }
+ if ( x )
+ continue; /* Found a multiple of an already known prime. */
+
+ mpi_add_ui( ptest, prime, step );
+
+ /* Do a fast Fermat test now. */
+ count2++;
+ mpi_sub_ui( pminus1, ptest, 1);
+ gcry_mpi_powm( result, val_2, pminus1, ptest );
+ if ( !mpi_cmp_ui( result, 1 ) )
+ {
+ /* Not composite, perform stronger tests */
+ if (is_prime(ptest, 5, &count2 ))
+ {
+ if (!mpi_test_bit( ptest, nbits-1-secret ))
+ {
+ progress('\n');
+ log_debug ("overflow in prime generation\n");
+ break; /* Stop loop, continue with a new prime. */
+ }
+
+ if (extra_check && extra_check (extra_check_arg, ptest))
+ {
+ /* The extra check told us that this prime is
+ not of the caller's taste. */
+ progress ('/');
+ }
+ else
+ {
+ /* Got it. */
+ mpi_free(val_2);
+ mpi_free(val_3);
+ mpi_free(result);
+ mpi_free(pminus1);
+ mpi_free(prime);
+ gcry_free(mods);
+ return ptest;
+ }
+ }
+ }
+ if (++dotcount == 10 )
+ {
+ progress('.');
+ dotcount = 0;
+ }
+ }
+ progress(':'); /* restart with a new random value */
+ }
+}
+
+/****************
+ * Returns: true if this may be a prime
+ * RM_ROUNDS gives the number of Rabin-Miller tests to run.
+ */
+static int
+check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
+ gcry_prime_check_func_t cb_func, void *cb_arg)
+{
+ int i;
+ unsigned int x;
+ unsigned int count=0;
+
+ /* Check against small primes. */
+ for (i=0; (x = small_prime_numbers[i]); i++ )
+ {
+ if ( mpi_divisible_ui( prime, x ) )
+ return 0;
+ }
+
+ /* A quick Fermat test. */
+ {
+ gcry_mpi_t result = mpi_alloc_like( prime );
+ gcry_mpi_t pminus1 = mpi_alloc_like( prime );
+ mpi_sub_ui( pminus1, prime, 1);
+ gcry_mpi_powm( result, val_2, pminus1, prime );
+ mpi_free( pminus1 );
+ if ( mpi_cmp_ui( result, 1 ) )
+ {
+ /* Is composite. */
+ mpi_free( result );
+ progress('.');
+ return 0;
+ }
+ mpi_free( result );
+ }
+
+ if (!cb_func || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_MAYBE_PRIME, prime))
+ {
+ /* Perform stronger tests. */
+ if ( is_prime( prime, rm_rounds, &count ) )
+ {
+ if (!cb_func
+ || cb_func (cb_arg, GCRY_PRIME_CHECK_AT_GOT_PRIME, prime))
+ return 1; /* Probably a prime. */
+ }
+ }
+ progress('.');
+ return 0;
+}
+
+
+/*
+ * Return true if n is probably a prime
+ */
+static int
+is_prime (gcry_mpi_t n, int steps, unsigned int *count)
+{
+ gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t z = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t nminus1 = mpi_alloc( mpi_get_nlimbs( n ) );
+ gcry_mpi_t a2 = mpi_alloc_set_ui( 2 );
+ gcry_mpi_t q;
+ unsigned i, j, k;
+ int rc = 0;
+ unsigned nbits = mpi_get_nbits( n );
+
+ if (steps < 5) /* Make sure that we do at least 5 rounds. */
+ steps = 5;
+
+ mpi_sub_ui( nminus1, n, 1 );
+
+ /* Find q and k, so that n = 1 + 2^k * q . */
+ q = mpi_copy ( nminus1 );
+ k = mpi_trailing_zeros ( q );
+ mpi_tdiv_q_2exp (q, q, k);
+
+ for (i=0 ; i < steps; i++ )
+ {
+ ++*count;
+ if( !i )
+ {
+ mpi_set_ui( x, 2 );
+ }
+ else
+ {
+ gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
+
+ /* Make sure that the number is smaller than the prime and
+ keep the randomness of the high bit. */
+ if ( mpi_test_bit ( x, nbits-2) )
+ {
+ mpi_set_highbit ( x, nbits-2); /* Clear all higher bits. */
+ }
+ else
+ {
+ mpi_set_highbit( x, nbits-2 );
+ mpi_clear_bit( x, nbits-2 );
+ }
+ gcry_assert (mpi_cmp (x, nminus1) < 0 && mpi_cmp_ui (x, 1) > 0);
+ }
+ gcry_mpi_powm ( y, x, q, n);
+ if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
+ {
+ for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
+ {
+ gcry_mpi_powm(y, y, a2, n);
+ if( !mpi_cmp_ui( y, 1 ) )
+ goto leave; /* Not a prime. */
+ }
+ if (mpi_cmp( y, nminus1 ) )
+ goto leave; /* Not a prime. */
+ }
+ progress('+');
+ }
+ rc = 1; /* May be a prime. */
+
+ leave:
+ mpi_free( x );
+ mpi_free( y );
+ mpi_free( z );
+ mpi_free( nminus1 );
+ mpi_free( q );
+ mpi_free( a2 );
+
+ return rc;
+}
+
+
+/* Given ARRAY of size N with M elements set to true produce a
+ modified array with the next permutation of M elements. Note, that
+ ARRAY is used in a one-bit-per-byte approach. To detected the last
+ permutation it is useful to initialize the array with the first M
+ element set to true and use this test:
+ m_out_of_n (array, m, n);
+ for (i = j = 0; i < n && j < m; i++)
+ if (array[i])
+ j++;
+ if (j == m)
+ goto ready;
+
+ This code is based on the algorithm 452 from the "Collected
+ Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
+*/
+static void
+m_out_of_n ( char *array, int m, int n )
+{
+ int i=0, i1=0, j=0, jp=0, j1=0, k1=0, k2=0;
+
+ if( !m || m >= n )
+ return;
+
+ /* Need to handle this simple case separately. */
+ if( m == 1 )
+ {
+ for (i=0; i < n; i++ )
+ {
+ if ( array[i] )
+ {
+ array[i++] = 0;
+ if( i >= n )
+ i = 0;
+ array[i] = 1;
+ return;
+ }
+ }
+ BUG();
+ }
+
+
+ for (j=1; j < n; j++ )
+ {
+ if ( array[n-1] == array[n-j-1])
+ continue;
+ j1 = j;
+ break;
+ }
+
+ if ( (m & 1) )
+ {
+ /* M is odd. */
+ if( array[n-1] )
+ {
+ if( j1 & 1 )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ goto scan;
+ }
+ k2 = n - j1 - 1;
+ if( k2 == 0 )
+ {
+ k1 = i;
+ k2 = n - j1;
+ }
+ else if( array[k2] && array[k2-1] )
+ k1 = n;
+ else
+ k1 = k2 + 1;
+ }
+ else
+ {
+ /* M is even. */
+ if( !array[n-1] )
+ {
+ k1 = n - j1;
+ k2 = k1 + 1;
+ goto leave;
+ }
+
+ if( !(j1 & 1) )
+ {
+ k1 = n - j1;
+ k2 = k1+2;
+ if( k2 > n )
+ k2 = n;
+ goto leave;
+ }
+ scan:
+ jp = n - j1 - 1;
+ for (i=1; i <= jp; i++ )
+ {
+ i1 = jp + 2 - i;
+ if( array[i1-1] )
+ {
+ if( array[i1-2] )
+ {
+ k1 = i1 - 1;
+ k2 = n - j1;
+ }
+ else
+ {
+ k1 = i1 - 1;
+ k2 = n + 1 - j1;
+ }
+ goto leave;
+ }
+ }
+ k1 = 1;
+ k2 = n + 1 - m;
+ }
+ leave:
+ /* Now complement the two selected bits. */
+ array[k1-1] = !array[k1-1];
+ array[k2-1] = !array[k2-1];
+}
+
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_error_t
+gcry_prime_generate (gcry_mpi_t *prime, unsigned int prime_bits,
+ unsigned int factor_bits, gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func, void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_mpi_t *factors_generated = NULL;
+ gcry_mpi_t prime_generated = NULL;
+ unsigned int mode = 0;
+
+ if (!prime)
+ return gpg_error (GPG_ERR_INV_ARG);
+ *prime = NULL;
+
+ if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
+ mode = 1;
+
+ /* Generate. */
+ err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
+ factor_bits, NULL,
+ factors? &factors_generated : NULL,
+ random_level, flags, 1,
+ cb_func, cb_arg);
+
+ if (! err)
+ if (cb_func)
+ {
+ /* Additional check. */
+ if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
+ {
+ /* Failed, deallocate resources. */
+ unsigned int i;
+
+ mpi_free (prime_generated);
+ if (factors)
+ {
+ for (i = 0; factors_generated[i]; i++)
+ mpi_free (factors_generated[i]);
+ gcry_free (factors_generated);
+ }
+ err = GPG_ERR_GENERAL;
+ }
+ }
+
+ if (! err)
+ {
+ if (factors)
+ *factors = factors_generated;
+ *prime = prime_generated;
+ }
+
+ return gcry_error (err);
+}
+
+/* Check whether the number X is prime. */
+gcry_error_t
+gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
+
+ (void)flags;
+
+ /* We use 64 rounds because the prime we are going to test is not
+ guaranteed to be a random one. */
+ if (! check_prime (x, val_2, 64, NULL, NULL))
+ err = GPG_ERR_NO_PRIME;
+
+ mpi_free (val_2);
+
+ return gcry_error (err);
+}
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as s
+ atart for the search. Returns 0 on success.*/
+gcry_error_t
+gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime, gcry_mpi_t *factors,
+ gcry_mpi_t start_g)
+{
+ gcry_mpi_t tmp = gcry_mpi_new (0);
+ gcry_mpi_t b = gcry_mpi_new (0);
+ gcry_mpi_t pmin1 = gcry_mpi_new (0);
+ gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3);
+ int first = 1;
+ int i, n;
+
+ if (!factors || !r_g || !prime)
+ return gpg_error (GPG_ERR_INV_ARG);
+ *r_g = NULL;
+
+ for (n=0; factors[n]; n++)
+ ;
+ if (n < 2)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ /* Extra sanity check - usually disabled. */
+/* mpi_set (tmp, factors[0]); */
+/* for(i = 1; i < n; i++) */
+/* mpi_mul (tmp, tmp, factors[i]); */
+/* mpi_add_ui (tmp, tmp, 1); */
+/* if (mpi_cmp (prime, tmp)) */
+/* return gpg_error (GPG_ERR_INV_ARG); */
+
+ gcry_mpi_sub_ui (pmin1, prime, 1);
+ do
+ {
+ if (first)
+ first = 0;
+ else
+ gcry_mpi_add_ui (g, g, 1);
+
+ if (DBG_CIPHER)
+ {
+ log_debug ("checking g:");
+ gcry_mpi_dump (g);
+ log_debug ("\n");
+ }
+ else
+ progress('^');
+
+ for (i = 0; i < n; i++)
+ {
+ mpi_fdiv_q (tmp, pmin1, factors[i]);
+ gcry_mpi_powm (b, g, tmp, prime);
+ if (! mpi_cmp_ui (b, 1))
+ break;
+ }
+ if (DBG_CIPHER)
+ progress('\n');
+ }
+ while (i < n);
+
+ gcry_mpi_release (tmp);
+ gcry_mpi_release (b);
+ gcry_mpi_release (pmin1);
+ *r_g = g;
+
+ return 0;
+}
+
+/* Convenience function to release the factors array. */
+void
+gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+ if (factors)
+ {
+ int i;
+
+ for (i=0; factors[i]; i++)
+ mpi_free (factors[i]);
+ gcry_free (factors);
+ }
+}
+
+
+\f
+/* Helper for _gcry_derive_x931_prime. */
+static gcry_mpi_t
+find_x931_prime (const gcry_mpi_t pfirst)
+{
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t prime;
+
+ prime = gcry_mpi_copy (pfirst);
+ /* If P is even add 1. */
+ mpi_set_bit (prime, 0);
+
+ /* We use 64 Rabin-Miller rounds which is better and thus
+ sufficient. We do not have a Lucas test implementaion thus we
+ can't do it in the X9.31 preferred way of running a few
+ Rabin-Miller followed by one Lucas test. */
+ while ( !check_prime (prime, val_2, 64, NULL, NULL) )
+ mpi_add_ui (prime, prime, 2);
+
+ mpi_free (val_2);
+
+ return prime;
+}
+
+
+/* Generate a prime using the algorithm from X9.31 appendix B.4.
+
+ This function requires that the provided public exponent E is odd.
+ XP, XP1 and XP2 are the seed values. All values are mandatory.
+
+ On success the prime is returned. If R_P1 or R_P2 are given the
+ internal values P1 and P2 are saved at these addresses. On error
+ NULL is returned. */
+gcry_mpi_t
+_gcry_derive_x931_prime (const gcry_mpi_t xp,
+ const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+ const gcry_mpi_t e,
+ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
+{
+ gcry_mpi_t p1, p2, p1p2, yp0;
+
+ if (!xp || !xp1 || !xp2)
+ return NULL;
+ if (!e || !mpi_test_bit (e, 0))
+ return NULL; /* We support only odd values for E. */
+
+ p1 = find_x931_prime (xp1);
+ p2 = find_x931_prime (xp2);
+ p1p2 = mpi_alloc_like (xp);
+ mpi_mul (p1p2, p1, p2);
+
+ {
+ gcry_mpi_t r1, tmp;
+
+ /* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
+ tmp = mpi_alloc_like (p1);
+ mpi_invm (tmp, p2, p1);
+ mpi_mul (tmp, tmp, p2);
+ r1 = tmp;
+
+ tmp = mpi_alloc_like (p2);
+ mpi_invm (tmp, p1, p2);
+ mpi_mul (tmp, tmp, p1);
+ mpi_sub (r1, r1, tmp);
+
+ /* Fixup a negative value. */
+ if (mpi_is_neg (r1))
+ mpi_add (r1, r1, p1p2);
+
+ /* yp0 = xp + (r1 - xp mod p1*p2) */
+ yp0 = tmp; tmp = NULL;
+ mpi_subm (yp0, r1, xp, p1p2);
+ mpi_add (yp0, yp0, xp);
+ mpi_free (r1);
+
+ /* Fixup a negative value. */
+ if (mpi_cmp (yp0, xp) < 0 )
+ mpi_add (yp0, yp0, p1p2);
+ }
+
+ /* yp0 is now the first integer greater than xp with p1 being a
+ large prime factor of yp0-1 and p2 a large prime factor of yp0+1. */
+
+ /* Note that the first example from X9.31 (D.1.1) which uses
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+ returns an yp0 of
+ #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC4E3
+ BF20CB896EE37E098A906313271422162CB6C642
+ 75C1201F#
+ and not
+ #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC2E6
+ C88FE299D52D78BE405A97E01FD71DD7819ECB91
+ FA85A076#
+ as stated in the standard. This seems to be a bug in X9.31.
+ */
+
+ {
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
+ int gcdres;
+
+ mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body. */
+ mpi_sub_ui (yp0, yp0, 1); /* Ditto. */
+ for (;;)
+ {
+ gcdres = gcry_mpi_gcd (gcdtmp, e, yp0);
+ mpi_add_ui (yp0, yp0, 1);
+ if (!gcdres)
+ progress ('/'); /* gcd (e, yp0-1) != 1 */
+ else if (check_prime (yp0, val_2, 64, NULL, NULL))
+ break; /* Found. */
+ /* We add p1p2-1 because yp0 is incremented after the gcd test. */
+ mpi_add (yp0, yp0, p1p2);
+ }
+ mpi_free (gcdtmp);
+ mpi_free (val_2);
+ }
+
+ mpi_free (p1p2);
+
+ progress('\n');
+ if (r_p1)
+ *r_p1 = p1;
+ else
+ mpi_free (p1);
+ if (r_p2)
+ *r_p2 = p2;
+ else
+ mpi_free (p2);
+ return yp0;
+}
+
+
+\f
+/* Generate the two prime used for DSA using the algorithm specified
+ in FIPS 186-2. PBITS is the desired length of the prime P and a
+ QBITS the length of the prime Q. If SEED is not supplied and
+ SEEDLEN is 0 the function generates an appropriate SEED. On
+ success the generated primes are stored at R_Q and R_P, the counter
+ value is stored at R_COUNTER and the seed actually used for
+ generation is stored at R_SEED and R_SEEDVALUE. */
+gpg_err_code_t
+_gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen)
+{
+ gpg_err_code_t ec;
+ unsigned char seed_help_buffer[160/8]; /* Used to hold a generated SEED. */
+ unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */
+ unsigned char digest[160/8]; /* Helper buffer for SHA-1 digest. */
+ gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */
+ gcry_mpi_t tmpval = NULL; /* Helper variable. */
+ int i;
+
+ unsigned char value_u[160/8];
+ int value_n, value_b, value_k;
+ int counter;
+ gcry_mpi_t value_w = NULL;
+ gcry_mpi_t value_x = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+
+ /* FIPS 186-2 allows only for 1024/160 bit. */
+ if (pbits != 1024 || qbits != 160)
+ return GPG_ERR_INV_KEYLEN;
+
+ if (!seed && !seedlen)
+ ; /* No seed value given: We are asked to generate it. */
+ else if (!seed || seedlen < qbits/8)
+ return GPG_ERR_INV_ARG;
+
+ /* Allocate a buffer to later compute SEED+some_increment. */
+ seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
+ if (!seed_plus)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ val_2 = mpi_alloc_set_ui (2);
+ value_n = (pbits - 1) / qbits;
+ value_b = (pbits - 1) - value_n * qbits;
+ value_w = gcry_mpi_new (pbits);
+ value_x = gcry_mpi_new (pbits);
+
+ restart:
+ /* Generate Q. */
+ for (;;)
+ {
+ /* Step 1: Generate a (new) seed unless one has been supplied. */
+ if (!seed)
+ {
+ seedlen = sizeof seed_help_buffer;
+ gcry_create_nonce (seed_help_buffer, seedlen);
+ seed = seed_help_buffer;
+ }
+
+ /* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits}) */
+ memcpy (seed_plus, seed, seedlen);
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
+ gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+ for (i=0; i < sizeof value_u; i++)
+ value_u[i] ^= digest[i];
+
+ /* Step 3: Form q from U */
+ gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, sizeof value_u, NULL));
+ if (ec)
+ goto leave;
+ mpi_set_highbit (prime_q, qbits-1 );
+ mpi_set_bit (prime_q, 0);
+
+ /* Step 4: Test whether Q is prime using 64 round of Rabin-Miller. */
+ if (check_prime (prime_q, val_2, 64, NULL, NULL))
+ break; /* Yes, Q is prime. */
+
+ /* Step 5. */
+ seed = NULL; /* Force a new seed at Step 1. */
+ }
+
+ /* Step 6. Note that we do no use an explicit offset but increment
+ SEED_PLUS accordingly. SEED_PLUS is currently SEED+1. */
+ counter = 0;
+
+ /* Generate P. */
+ prime_p = gcry_mpi_new (pbits);
+ for (;;)
+ {
+ /* Step 7: For k = 0,...n let
+ V_k = sha1(seed+offset+k) mod 2^{qbits}
+ Step 8: W = V_0 + V_1*2^160 +
+ ...
+ + V_{n-1}*2^{(n-1)*160}
+ + (V_{n} mod 2^b)*2^{n*160}
+ */
+ mpi_set_ui (value_w, 0);
+ for (value_k=0; value_k <= value_n; value_k++)
+ {
+ /* There is no need to have an explicit offset variable: In
+ the first round we shall have an offset of 2, this is
+ achieved by using SEED_PLUS which is already at SEED+1,
+ thus we just need to increment it once again. The
+ requirement for the next round is to update offset by N,
+ which we implictly did at the end of this loop, and then
+ to add one; this one is the same as in the first round. */
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+
+ gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, sizeof digest, NULL));
+ if (ec)
+ goto leave;
+ if (value_k == value_n)
+ mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+ mpi_lshift (tmpval, tmpval, value_k*qbits);
+ mpi_add (value_w, value_w, tmpval);
+ }
+
+ /* Step 8 continued: X = W + 2^{L-1} */
+ mpi_set_ui (value_x, 0);
+ mpi_set_highbit (value_x, pbits-1);
+ mpi_add (value_x, value_x, value_w);
+
+ /* Step 9: c = X mod 2q, p = X - (c - 1) */
+ mpi_mul_2exp (tmpval, prime_q, 1);
+ mpi_mod (tmpval, value_x, tmpval);
+ mpi_sub_ui (tmpval, tmpval, 1);
+ mpi_sub (prime_p, value_x, tmpval);
+
+ /* Step 10: If p < 2^{L-1} skip the primality test. */
+ /* Step 11 and 12: Primality test. */
+ if (mpi_get_nbits (prime_p) >= pbits-1
+ && check_prime (prime_p, val_2, 64, NULL, NULL) )
+ break; /* Yes, P is prime, continue with Step 15. */
+
+ /* Step 13: counter = counter + 1, offset = offset + n + 1. */
+ counter++;
+
+ /* Step 14: If counter >= 2^12 goto Step 1. */
+ if (counter >= 4096)
+ goto restart;
+ }
+
+ /* Step 15: Save p, q, counter and seed. */
+/* log_debug ("fips186-2 pbits p=%u q=%u counter=%d\n", */
+/* mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); */
+/* log_printhex("fips186-2 seed:", seed, seedlen); */
+/* log_mpidump ("fips186-2 prime p", prime_p); */
+/* log_mpidump ("fips186-2 prime q", prime_q); */
+ if (r_q)
+ {
+ *r_q = prime_q;
+ prime_q = NULL;
+ }
+ if (r_p)
+ {
+ *r_p = prime_p;
+ prime_p = NULL;
+ }
+ if (r_counter)
+ *r_counter = counter;
+ if (r_seed && r_seedlen)
+ {
+ memcpy (seed_plus, seed, seedlen);
+ *r_seed = seed_plus;
+ seed_plus = NULL;
+ *r_seedlen = seedlen;
+ }
+
+
+ leave:
+ gcry_mpi_release (tmpval);
+ gcry_mpi_release (value_x);
+ gcry_mpi_release (value_w);
+ gcry_mpi_release (prime_p);
+ gcry_mpi_release (prime_q);
+ gcry_free (seed_plus);
+ gcry_mpi_release (val_2);
+ return ec;
+}
+
+
+\f
+/* WARNING: The code below has not yet been tested! However, it is
+ not yet used. We need to wait for FIPS 186-3 final and for test
+ vectors.
+
+ Generate the two prime used for DSA using the algorithm specified
+ in FIPS 186-3, A.1.1.2. PBITS is the desired length of the prime P
+ and a QBITS the length of the prime Q. If SEED is not supplied and
+ SEEDLEN is 0 the function generates an appropriate SEED. On
+ success the generated primes are stored at R_Q and R_P, the counter
+ value is stored at R_COUNTER and the seed actually used for
+ generation is stored at R_SEED and R_SEEDVALUE. The hash algorithm
+ used is stored at R_HASHALGO.
+
+ Note that this function is very similar to the fips186_2 code. Due
+ to the minor differences, other buffer sizes and for documentarion,
+ we use a separate function.
+*/
+gpg_err_code_t
+_gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen,
+ int *r_hashalgo)
+{
+ gpg_err_code_t ec;
+ unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */
+ unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */
+ unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */
+ gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */
+ gcry_mpi_t tmpval = NULL; /* Helper variable. */
+ int hashalgo; /* The id of the Approved Hash Function. */
+ int i;
+
+ unsigned char value_u[256/8];
+ int value_n, value_b, value_j;
+ int counter;
+ gcry_mpi_t value_w = NULL;
+ gcry_mpi_t value_x = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
+
+ gcry_assert (sizeof seed_help_buffer == sizeof digest
+ && sizeof seed_help_buffer == sizeof value_u);
+
+ /* Step 1: Check the requested prime lengths. */
+ /* Note that due to the size of our buffers QBITS is limited to 256. */
+ if (pbits == 1024 && qbits == 160)
+ hashalgo = GCRY_MD_SHA1;
+ else if (pbits == 2048 && qbits == 224)
+ hashalgo = GCRY_MD_SHA224;
+ else if (pbits == 2048 && qbits == 256)
+ hashalgo = GCRY_MD_SHA256;
+ else if (pbits == 3072 && qbits == 256)
+ hashalgo = GCRY_MD_SHA256;
+ else
+ return GPG_ERR_INV_KEYLEN;
+
+ /* Also check that the hash algorithm is available. */
+ ec = gpg_err_code (gcry_md_test_algo (hashalgo));
+ if (ec)
+ return ec;
+ gcry_assert (qbits/8 <= sizeof digest);
+ gcry_assert (gcry_md_get_algo_dlen (hashalgo) == qbits/8);
+
+
+ /* Step 2: Check seedlen. */
+ if (!seed && !seedlen)
+ ; /* No seed value given: We are asked to generate it. */
+ else if (!seed || seedlen < qbits/8)
+ return GPG_ERR_INV_ARG;
+
+ /* Allocate a buffer to later compute SEED+some_increment and a few
+ helper variables. */
+ seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer?
+ sizeof seed_help_buffer : seedlen);
+ if (!seed_plus)
+ {
+ ec = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ val_2 = mpi_alloc_set_ui (2);
+ value_w = gcry_mpi_new (pbits);
+ value_x = gcry_mpi_new (pbits);
+
+ /* Step 3: n = \lceil L / outlen \rceil - 1 */
+ value_n = (pbits + qbits - 1) / qbits - 1;
+ /* Step 4: b = L - 1 - (n * outlen) */
+ value_b = pbits - 1 - (value_n * qbits);
+
+ restart:
+ /* Generate Q. */
+ for (;;)
+ {
+ /* Step 5: Generate a (new) seed unless one has been supplied. */
+ if (!seed)
+ {
+ seedlen = qbits/8;
+ gcry_assert (seedlen <= sizeof seed_help_buffer);
+ gcry_create_nonce (seed_help_buffer, seedlen);
+ seed = seed_help_buffer;
+ }
+
+ /* Step 6: U = hash(seed) */
+ gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
+
+ /* Step 7: q = 2^{N-1} + U + 1 - (U mod 2) */
+ if ( !(value_u[qbits/8-1] & 0x01) )
+ {
+ for (i=qbits/8-1; i >= 0; i--)
+ {
+ value_u[i]++;
+ if (value_u[i])
+ break;
+ }
+ }
+ gcry_mpi_release (prime_q); prime_q = NULL;
+ ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ value_u, sizeof value_u, NULL));
+ if (ec)
+ goto leave;
+ mpi_set_highbit (prime_q, qbits-1 );
+
+ /* Step 8: Test whether Q is prime using 64 round of Rabin-Miller.
+ According to table C.1 this is sufficient for all
+ supported prime sizes (i.e. up 3072/256). */
+ if (check_prime (prime_q, val_2, 64, NULL, NULL))
+ break; /* Yes, Q is prime. */
+
+ /* Step 8. */
+ seed = NULL; /* Force a new seed at Step 5. */
+ }
+
+ /* Step 11. Note that we do no use an explicit offset but increment
+ SEED_PLUS accordingly. */
+ memcpy (seed_plus, seed, seedlen);
+ counter = 0;
+
+ /* Generate P. */
+ prime_p = gcry_mpi_new (pbits);
+ for (;;)
+ {
+ /* Step 11.1: For j = 0,...n let
+ V_j = hash(seed+offset+j)
+ Step 11.2: W = V_0 + V_1*2^outlen +
+ ...
+ + V_{n-1}*2^{(n-1)*outlen}
+ + (V_{n} mod 2^b)*2^{n*outlen}
+ */
+ mpi_set_ui (value_w, 0);
+ for (value_j=0; value_j <= value_n; value_j++)
+ {
+ /* There is no need to have an explicit offset variable: In
+ the first round we shall have an offset of 1 and a j of
+ 0. This is achieved by incrementing SEED_PLUS here. For
+ the next round offset is implicitly updated by using
+ SEED_PLUS again. */
+ for (i=seedlen-1; i >= 0; i--)
+ {
+ seed_plus[i]++;
+ if (seed_plus[i])
+ break;
+ }
+ gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+
+ gcry_mpi_release (tmpval); tmpval = NULL;
+ ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+ digest, sizeof digest, NULL));
+ if (ec)
+ goto leave;
+ if (value_j == value_n)
+ mpi_clear_highbit (tmpval, value_b); /* (V_n mod 2^b) */
+ mpi_lshift (tmpval, tmpval, value_j*qbits);
+ mpi_add (value_w, value_w, tmpval);
+ }
+
+ /* Step 11.3: X = W + 2^{L-1} */
+ mpi_set_ui (value_x, 0);
+ mpi_set_highbit (value_x, pbits-1);
+ mpi_add (value_x, value_x, value_w);
+
+ /* Step 11.4: c = X mod 2q */
+ mpi_mul_2exp (tmpval, prime_q, 1);
+ mpi_mod (tmpval, value_x, tmpval);
+
+ /* Step 11.5: p = X - (c - 1) */
+ mpi_sub_ui (tmpval, tmpval, 1);
+ mpi_sub (prime_p, value_x, tmpval);
+
+ /* Step 11.6: If p < 2^{L-1} skip the primality test. */
+ /* Step 11.7 and 11.8: Primality test. */
+ if (mpi_get_nbits (prime_p) >= pbits-1
+ && check_prime (prime_p, val_2, 64, NULL, NULL) )
+ break; /* Yes, P is prime, continue with Step 15. */
+
+ /* Step 11.9: counter = counter + 1, offset = offset + n + 1.
+ If counter >= 4L goto Step 5. */
+ counter++;
+ if (counter >= 4*pbits)
+ goto restart;
+ }
+
+ /* Step 12: Save p, q, counter and seed. */
+ log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n",
+ mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter);
+ log_printhex("fips186-3 seed:", seed, seedlen);
+ log_mpidump ("fips186-3 prime p", prime_p);
+ log_mpidump ("fips186-3 prime q", prime_q);
+ if (r_q)
+ {
+ *r_q = prime_q;
+ prime_q = NULL;
+ }
+ if (r_p)
+ {
+ *r_p = prime_p;
+ prime_p = NULL;
+ }
+ if (r_counter)
+ *r_counter = counter;
+ if (r_seed && r_seedlen)
+ {
+ memcpy (seed_plus, seed, seedlen);
+ *r_seed = seed_plus;
+ seed_plus = NULL;
+ *r_seedlen = seedlen;
+ }
+ if (r_hashalgo)
+ *r_hashalgo = hashalgo;
+
+ leave:
+ gcry_mpi_release (tmpval);
+ gcry_mpi_release (value_x);
+ gcry_mpi_release (value_w);
+ gcry_mpi_release (prime_p);
+ gcry_mpi_release (prime_q);
+ gcry_free (seed_plus);
+ gcry_mpi_release (val_2);
+ return ec;
+}
--- /dev/null
+/* pubkey.c - pubkey dispatcher
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
+ * 2007, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "ath.h"
+
+
+static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
+ gcry_mpi_t *data, gcry_mpi_t *skey,
+ int flags);
+static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
+ gcry_mpi_t hash, gcry_mpi_t *skey);
+static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
+ gcry_mpi_t *data, gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t),
+ void *opaque);
+
+
+/* A dummy extraspec so that we do not need to tests the extraspec
+ field from the module specification against NULL and instead
+ directly test the respective fields of extraspecs. */
+static pk_extra_spec_t dummy_extra_spec;
+
+
+/* This is the list of the default public-key ciphers included in
+ libgcrypt. FIPS_ALLOWED indicated whether the algorithm is used in
+ FIPS mode. */
+static struct pubkey_table_entry
+{
+ gcry_pk_spec_t *pubkey;
+ pk_extra_spec_t *extraspec;
+ unsigned int algorithm;
+ int fips_allowed;
+} pubkey_table[] =
+ {
+#if USE_RSA
+ { &_gcry_pubkey_spec_rsa,
+ &_gcry_pubkey_extraspec_rsa, GCRY_PK_RSA, 1},
+#endif
+#if USE_ELGAMAL
+ { &_gcry_pubkey_spec_elg,
+ &_gcry_pubkey_extraspec_elg, GCRY_PK_ELG },
+ { &_gcry_pubkey_spec_elg,
+ &_gcry_pubkey_extraspec_elg, GCRY_PK_ELG_E },
+#endif
+#if USE_DSA
+ { &_gcry_pubkey_spec_dsa,
+ &_gcry_pubkey_extraspec_dsa, GCRY_PK_DSA, 1 },
+#endif
+#if USE_ECC
+ { &_gcry_pubkey_spec_ecdsa,
+ &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
+ { &_gcry_pubkey_spec_ecdh,
+ &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
+#endif
+ { NULL, 0 },
+ };
+
+/* List of registered ciphers. */
+static gcry_module_t pubkeys_registered;
+
+/* This is the lock protecting PUBKEYS_REGISTERED. */
+static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
+
+/* Flag to check whether the default pubkeys have already been
+ registered. */
+static int default_pubkeys_registered;
+
+/* Convenient macro for registering the default digests. */
+#define REGISTER_DEFAULT_PUBKEYS \
+ do \
+ { \
+ ath_mutex_lock (&pubkeys_registered_lock); \
+ if (! default_pubkeys_registered) \
+ { \
+ pk_register_default (); \
+ default_pubkeys_registered = 1; \
+ } \
+ ath_mutex_unlock (&pubkeys_registered_lock); \
+ } \
+ while (0)
+
+/* These dummy functions are used in case a cipher implementation
+ refuses to provide it's own functions. */
+
+static gcry_err_code_t
+dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+ (void)algorithm;
+ (void)nbits;
+ (void)dummy;
+ (void)skey;
+ (void)retfactors;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
+{
+ (void)algorithm;
+ (void)skey;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *pkey, int flags)
+{
+ (void)algorithm;
+ (void)resarr;
+ (void)data;
+ (void)pkey;
+ (void)flags;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags)
+{
+ (void)algorithm;
+ (void)result;
+ (void)data;
+ (void)skey;
+ (void)flags;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *skey)
+{
+ (void)algorithm;
+ (void)resarr;
+ (void)data;
+ (void)skey;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static gcry_err_code_t
+dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+ gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+{
+ (void)algorithm;
+ (void)hash;
+ (void)data;
+ (void)pkey;
+ (void)cmp;
+ (void)opaquev;
+ fips_signal_error ("using dummy public key function");
+ return GPG_ERR_NOT_IMPLEMENTED;
+}
+
+static unsigned
+dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
+{
+ (void)algorithm;
+ (void)pkey;
+ fips_signal_error ("using dummy public key function");
+ return 0;
+}
+
+/* Internal function. Register all the pubkeys included in
+ PUBKEY_TABLE. Returns zero on success or an error code. */
+static void
+pk_register_default (void)
+{
+ gcry_err_code_t err = 0;
+ int i;
+
+ for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
+ {
+#define pubkey_use_dummy(func) \
+ if (! pubkey_table[i].pubkey->func) \
+ pubkey_table[i].pubkey->func = dummy_##func;
+
+ pubkey_use_dummy (generate);
+ pubkey_use_dummy (check_secret_key);
+ pubkey_use_dummy (encrypt);
+ pubkey_use_dummy (decrypt);
+ pubkey_use_dummy (sign);
+ pubkey_use_dummy (verify);
+ pubkey_use_dummy (get_nbits);
+#undef pubkey_use_dummy
+
+ err = _gcry_module_add (&pubkeys_registered,
+ pubkey_table[i].algorithm,
+ (void *) pubkey_table[i].pubkey,
+ (void *) pubkey_table[i].extraspec,
+ NULL);
+ }
+
+ if (err)
+ BUG ();
+}
+
+/* Internal callback function. Used via _gcry_module_lookup. */
+static int
+gcry_pk_lookup_func_name (void *spec, void *data)
+{
+ gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
+ char *name = (char *) data;
+ const char **aliases = pubkey->aliases;
+ int ret = stricmp (name, pubkey->name);
+
+ while (ret && *aliases)
+ ret = stricmp (name, *aliases++);
+
+ return ! ret;
+}
+
+/* Internal function. Lookup a pubkey entry by it's name. */
+static gcry_module_t
+gcry_pk_lookup_name (const char *name)
+{
+ gcry_module_t pubkey;
+
+ pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
+ gcry_pk_lookup_func_name);
+
+ return pubkey;
+}
+
+/* Register a new pubkey module whose specification can be found in
+ PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t
+_gcry_pk_register (gcry_pk_spec_t *pubkey,
+ pk_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t mod;
+
+ /* We do not support module loading in fips mode. */
+ if (fips_mode ())
+ return gpg_error (GPG_ERR_NOT_SUPPORTED);
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ err = _gcry_module_add (&pubkeys_registered, 0,
+ (void *) pubkey,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
+ &mod);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (! err)
+ {
+ *module = mod;
+ *algorithm_id = mod->mod_id;
+ }
+
+ return err;
+}
+
+/* Unregister the pubkey identified by ID, which must have been
+ registered with gcry_pk_register. */
+void
+gcry_pk_unregister (gcry_module_t module)
+{
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+static void
+release_mpi_array (gcry_mpi_t *array)
+{
+ for (; *array; array++)
+ {
+ mpi_free(*array);
+ *array = NULL;
+ }
+}
+
+/****************
+ * Map a string to the pubkey algo
+ */
+int
+gcry_pk_map_name (const char *string)
+{
+ gcry_module_t pubkey;
+ int algorithm = 0;
+
+ if (!string)
+ return 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = gcry_pk_lookup_name (string);
+ if (pubkey)
+ {
+ algorithm = pubkey->mod_id;
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return algorithm;
+}
+
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *
+gcry_pk_algo_name (int algorithm)
+{
+ gcry_module_t pubkey;
+ const char *name;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ name = ((gcry_pk_spec_t *) pubkey->spec)->name;
+ _gcry_module_release (pubkey);
+ }
+ else
+ name = "?";
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return name;
+}
+
+
+/* A special version of gcry_pk_algo name to return the first aliased
+ name of the algorithm. This is required to adhere to the spki
+ specs where the algorithm names are lowercase. */
+const char *
+_gcry_pk_aliased_algo_name (int algorithm)
+{
+ const char *name = NULL;
+ gcry_module_t module;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
+
+ name = pubkey->aliases? *pubkey->aliases : NULL;
+ if (!name || !*name)
+ name = pubkey->name;
+ _gcry_module_release (module);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return name;
+}
+
+
+static void
+disable_pubkey_algo (int algorithm)
+{
+ gcry_module_t pubkey;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
+ pubkey->flags |= FLAG_MODULE_DISABLED;
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+
+/****************
+ * A USE of 0 means: don't care.
+ */
+static gcry_err_code_t
+check_pubkey_algo (int algorithm, unsigned use)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_pk_spec_t *pubkey;
+ gcry_module_t module;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+
+ if (((use & GCRY_PK_USAGE_SIGN)
+ && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
+ || ((use & GCRY_PK_USAGE_ENCR)
+ && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
+ err = GPG_ERR_WRONG_PUBKEY_ALGO;
+ else if (module->flags & FLAG_MODULE_DISABLED)
+ err = GPG_ERR_PUBKEY_ALGO;
+ _gcry_module_release (module);
+ }
+ else
+ err = GPG_ERR_PUBKEY_ALGO;
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return err;
+}
+
+
+/****************
+ * Return the number of public key material numbers
+ */
+static int
+pubkey_get_npkey (int algorithm)
+{
+ gcry_module_t pubkey;
+ int npkey = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return npkey;
+}
+
+/****************
+ * Return the number of secret key material numbers
+ */
+static int
+pubkey_get_nskey (int algorithm)
+{
+ gcry_module_t pubkey;
+ int nskey = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return nskey;
+}
+
+/****************
+ * Return the number of signature material numbers
+ */
+static int
+pubkey_get_nsig (int algorithm)
+{
+ gcry_module_t pubkey;
+ int nsig = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return nsig;
+}
+
+/****************
+ * Return the number of encryption material numbers
+ */
+static int
+pubkey_get_nenc (int algorithm)
+{
+ gcry_module_t pubkey;
+ int nenc = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return nenc;
+}
+
+
+/* Generate a new public key with algorithm ALGORITHM of size NBITS
+ and return it at SKEY. USE_E depends on the ALGORITHM. GENPARMS
+ is passed to the algorithm module if it features an extended
+ generation function. RETFACTOR is used by some algorithms to
+ return certain additional information which are in general not
+ required.
+
+ The function returns the error code number or 0 on success. */
+static gcry_err_code_t
+pubkey_generate (int algorithm,
+ unsigned int nbits,
+ unsigned long use_e,
+ gcry_sexp_t genparms,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+ gcry_sexp_t *r_extrainfo)
+{
+ gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
+ gcry_module_t pubkey;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ pk_extra_spec_t *extraspec = pubkey->extraspec;
+
+ if (extraspec && extraspec->ext_generate)
+ {
+ /* Use the extended generate function. */
+ ec = extraspec->ext_generate
+ (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
+ }
+ else
+ {
+ /* Use the standard generate function. */
+ ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
+ (algorithm, nbits, use_e, skey, retfactors);
+ }
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return ec;
+}
+
+
+static gcry_err_code_t
+pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
+ gcry_module_t pubkey;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
+ (algorithm, skey);
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return err;
+}
+
+
+/****************
+ * This is the interface to the public key encryption. Encrypt DATA
+ * with PKEY and put it into RESARR which should be an array of MPIs
+ * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
+ * check with pubkey_get_nenc() )
+ */
+static gcry_err_code_t
+pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *pkey, int flags)
+{
+ gcry_pk_spec_t *pubkey;
+ gcry_module_t module;
+ gcry_err_code_t rc;
+ int i;
+
+ /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
+ an extra failsafe protection we explicitly test for fips mode
+ here. */
+ if (DBG_CIPHER && !fips_mode ())
+ {
+ log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
+ for(i = 0; i < pubkey_get_npkey (algorithm); i++)
+ log_mpidump (" pkey:", pkey[i]);
+ log_mpidump (" data:", data);
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
+ _gcry_module_release (module);
+ goto ready;
+ }
+ rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (!rc && DBG_CIPHER && !fips_mode ())
+ {
+ for(i = 0; i < pubkey_get_nenc (algorithm); i++)
+ log_mpidump(" encr:", resarr[i] );
+ }
+ return rc;
+}
+
+
+/****************
+ * This is the interface to the public key decryption.
+ * ALGO gives the algorithm to use and this implicitly determines
+ * the size of the arrays.
+ * result is a pointer to a mpi variable which will receive a
+ * newly allocated mpi or NULL in case of an error.
+ */
+static gcry_err_code_t
+pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags)
+{
+ gcry_pk_spec_t *pubkey;
+ gcry_module_t module;
+ gcry_err_code_t rc;
+ int i;
+
+ *result = NULL; /* so the caller can always do a mpi_free */
+ if (DBG_CIPHER && !fips_mode ())
+ {
+ log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
+ for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+ log_mpidump (" skey:", skey[i]);
+ for(i = 0; i < pubkey_get_nenc (algorithm); i++)
+ log_mpidump (" data:", data[i]);
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ rc = pubkey->decrypt (algorithm, result, data, skey, flags);
+ _gcry_module_release (module);
+ goto ready;
+ }
+
+ rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (!rc && DBG_CIPHER && !fips_mode ())
+ log_mpidump (" plain:", *result);
+
+ return rc;
+}
+
+
+/****************
+ * This is the interface to the public key signing.
+ * Sign data with skey and put the result into resarr which
+ * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
+ * algorithm allows this - check with pubkey_get_nsig() )
+ */
+static gcry_err_code_t
+pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *skey)
+{
+ gcry_pk_spec_t *pubkey;
+ gcry_module_t module;
+ gcry_err_code_t rc;
+ int i;
+
+ if (DBG_CIPHER && !fips_mode ())
+ {
+ log_debug ("pubkey_sign: algo=%d\n", algorithm);
+ for(i = 0; i < pubkey_get_nskey (algorithm); i++)
+ log_mpidump (" skey:", skey[i]);
+ log_mpidump(" data:", data );
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ rc = pubkey->sign (algorithm, resarr, data, skey);
+ _gcry_module_release (module);
+ goto ready;
+ }
+
+ rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (!rc && DBG_CIPHER && !fips_mode ())
+ for (i = 0; i < pubkey_get_nsig (algorithm); i++)
+ log_mpidump (" sig:", resarr[i]);
+
+ return rc;
+}
+
+/****************
+ * Verify a public key signature.
+ * Return 0 if the signature is good
+ */
+static gcry_err_code_t
+pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
+ gcry_mpi_t *pkey,
+ int (*cmp)(void *, gcry_mpi_t), void *opaquev)
+{
+ gcry_pk_spec_t *pubkey;
+ gcry_module_t module;
+ gcry_err_code_t rc;
+ int i;
+
+ if (DBG_CIPHER && !fips_mode ())
+ {
+ log_debug ("pubkey_verify: algo=%d\n", algorithm);
+ for (i = 0; i < pubkey_get_npkey (algorithm); i++)
+ log_mpidump (" pkey", pkey[i]);
+ for (i = 0; i < pubkey_get_nsig (algorithm); i++)
+ log_mpidump (" sig", data[i]);
+ log_mpidump (" hash", hash);
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (module)
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
+ _gcry_module_release (module);
+ goto ready;
+ }
+
+ rc = GPG_ERR_PUBKEY_ALGO;
+
+ ready:
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ return rc;
+}
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME or - if R_RAME is NULL - copy it into the caller
+ provided buffer SPACE; either SPACE or R_FRAME may be used. If
+ SPACE if not NULL, the caller must provide a buffer of at least
+ NBYTES. If the resulting octet string is shorter than NBYTES pad
+ it to the left with zeroes. If VALUE does not fit into NBYTES
+ return an error code. */
+static gpg_err_code_t
+octet_string_from_mpi (unsigned char **r_frame, void *space,
+ gcry_mpi_t value, size_t nbytes)
+{
+ gpg_err_code_t rc;
+ size_t nframe, noff, n;
+ unsigned char *frame;
+
+ if (!r_frame == !space)
+ return GPG_ERR_INV_ARG; /* Only one may be used. */
+
+ if (r_frame)
+ *r_frame = NULL;
+
+ rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
+ NULL, 0, &nframe, value));
+ if (rc)
+ return rc;
+ if (nframe > nbytes)
+ return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
+
+ noff = (nframe < nbytes)? nbytes - nframe : 0;
+ n = nframe + noff;
+ if (space)
+ frame = space;
+ else
+ {
+ frame = mpi_is_secure (value)? gcry_malloc_secure (n) : gcry_malloc (n);
+ if (!frame)
+ {
+ rc = gpg_err_code_from_syserror ();
+ return rc;
+ }
+ }
+ if (noff)
+ memset (frame, 0, noff);
+ nframe += noff;
+ rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
+ frame+noff, nframe-noff, NULL, value));
+ if (rc)
+ {
+ gcry_free (frame);
+ return rc;
+ }
+
+ if (r_frame)
+ *r_frame = frame;
+ return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+ type 2 padding. On sucess the result is stored as a new MPI at
+ R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests. Note that this value may not
+ contain zero bytes.
+
+ We encode the value in this way:
+
+ 0 2 RND(n bytes) 0 VALUE
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 2 is the block type.
+ RND are non-zero random bytes.
+
+ (Note that OpenPGP includes the cipher algorithm and a checksum in
+ VALUE; the caller needs to prepare the value accordingly.)
+ */
+static gcry_err_code_t
+pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *random_override,
+ size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ unsigned char *p;
+
+ if (valuelen + 7 > nframe || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ if ( !(frame = gcry_malloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 2; /* block type */
+ i = nframe - 3 - valuelen;
+ gcry_assert (i > 0);
+
+ if (random_override)
+ {
+ int j;
+
+ if (random_override_len != i)
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ /* Check that random does not include a zero byte. */
+ for (j=0; j < random_override_len; j++)
+ if (!random_override[j])
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + n, random_override, random_override_len);
+ n += random_override_len;
+ }
+ else
+ {
+ p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+ /* Replace zero bytes by new values. */
+ for (;;)
+ {
+ int j, k;
+ unsigned char *pp;
+
+ /* Count the zero bytes. */
+ for (j=k=0; j < i; j++)
+ {
+ if (!p[j])
+ k++;
+ }
+ if (!k)
+ break; /* Okay: no (more) zero bytes. */
+
+ k += k/128 + 3; /* Better get some more. */
+ pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+ for (j=0; j < i && k; )
+ {
+ if (!p[j])
+ p[j] = pp[--k];
+ if (p[j])
+ j++;
+ }
+ gcry_free (pp);
+ }
+ memcpy (frame+n, p, i);
+ n += i;
+ gcry_free (p);
+ }
+
+ frame[n++] = 0;
+ memcpy (frame+n, value, valuelen);
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
+ NBITS is the size of the secret key. On success the result is
+ stored as a newly allocated buffer at R_RESULT and its valid length at
+ R_RESULTLEN. On error NULL is stored at R_RESULT. */
+static gcry_err_code_t
+pkcs1_decode_for_encryption (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, gcry_mpi_t value)
+{
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ size_t n;
+
+ *r_result = NULL;
+
+ if ( !(frame = gcry_malloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
+ if (err)
+ {
+ gcry_free (frame);
+ return gcry_err_code (err);
+ }
+
+ nframe = n; /* Set NFRAME to the actual length. */
+
+ /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
+
+ pkcs#1 requires that the first byte is zero. Our MPIs usually
+ strip leading zero bytes; thus we are not able to detect them.
+ However due to the way gcry_mpi_print is implemented we may see
+ leading zero bytes nevertheless. We handle this by making the
+ first zero byte optional. */
+ if (nframe < 4)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Too short. */
+ }
+ n = 0;
+ if (!frame[0])
+ n++;
+ if (frame[n++] != 0x02)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Wrong block type. */
+ }
+
+ /* Skip the non-zero random bytes and the terminating zero byte. */
+ for (; n < nframe && frame[n] != 0x00; n++)
+ ;
+ if (n+1 >= nframe)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* No zero byte. */
+ }
+ n++; /* Skip the zero byte. */
+
+ /* To avoid an extra allocation we reuse the frame buffer. The only
+ caller of this function will anyway free the result soon. */
+ memmove (frame, frame + n, nframe - n);
+ *r_result = frame;
+ *r_resultlen = nframe - n;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from PKCS#1 block type 2 encoded data:",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
+ using the pkcs#1 block type 1 padding. On success the result is
+ stored as a new MPI at R_RESULT. On error the value at R_RESULT is
+ undefined.
+
+ We encode the value in this way:
+
+ 0 1 PAD(n bytes) 0 ASN(asnlen bytes) VALUE(valuelen bytes)
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 1 is the block type.
+ PAD consists of 0xff bytes.
+ 0 marks the end of the padding.
+ ASN is the DER encoding of the hash algorithm; along with the VALUE
+ it yields a valid DER encoding.
+
+ (Note that PGP prior to version 2.3 encoded the message digest as:
+ 0 1 MD(16 bytes) 0 PAD(n bytes) 1
+ The MD is always 16 bytes here because it's always MD5. GnuPG
+ does not not support pre-v2.3 signatures, but I'm including this
+ comment so the information is easily found if needed.)
+*/
+static gcry_err_code_t
+pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ int algo)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ byte asn[100];
+ byte *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ size_t asnlen, dlen;
+
+ asnlen = DIM(asn);
+ dlen = gcry_md_get_algo_dlen (algo);
+
+ if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+ {
+ /* We don't have yet all of the above algorithms. */
+ return GPG_ERR_NOT_IMPLEMENTED;
+ }
+
+ if ( valuelen != dlen )
+ {
+ /* Hash value does not match the length of digest for
+ the given algorithm. */
+ return GPG_ERR_CONFLICT;
+ }
+
+ if ( !dlen || dlen + asnlen + 4 > nframe)
+ {
+ /* Can't encode an DLEN byte digest MD into an NFRAME byte
+ frame. */
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if ( !(frame = gcry_malloc (nframe)) )
+ return gpg_err_code_from_syserror ();
+
+ /* Assemble the pkcs#1 block type 1. */
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - valuelen - asnlen - 3 ;
+ gcry_assert (i > 1);
+ memset (frame+n, 0xff, i );
+ n += i;
+ frame[n++] = 0;
+ memcpy (frame+n, asn, asnlen);
+ n += asnlen;
+ memcpy (frame+n, value, valuelen );
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ /* Convert it into an MPI. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* Mask generation function for OAEP. See RFC-3447 B.2.1. */
+static gcry_err_code_t
+mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
+ int algo)
+{
+ size_t dlen, nbytes, n;
+ int idx;
+ gcry_md_hd_t hd;
+ gcry_error_t err;
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ return gpg_err_code (err);
+
+ dlen = gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1 which would be assert(OUTLEN <= 2^32). The loop
+ in step 3 is merged with step 4 by concatenating no more octets
+ than what would fit into OUTPUT. The ceiling for the counter IDX
+ is implemented indirectly. */
+ nbytes = 0; /* Step 2. */
+ idx = 0;
+ while ( nbytes < outlen )
+ {
+ unsigned char c[4], *digest;
+
+ if (idx)
+ gcry_md_reset (hd);
+
+ c[0] = (idx >> 24) & 0xFF;
+ c[1] = (idx >> 16) & 0xFF;
+ c[2] = (idx >> 8) & 0xFF;
+ c[3] = idx & 0xFF;
+ idx++;
+
+ gcry_md_write (hd, seed, seedlen);
+ gcry_md_write (hd, c, 4);
+ digest = gcry_md_read (hd, 0);
+
+ n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
+ memcpy (output+nbytes, digest, n);
+ nbytes += n;
+ }
+
+ gcry_md_close (hd);
+ return GPG_ERR_NO_ERROR;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP encoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. {VALUE,VALUELEN} is the message to
+ encrypt. {LABEL,LABELLEN} is the optional label to be associated
+ with the message, if LABEL is NULL the default is to use the empty
+ string as label. On success the encoded ciphertext is returned at
+ R_RESULT.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests.
+
+ Here is figure 1 from the RFC depicting the process:
+
+ +----------+---------+-------+
+ DB = | lHash | PS | M |
+ +----------+---------+-------+
+ |
+ +----------+ V
+ | seed |--> MGF ---> xor
+ +----------+ |
+ | |
+ +--+ V |
+ |00| xor <----- MGF <-----|
+ +--+ | |
+ | | |
+ V V V
+ +--+----------+----------------------------+
+ EM = |00|maskedSeed| maskedDB |
+ +--+----------+----------------------------+
+ */
+static gcry_err_code_t
+oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *label, size_t labellen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ unsigned char *p;
+ size_t hlen;
+ size_t n;
+
+ *r_result = NULL;
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ hlen = gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1a which would be to check that LABELLEN is not
+ greater than 2^61-1. See rfc-3447 7.1.1. */
+
+ /* Step 1b. Note that the obsolete rfc-2437 uses the check:
+ valuelen > nframe - 2 * hlen - 1 . */
+ if (valuelen > nframe - 2 * hlen - 2 || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ /* Allocate the frame. */
+ frame = gcry_calloc_secure (1, nframe);
+ if (!frame)
+ return gpg_err_code_from_syserror ();
+
+ /* Step 2a: Compute the hash of the label. We store it in the frame
+ where later the maskedDB will commence. */
+ gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
+
+ /* Step 2b: Set octet string to zero. */
+ /* This has already been done while allocating FRAME. */
+
+ /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M. */
+ n = nframe - valuelen - 1;
+ frame[n] = 0x01;
+ memcpy (frame + n + 1, value, valuelen);
+
+ /* Step 3d: Generate seed. We store it where the maskedSeed will go
+ later. */
+ if (random_override)
+ {
+ if (random_override_len != hlen)
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + 1, random_override, hlen);
+ }
+ else
+ gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
+
+ /* Step 2e and 2f: Create maskedDB. */
+ {
+ unsigned char *dmask;
+
+ dmask = gcry_malloc_secure (nframe - hlen - 1);
+ if (!dmask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ return rc;
+ }
+ rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
+ if (rc)
+ {
+ gcry_free (dmask);
+ gcry_free (frame);
+ return rc;
+ }
+ for (n = 1 + hlen, p = dmask; n < nframe; n++)
+ frame[n] ^= *p++;
+ gcry_free (dmask);
+ }
+
+ /* Step 2g and 2h: Create maskedSeed. */
+ {
+ unsigned char *smask;
+
+ smask = gcry_malloc_secure (hlen);
+ if (!smask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ return rc;
+ }
+ rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
+ if (rc)
+ {
+ gcry_free (smask);
+ gcry_free (frame);
+ return rc;
+ }
+ for (n = 1, p = smask; n < 1 + hlen; n++)
+ frame[n] ^= *p++;
+ gcry_free (smask);
+ }
+
+ /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB. */
+ /* This has already been done by using in-place operations. */
+
+ /* Convert the stuff into an MPI as expected by the caller. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("OAEP encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP decoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. VALUE is the raw decrypted message
+ {LABEL,LABELLEN} is the optional label to be associated with the
+ message, if LABEL is NULL the default is to use the empty string as
+ label. On success the plaintext is returned as a newly allocated
+ buffer at R_RESULT; its valid length is stored at R_RESULTLEN. On
+ error NULL is stored at R_RESULT. */
+static gcry_err_code_t
+oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, int algo,
+ gcry_mpi_t value, const unsigned char *label, size_t labellen)
+{
+ gcry_err_code_t rc;
+ unsigned char *frame = NULL; /* Encoded messages (EM). */
+ unsigned char *masked_seed; /* Points into FRAME. */
+ unsigned char *masked_db; /* Points into FRAME. */
+ unsigned char *seed = NULL; /* Allocated space for the seed and DB. */
+ unsigned char *db; /* Points into SEED. */
+ unsigned char *lhash = NULL; /* Hash of the label. */
+ size_t nframe; /* Length of the ciphertext (EM). */
+ size_t hlen; /* Length of the hash digest. */
+ size_t db_len; /* Length of DB and masked_db. */
+ size_t nkey = (nbits+7)/8; /* Length of the key in bytes. */
+ int failed = 0; /* Error indicator. */
+ size_t n;
+
+ *r_result = NULL;
+
+ /* This code is implemented as described by rfc-3447 7.1.2. */
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+
+ /* Hash the label right away. */
+ lhash = gcry_malloc (hlen);
+ if (!lhash)
+ return gpg_err_code_from_syserror ();
+ gcry_md_hash_buffer (algo, lhash, label, labellen);
+
+ /* Turn the MPI into an octet string. If the octet string is
+ shorter than the key we pad it to the left with zeroes. This may
+ happen due to the leading zero in OAEP frames and due to the
+ following random octets (seed^mask) which may have leading zero
+ bytes. This all is needed to cope with our leading zeroes
+ suppressing MPI implementation. The code implictly implements
+ Step 1b (bail out if NFRAME != N). */
+ rc = octet_string_from_mpi (&frame, NULL, value, nkey);
+ if (rc)
+ {
+ gcry_free (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+ nframe = nkey;
+
+ /* Step 1c: Check that the key is long enough. */
+ if ( nframe < 2 * hlen + 2 )
+ {
+ gcry_free (frame);
+ gcry_free (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 2 has already been done by the caller and the
+ gcry_mpi_aprint above. */
+
+ /* Allocate space for SEED and DB. */
+ seed = gcry_malloc_secure (nframe - 1);
+ if (!seed)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ gcry_free (lhash);
+ return rc;
+ }
+ db = seed + hlen;
+
+ /* To avoid choosen ciphertext attacks from now on we make sure to
+ run all code even in the error case; this avoids possible timing
+ attacks as described by Manger. */
+
+ /* Step 3a: Hash the label. */
+ /* This has already been done. */
+
+ /* Step 3b: Separate the encoded message. */
+ masked_seed = frame + 1;
+ masked_db = frame + 1 + hlen;
+ db_len = nframe - 1 - hlen;
+
+ /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen). */
+ if (mgf1 (seed, hlen, masked_db, db_len, algo))
+ failed = 1;
+ for (n = 0; n < hlen; n++)
+ seed[n] ^= masked_seed[n];
+
+ /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len). */
+ if (mgf1 (db, db_len, seed, hlen, algo))
+ failed = 1;
+ for (n = 0; n < db_len; n++)
+ db[n] ^= masked_db[n];
+
+ /* Step 3g: Check lhash, an possible empty padding string terminated
+ by 0x01 and the first byte of EM being 0. */
+ if (memcmp (lhash, db, hlen))
+ failed = 1;
+ for (n = hlen; n < db_len; n++)
+ if (db[n] == 0x01)
+ break;
+ if (n == db_len)
+ failed = 1;
+ if (frame[0])
+ failed = 1;
+
+ gcry_free (lhash);
+ gcry_free (frame);
+ if (failed)
+ {
+ gcry_free (seed);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 4: Output M. */
+ /* To avoid an extra allocation we reuse the seed buffer. The only
+ caller of this function will anyway free the result soon. */
+ n++;
+ memmove (seed, db + n, db_len - n);
+ *r_result = seed;
+ *r_resultlen = db_len - n;
+ seed = NULL;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from OAEP encoded data:",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) PSS encoding. Encode {VALUE,VALUELEN} for
+ an NBITS key. Note that VALUE is already the mHash from the
+ picture below. ALGO is a valid hash algorithm and SALTLEN is the
+ length of salt to be used. On success the result is stored as a
+ new MPI at R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the salt instead of using a random string for the salt. This
+ feature is only useful for regression tests.
+
+ Here is figure 2 from the RFC (errata 595 applied) depicting the
+ process:
+
+ +-----------+
+ | M |
+ +-----------+
+ |
+ V
+ Hash
+ |
+ V
+ +--------+----------+----------+
+ M' = |Padding1| mHash | salt |
+ +--------+----------+----------+
+ |
+ +--------+----------+ V
+ DB = |Padding2| salt | Hash
+ +--------+----------+ |
+ | |
+ V | +----+
+ xor <--- MGF <---| |0xbc|
+ | | +----+
+ | | |
+ V V V
+ +-------------------+----------+----+
+ EM = | maskedDB | H |0xbc|
+ +-------------------+----------+----+
+
+ */
+static gcry_err_code_t
+pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen, int saltlen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *salt; /* Points into BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.1. */
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers. */
+ buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
+ buf = gcry_malloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ mhash = buf + 8;
+ salt = mhash + hlen;
+ dbmask= salt + saltlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we do only a consistency check and copy to MHASH. */
+ if (valuelen != hlen)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+ memcpy (mhash, value, hlen);
+
+ /* Step 3: Check length constraints. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT;
+ goto leave;
+ }
+
+ /* Allocate space for EM. */
+ em = gcry_malloc (emlen);
+ if (!em)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ h = em + emlen - 1 - hlen;
+
+ /* Step 4: Create a salt. */
+ if (saltlen)
+ {
+ if (random_override)
+ {
+ if (random_override_len != saltlen)
+ {
+ rc = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+ memcpy (salt, random_override, saltlen);
+ }
+ else
+ gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+ }
+
+ /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */
+ memset (buf, 0, 8); /* Padding. */
+ gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
+
+ /* Step 7 and 8: DB = PS || 0x01 || salt. */
+ /* Note that we use EM to store DB and later Xor in-place. */
+ p = em + emlen - 1 - hlen - saltlen - 1;
+ memset (em, 0, p - em);
+ *p++ = 0x01;
+ memcpy (p, salt, saltlen);
+
+ /* Step 9: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 10: maskedDB = DB ^ dbMask */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 11: Set the leftmost bits to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 12: EM = maskedDB || H || 0xbc. */
+ em[emlen-1] = 0xbc;
+
+ /* Convert EM into an MPI. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PSS encoded data", *r_result);
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ gcry_free (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ gcry_free (buf);
+ }
+ return rc;
+}
+
+
+/* Verify a signature assuming PSS padding. VALUE is the hash of the
+ message (mHash) encoded as an MPI; its length must match the digest
+ length of ALGO. ENCODED is the output of the RSA public key
+ function (EM). NBITS is the size of the public key. ALGO is the
+ hash algorithm and SALTLEN is the length of the used salt. The
+ function returns 0 on success or on error code. */
+static gcry_err_code_t
+pss_verify (gcry_mpi_t value, gcry_mpi_t encoded, unsigned int nbits, int algo,
+ size_t saltlen)
+{
+ gcry_err_code_t rc = 0;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *salt; /* Points into EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.2. */
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers.
+ This buffer is used for two purposes:
+ +------------------------------+-------+
+ 1. | dbmask | mHash |
+ +------------------------------+-------+
+ emlen - hlen - 1 hlen
+
+ +----------+-------+---------+-+-------+
+ 2. | padding1 | mHash | salt | | mHash |
+ +----------+-------+---------+-+-------+
+ 8 hlen saltlen hlen
+ */
+ buflen = 8 + hlen + saltlen;
+ if (buflen < emlen - hlen - 1)
+ buflen = emlen - hlen - 1;
+ buflen += hlen;
+ buf = gcry_malloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ dbmask = buf;
+ mhash = buf + buflen - hlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we only need to convert VALUE into MHASH. */
+ rc = octet_string_from_mpi (NULL, mhash, value, hlen);
+ if (rc)
+ goto leave;
+
+ /* Convert the signature into an octet string. */
+ rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
+ if (rc)
+ goto leave;
+
+ /* Step 3: Check length of EM. Because we internally use MPI
+ functions we can't do this properly; EMLEN is always the length
+ of the key because octet_string_from_mpi needs to left pad the
+ result with zero to cope with the fact that our MPIs suppress all
+ leading zeroes. Thus what we test here are merely the digest and
+ salt lengths to the key. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen. */
+ goto leave;
+ }
+
+ /* Step 4: Check last octet. */
+ if (em[emlen - 1] != 0xbc)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 5: Split EM. */
+ h = em + emlen - 1 - hlen;
+
+ /* Step 6: Check the leftmost bits. */
+ if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 7: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 8: maskedDB = DB ^ dbMask. */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 9: Set leftmost bits in DB to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 10: Check the padding of DB. */
+ for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
+ ;
+ if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 11: Extract salt from DB. */
+ salt = em + n;
+
+ /* Step 12: M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
+ memset (buf, 0, 8);
+ memcpy (buf+8, mhash, hlen);
+ memcpy (buf+8+hlen, salt, saltlen);
+
+ /* Step 13: H' = Hash(M'). */
+ gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
+
+ /* Step 14: Check H == H'. */
+ rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ gcry_free (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ gcry_free (buf);
+ }
+ return rc;
+}
+
+
+/* Callback for the pubkey algorithm code to verify PSS signatures.
+ OPAQUE is the data provided by the actual caller. The meaning of
+ TMP depends on the actual algorithm (but there is only RSA); now
+ for RSA it is the output of running the public key function on the
+ input. */
+static int
+pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
+{
+ struct pk_encoding_ctx *ctx = opaque;
+ gcry_mpi_t hash = ctx->verify_arg;
+
+ return pss_verify (hash, tmp, ctx->nbits - 1, ctx->hash_algo, ctx->saltlen);
+}
+
+
+/* Internal function. */
+static gcry_err_code_t
+sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
+ gcry_mpi_t *elements, const char *algo_name)
+{
+ gcry_err_code_t err = 0;
+ int i, idx;
+ const char *name;
+ gcry_sexp_t list;
+
+ for (name = element_names, idx = 0; *name && !err; name++, idx++)
+ {
+ list = gcry_sexp_find_token (key_sexp, name, 1);
+ if (!list)
+ elements[idx] = NULL;
+ else
+ {
+ elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (list);
+ if (!elements[idx])
+ err = GPG_ERR_INV_OBJ;
+ }
+ }
+
+ if (!err)
+ {
+ /* Check that all elements are available. */
+ for (name = element_names, idx = 0; *name; name++, idx++)
+ if (!elements[idx])
+ break;
+ if (*name)
+ {
+ err = GPG_ERR_NO_OBJ;
+ /* Some are missing. Before bailing out we test for
+ optional parameters. */
+ if (algo_name && !strcmp (algo_name, "RSA")
+ && !strcmp (element_names, "nedpqu") )
+ {
+ /* This is RSA. Test whether we got N, E and D and that
+ the optional P, Q and U are all missing. */
+ if (elements[0] && elements[1] && elements[2]
+ && !elements[3] && !elements[4] && !elements[5])
+ err = 0;
+ }
+ }
+ }
+
+
+ if (err)
+ {
+ for (i = 0; i < idx; i++)
+ if (elements[i])
+ gcry_free (elements[i]);
+ }
+ return err;
+}
+
+
+/* Internal function used for ecc. Note, that this function makes use
+ of its intimate knowledge about the ECC parameters from ecc.c. */
+static gcry_err_code_t
+sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
+ gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
+
+{
+ gcry_err_code_t err = 0;
+ int idx;
+ const char *name;
+ gcry_sexp_t list;
+
+ /* Clear the array for easier error cleanup. */
+ for (name = element_names, idx = 0; *name; name++, idx++)
+ elements[idx] = NULL;
+ gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
+ (params only) or 6 (full public key). */
+ if (idx == 5)
+ elements[5] = NULL; /* Extra clear for the params only case. */
+
+
+ /* Init the array with the available curve parameters. */
+ for (name = element_names, idx = 0; *name && !err; name++, idx++)
+ {
+ list = gcry_sexp_find_token (key_sexp, name, 1);
+ if (!list)
+ elements[idx] = NULL;
+ else
+ {
+ elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (list);
+ if (!elements[idx])
+ {
+ err = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ }
+ }
+
+ /* Check whether a curve parameter has been given and then fill any
+ missing elements. */
+ list = gcry_sexp_find_token (key_sexp, "curve", 5);
+ if (list)
+ {
+ if (extraspec->get_param)
+ {
+ char *curve;
+ gcry_mpi_t params[6];
+
+ for (idx = 0; idx < DIM(params); idx++)
+ params[idx] = NULL;
+
+ curve = _gcry_sexp_nth_string (list, 1);
+ gcry_sexp_release (list);
+ if (!curve)
+ {
+ /* No curve name given (or out of core). */
+ err = GPG_ERR_INV_OBJ;
+ goto leave;
+ }
+ err = extraspec->get_param (curve, params);
+ gcry_free (curve);
+ if (err)
+ goto leave;
+
+ for (idx = 0; idx < DIM(params); idx++)
+ {
+ if (!elements[idx])
+ elements[idx] = params[idx];
+ else
+ mpi_free (params[idx]);
+ }
+ }
+ else
+ {
+ gcry_sexp_release (list);
+ err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
+ goto leave;
+ }
+ }
+
+ /* Check that all parameters are known. */
+ for (name = element_names, idx = 0; *name; name++, idx++)
+ if (!elements[idx])
+ {
+ err = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+
+ leave:
+ if (err)
+ {
+ for (name = element_names, idx = 0; *name; name++, idx++)
+ if (elements[idx])
+ gcry_free (elements[idx]);
+ }
+ return err;
+}
+
+
+
+/****************
+ * Convert a S-Exp with either a private or a public key to our
+ * internal format. Currently we do only support the following
+ * algorithms:
+ * dsa
+ * rsa
+ * openpgp-dsa
+ * openpgp-rsa
+ * openpgp-elg
+ * openpgp-elg-sig
+ * ecdsa
+ * ecdh
+ * Provide a SE with the first element be either "private-key" or
+ * or "public-key". It is followed by a list with its first element
+ * be one of the above algorithm identifiers and the remaning
+ * elements are pairs with parameter-id and value.
+ * NOTE: we look through the list to find a list beginning with
+ * "private-key" or "public-key" - the first one found is used.
+ *
+ * If OVERRIDE_ELEMS is not NULL those elems override the parameter
+ * specification taken from the module. This ise used by
+ * gcry_pk_get_curve.
+ *
+ * Returns: A pointer to an allocated array of MPIs if the return value is
+ * zero; the caller has to release this array.
+ *
+ * Example of a DSA public key:
+ * (private-key
+ * (dsa
+ * (p <mpi>)
+ * (g <mpi>)
+ * (y <mpi>)
+ * (x <mpi>)
+ * )
+ * )
+ * The <mpi> are expected to be in GCRYMPI_FMT_USG
+ */
+static gcry_err_code_t
+sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
+ gcry_mpi_t **retarray, gcry_module_t *retalgo)
+{
+ gcry_err_code_t err = 0;
+ gcry_sexp_t list, l2;
+ char *name;
+ const char *elems;
+ gcry_mpi_t *array;
+ gcry_module_t module;
+ gcry_pk_spec_t *pubkey;
+ pk_extra_spec_t *extraspec;
+ int is_ecc;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token (sexp,
+ want_private? "private-key":"public-key", 0);
+ if (!list)
+ return GPG_ERR_INV_OBJ; /* Does not contain a key object. */
+
+ l2 = gcry_sexp_cadr( list );
+ gcry_sexp_release ( list );
+ list = l2;
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ {
+ gcry_sexp_release ( list );
+ return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ /* Fixme: We should make sure that an ECC key is always named "ecc"
+ and not "ecdsa". "ecdsa" should be used for the signature
+ itself. We need a function to test whether an algorithm given
+ with a key is compatible with an application of the key (signing,
+ encryption). For RSA this is easy, but ECC is the first
+ algorithm which has many flavours. */
+ is_ecc = ( !strcmp (name, "ecdsa")
+ || !strcmp (name, "ecdh")
+ || !strcmp (name, "ecc") );
+ gcry_free (name);
+
+ if (!module)
+ {
+ gcry_sexp_release (list);
+ return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ }
+ else
+ {
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ extraspec = module->extraspec;
+ }
+
+ if (override_elems)
+ elems = override_elems;
+ else if (want_private)
+ elems = pubkey->elements_skey;
+ else
+ elems = pubkey->elements_pkey;
+ array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
+ if (!array)
+ err = gpg_err_code_from_syserror ();
+ if (!err)
+ {
+ if (is_ecc)
+ err = sexp_elements_extract_ecc (list, elems, array, extraspec);
+ else
+ err = sexp_elements_extract (list, elems, array, pubkey->name);
+ }
+
+ gcry_sexp_release (list);
+
+ if (err)
+ {
+ gcry_free (array);
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ else
+ {
+ *retarray = array;
+ *retalgo = module;
+ }
+
+ return err;
+}
+
+
+static gcry_err_code_t
+sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
+ gcry_module_t *retalgo)
+{
+ gcry_err_code_t err = 0;
+ gcry_sexp_t list, l2;
+ char *name;
+ const char *elems;
+ gcry_mpi_t *array;
+ gcry_module_t module;
+ gcry_pk_spec_t *pubkey;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
+ if (!list)
+ return GPG_ERR_INV_OBJ; /* Does not contain a signature value object. */
+
+ l2 = gcry_sexp_nth (list, 1);
+ if (!l2)
+ {
+ gcry_sexp_release (list);
+ return GPG_ERR_NO_OBJ; /* No cadr for the sig object. */
+ }
+ name = _gcry_sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ gcry_sexp_release (list);
+ gcry_sexp_release (l2);
+ return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ }
+ else if (!strcmp (name, "flags"))
+ {
+ /* Skip flags, since they are not used but here just for the
+ sake of consistent S-expressions. */
+ gcry_free (name);
+ gcry_sexp_release (l2);
+ l2 = gcry_sexp_nth (list, 2);
+ if (!l2)
+ {
+ gcry_sexp_release (list);
+ return GPG_ERR_INV_OBJ;
+ }
+ name = _gcry_sexp_nth_string (l2, 0);
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ gcry_free (name);
+ name = NULL;
+
+ if (!module)
+ {
+ gcry_sexp_release (l2);
+ gcry_sexp_release (list);
+ return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ }
+ else
+ pubkey = (gcry_pk_spec_t *) module->spec;
+
+ elems = pubkey->elements_sig;
+ array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
+ if (!array)
+ err = gpg_err_code_from_syserror ();
+
+ if (!err)
+ err = sexp_elements_extract (list, elems, array, NULL);
+
+ gcry_sexp_release (l2);
+ gcry_sexp_release (list);
+
+ if (err)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ gcry_free (array);
+ }
+ else
+ {
+ *retarray = array;
+ *retalgo = module;
+ }
+
+ return err;
+}
+
+static inline int
+get_hash_algo (const char *s, size_t n)
+{
+ static const struct { const char *name; int algo; } hashnames[] = {
+ { "sha1", GCRY_MD_SHA1 },
+ { "md5", GCRY_MD_MD5 },
+ { "sha256", GCRY_MD_SHA256 },
+ { "ripemd160", GCRY_MD_RMD160 },
+ { "rmd160", GCRY_MD_RMD160 },
+ { "sha384", GCRY_MD_SHA384 },
+ { "sha512", GCRY_MD_SHA512 },
+ { "sha224", GCRY_MD_SHA224 },
+ { "md2", GCRY_MD_MD2 },
+ { "md4", GCRY_MD_MD4 },
+ { "tiger", GCRY_MD_TIGER },
+ { "haval", GCRY_MD_HAVAL },
+ { NULL, 0 }
+ };
+ int algo;
+ int i;
+
+ for (i=0; hashnames[i].name; i++)
+ {
+ if ( strlen (hashnames[i].name) == n
+ && !memcmp (hashnames[i].name, s, n))
+ break;
+ }
+ if (hashnames[i].name)
+ algo = hashnames[i].algo;
+ else
+ {
+ /* In case of not listed or dynamically allocated hash
+ algorithm we fall back to this somewhat slower
+ method. Further, it also allows to use OIDs as
+ algorithm names. */
+ char *tmpname;
+
+ tmpname = gcry_malloc (n+1);
+ if (!tmpname)
+ algo = 0; /* Out of core - silently give up. */
+ else
+ {
+ memcpy (tmpname, s, n);
+ tmpname[n] = 0;
+ algo = gcry_md_map_name (tmpname);
+ gcry_free (tmpname);
+ }
+ }
+ return algo;
+}
+
+
+/****************
+ * Take sexp and return an array of MPI as used for our internal decrypt
+ * function.
+ * s_data = (enc-val
+ * [(flags [raw, pkcs1, oaep, no-blinding])]
+ * [(hash-algo <algo>)]
+ * [(label <label>)]
+ * (<algo>
+ * (<param_name1> <mpi>)
+ * ...
+ * (<param_namen> <mpi>)
+ * ))
+ * HASH-ALGO and LABEL are specific to OAEP.
+ * RET_MODERN is set to true when at least an empty flags list has been found.
+ * CTX is used to return encoding information; it may be NULL in which
+ * case raw encoding is used.
+ */
+static gcry_err_code_t
+sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
+ int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
+{
+ gcry_err_code_t err = 0;
+ gcry_sexp_t list = NULL, l2 = NULL;
+ gcry_pk_spec_t *pubkey = NULL;
+ gcry_module_t module = NULL;
+ char *name = NULL;
+ size_t n;
+ int parsed_flags = 0;
+ const char *elems;
+ gcry_mpi_t *array = NULL;
+
+ *ret_modern = 0;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token (sexp, "enc-val" , 0);
+ if (!list)
+ {
+ err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object. */
+ goto leave;
+ }
+
+ l2 = gcry_sexp_nth (list, 1);
+ if (!l2)
+ {
+ err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
+ goto leave;
+ }
+
+ /* Extract identifier of sublist. */
+ name = _gcry_sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+
+ if (!strcmp (name, "flags"))
+ {
+ /* There is a flags element - process it. */
+ const char *s;
+ int i;
+
+ *ret_modern = 1;
+ for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
+ {
+ s = gcry_sexp_nth_data (l2, i, &n);
+ if (! s)
+ ; /* Not a data element - ignore. */
+ else if (n == 3 && !memcmp (s, "raw", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW;
+ else if (n == 5 && !memcmp (s, "pkcs1", 5)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PKCS1;
+ else if (n == 4 && !memcmp (s, "oaep", 4)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_OAEP;
+ else if (n == 3 && !memcmp (s, "pss", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ err = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+ else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+ parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
+ else
+ {
+ err = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ }
+ gcry_sexp_release (l2);
+
+ /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
+ if (ctx->encoding == PUBKEY_ENC_OAEP)
+ {
+ /* Get HASH-ALGO. */
+ l2 = gcry_sexp_find_token (list, "hash-algo", 0);
+ if (l2)
+ {
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if (!s)
+ err = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+ gcry_sexp_release (l2);
+ if (err)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ l2 = gcry_sexp_find_token (list, "label", 0);
+ if (l2)
+ {
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if (!s)
+ err = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = gcry_malloc (n);
+ if (!ctx->label)
+ err = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ gcry_sexp_release (l2);
+ if (err)
+ goto leave;
+ }
+ }
+
+ /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
+ for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
+ {
+ s = gcry_sexp_nth_data (l2, 0, &n);
+ if (!(n == 9 && !memcmp (s, "hash-algo", 9))
+ && !(n == 5 && !memcmp (s, "label", 5))
+ && !(n == 15 && !memcmp (s, "random-override", 15)))
+ break;
+ gcry_sexp_release (l2);
+ }
+
+ if (!l2)
+ {
+ err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
+ goto leave;
+ }
+
+ /* Extract sublist identifier. */
+ gcry_free (name);
+ name = _gcry_sexp_nth_string (l2, 0);
+ if (!name)
+ {
+ err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+ goto leave;
+ }
+
+ gcry_sexp_release (list);
+ list = l2;
+ l2 = NULL;
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (!module)
+ {
+ err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ goto leave;
+ }
+ pubkey = (gcry_pk_spec_t *) module->spec;
+
+ elems = pubkey->elements_enc;
+ array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
+ if (!array)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ err = sexp_elements_extract (list, elems, array, NULL);
+
+ leave:
+ gcry_sexp_release (list);
+ gcry_sexp_release (l2);
+ gcry_free (name);
+
+ if (err)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ gcry_free (array);
+ gcry_free (ctx->label);
+ ctx->label = NULL;
+ }
+ else
+ {
+ *retarray = array;
+ *retalgo = module;
+ *flags = parsed_flags;
+ }
+
+ return err;
+}
+
+/* Take the hash value and convert into an MPI, suitable for
+ passing to the low level functions. We currently support the
+ old style way of passing just a MPI and the modern interface which
+ allows to pass flags so that we can choose between raw and pkcs1
+ padding - may be more padding options later.
+
+ (<mpi>)
+ or
+ (data
+ [(flags [raw, pkcs1, oaep, pss, no-blinding])]
+ [(hash <algo> <value>)]
+ [(value <text>)]
+ [(hash-algo <algo>)]
+ [(label <label>)]
+ [(salt-length <length>)]
+ [(random-override <data>)]
+ )
+
+ Either the VALUE or the HASH element must be present for use
+ with signatures. VALUE is used for encryption.
+
+ HASH-ALGO and LABEL are specific to OAEP.
+
+ SALT-LENGTH is for PSS.
+
+ RANDOM-OVERRIDE is used to replace random nonces for regression
+ testing. */
+static gcry_err_code_t
+sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
+ struct pk_encoding_ctx *ctx)
+{
+ gcry_err_code_t rc = 0;
+ gcry_sexp_t ldata, lhash, lvalue;
+ int i;
+ size_t n;
+ const char *s;
+ int unknown_flag=0;
+ int parsed_flags = 0;
+
+ *ret_mpi = NULL;
+ ldata = gcry_sexp_find_token (input, "data", 0);
+ if (!ldata)
+ { /* assume old style */
+ *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
+ return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
+ }
+
+ /* see whether there is a flags object */
+ {
+ gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
+ if (lflags)
+ { /* parse the flags list. */
+ for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
+ {
+ s = gcry_sexp_nth_data (lflags, i, &n);
+ if (!s)
+ ; /* not a data element*/
+ else if ( n == 3 && !memcmp (s, "raw", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW;
+ else if ( n == 5 && !memcmp (s, "pkcs1", 5)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PKCS1;
+ else if ( n == 4 && !memcmp (s, "oaep", 4)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_OAEP;
+ else if ( n == 3 && !memcmp (s, "pss", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PSS;
+ else if (n == 11 && ! memcmp (s, "no-blinding", 11))
+ parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
+ else
+ unknown_flag = 1;
+ }
+ gcry_sexp_release (lflags);
+ }
+ }
+
+ if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
+
+ /* Get HASH or MPI */
+ lhash = gcry_sexp_find_token (ldata, "hash", 0);
+ lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
+
+ if (!(!lhash ^ !lvalue))
+ rc = GPG_ERR_INV_OBJ; /* none or both given */
+ else if (unknown_flag)
+ rc = GPG_ERR_INV_FLAG;
+ else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
+ {
+ *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
+ if (!*ret_mpi)
+ rc = GPG_ERR_INV_OBJ;
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
+ const void * value;
+ size_t valuelen;
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ rc = pkcs1_encode_for_encryption (ret_mpi, ctx->nbits,
+ value, valuelen,
+ random_override,
+ random_override_len);
+ gcry_free (random_override);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
+ && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+ {
+ if (gcry_sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ const void * value;
+ size_t valuelen;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ rc = pkcs1_encode_for_signature (ret_mpi, ctx->nbits,
+ value, valuelen,
+ ctx->hash_algo);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
+ const void * value;
+ size_t valuelen;
+
+ if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ /* Get HASH-ALGO. */
+ list = gcry_sexp_find_token (ldata, "hash-algo", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ list = gcry_sexp_find_token (ldata, "label", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = gcry_malloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
+ value, valuelen,
+ ctx->label, ctx->labellen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_SIGN)
+ {
+ if (gcry_sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ const void * value;
+ size_t valuelen;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ gcry_sexp_t list;
+
+ /* Get SALT-LENGTH. */
+ list = gcry_sexp_find_token (ldata, "salt-length", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
+ gcry_sexp_release (list);
+ }
+
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Encode the data. (NBITS-1 is due to 8.1.1, step 1.) */
+ rc = pss_encode (ret_mpi, ctx->nbits - 1, ctx->hash_algo,
+ value, valuelen, ctx->saltlen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
+ }
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_VERIFY)
+ {
+ if (gcry_sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else
+ {
+ *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
+ if (!*ret_mpi)
+ rc = GPG_ERR_INV_OBJ;
+ ctx->verify_cmp = pss_verify_cmp;
+ ctx->verify_arg = *ret_mpi;
+ }
+ }
+ }
+ else
+ rc = GPG_ERR_CONFLICT;
+
+ leave:
+ gcry_sexp_release (ldata);
+ gcry_sexp_release (lhash);
+ gcry_sexp_release (lvalue);
+
+ if (!rc)
+ ctx->flags = parsed_flags;
+ else
+ {
+ gcry_free (ctx->label);
+ ctx->label = NULL;
+ }
+
+ return rc;
+}
+
+static void
+init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
+ unsigned int nbits)
+{
+ ctx->op = op;
+ ctx->nbits = nbits;
+ ctx->encoding = PUBKEY_ENC_UNKNOWN;
+ ctx->flags = 0;
+ ctx->hash_algo = GCRY_MD_SHA1;
+ ctx->label = NULL;
+ ctx->labellen = 0;
+ ctx->saltlen = 20;
+ ctx->verify_cmp = NULL;
+ ctx->verify_arg = NULL;
+}
+
+
+/*
+ Do a PK encrypt operation
+
+ Caller has to provide a public key as the SEXP pkey and data as a
+ SEXP with just one MPI in it. Alternatively S_DATA might be a
+ complex S-Expression, similar to the one used for signature
+ verification. This provides a flag which allows to handle PKCS#1
+ block type 2 padding. The function returns a sexp which may be
+ passed to to pk_decrypt.
+
+ Returns: 0 or an errorcode.
+
+ s_data = See comment for sexp_data_to_mpi
+ s_pkey = <key-as-defined-in-sexp_to_key>
+ r_ciph = (enc-val
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>)
+ ))
+
+*/
+gcry_error_t
+gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
+{
+ gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
+ const char *algo_name, *algo_elems;
+ struct pk_encoding_ctx ctx;
+ gcry_err_code_t rc;
+ gcry_pk_spec_t *pubkey = NULL;
+ gcry_module_t module = NULL;
+
+ *r_ciph = NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ /* Get the key. */
+ rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
+ if (rc)
+ goto leave;
+
+ gcry_assert (module);
+ pubkey = (gcry_pk_spec_t *) module->spec;
+
+ /* If aliases for the algorithm name exists, take the first one
+ instead of the regular name to adhere to SPKI conventions. We
+ assume that the first alias name is the lowercase version of the
+ regular one. This change is required for compatibility with
+ 1.1.12 generated S-expressions. */
+ algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+ if (!algo_name || !*algo_name)
+ algo_name = pubkey->name;
+
+ algo_elems = pubkey->elements_enc;
+
+ /* Get the stuff we want to encrypt. */
+ init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
+ rc = sexp_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+
+ /* Now we can encrypt DATA to CIPH. */
+ ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
+ if (!ciph)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
+ mpi_free (data);
+ data = NULL;
+ if (rc)
+ goto leave;
+
+ /* We did it. Now build the return list */
+ if (ctx.encoding == PUBKEY_ENC_OAEP
+ || ctx.encoding == PUBKEY_ENC_PKCS1)
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. We know that this
+ encoding does only make sense with RSA thus we don't need to
+ build the S-expression on the fly. */
+ unsigned char *em;
+ size_t emlen = (ctx.nbits+7)/8;
+
+ rc = octet_string_from_mpi (&em, NULL, ciph[0], emlen);
+ if (rc)
+ goto leave;
+ rc = gcry_err_code (gcry_sexp_build (r_ciph, NULL,
+ "(enc-val(%s(a%b)))",
+ algo_name, (int)emlen, em));
+ gcry_free (em);
+ if (rc)
+ goto leave;
+ }
+ else
+ {
+ char *string, *p;
+ int i;
+ size_t nelem = strlen (algo_elems);
+ size_t needed = 19 + strlen (algo_name) + (nelem * 5);
+ void **arg_list;
+
+ /* Build the string. */
+ string = p = gcry_malloc (needed);
+ if (!string)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ p = stpcpy ( p, "(enc-val(" );
+ p = stpcpy ( p, algo_name );
+ for (i=0; algo_elems[i]; i++ )
+ {
+ *p++ = '(';
+ *p++ = algo_elems[i];
+ p = stpcpy ( p, "%m)" );
+ }
+ strcpy ( p, "))" );
+
+ /* And now the ugly part: We don't have a function to pass an
+ * array to a format string, so we have to do it this way :-(. */
+ /* FIXME: There is now such a format specifier, so we can
+ change the code to be more clear. */
+ arg_list = malloc (nelem * sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ for (i = 0; i < nelem; i++)
+ arg_list[i] = ciph + i;
+
+ rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
+ free (arg_list);
+ if (rc)
+ BUG ();
+ gcry_free (string);
+ }
+
+ leave:
+ if (pkey)
+ {
+ release_mpi_array (pkey);
+ gcry_free (pkey);
+ }
+
+ if (ciph)
+ {
+ release_mpi_array (ciph);
+ gcry_free (ciph);
+ }
+
+ if (module)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+
+ gcry_free (ctx.label);
+
+ return gcry_error (rc);
+}
+
+/*
+ Do a PK decrypt operation
+
+ Caller has to provide a secret key as the SEXP skey and data in a
+ format as created by gcry_pk_encrypt. For historic reasons the
+ function returns simply an MPI as an S-expression part; this is
+ deprecated and the new method should be used which returns a real
+ S-expressionl this is selected by adding at least an empty flags
+ list to S_DATA.
+
+ Returns: 0 or an errorcode.
+
+ s_data = (enc-val
+ [(flags [raw, pkcs1, oaep])]
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>)
+ ))
+ s_skey = <key-as-defined-in-sexp_to_key>
+ r_plain= Either an incomplete S-expression without the parentheses
+ or if the flags list is used (even if empty) a real S-expression:
+ (value PLAIN). In raw mode (or no flags given) the returned value
+ is to be interpreted as a signed MPI, thus it may have an extra
+ leading zero octet even if not included in the original data.
+ With pkcs1 or oaep decoding enabled the returned value is a
+ verbatim octet string.
+ */
+gcry_error_t
+gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
+{
+ gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
+ unsigned char *unpad = NULL;
+ size_t unpadlen = 0;
+ int modern, flags;
+ struct pk_encoding_ctx ctx;
+ gcry_err_code_t rc;
+ gcry_module_t module_enc = NULL, module_key = NULL;
+
+ *r_plain = NULL;
+ ctx.label = NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
+ if (rc)
+ goto leave;
+
+ init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
+ rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
+ if (rc)
+ goto leave;
+
+ if (module_key->mod_id != module_enc->mod_id)
+ {
+ rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
+ goto leave;
+ }
+
+ rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
+ if (rc)
+ goto leave;
+
+ /* Do un-padding if necessary. */
+ switch (ctx.encoding)
+ {
+ case PUBKEY_ENC_PKCS1:
+ rc = pkcs1_decode_for_encryption (&unpad, &unpadlen,
+ gcry_pk_get_nbits (s_skey), plain);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ case PUBKEY_ENC_OAEP:
+ rc = oaep_decode (&unpad, &unpadlen,
+ gcry_pk_get_nbits (s_skey), ctx.hash_algo,
+ plain, ctx.label, ctx.labellen);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ default:
+ /* Raw format. For backward compatibility we need to assume a
+ signed mpi by using the sexp format string "%m". */
+ rc = gcry_err_code (gcry_sexp_build
+ (r_plain, NULL, modern? "(value %m)" : "%m", plain));
+ break;
+ }
+
+ leave:
+ gcry_free (unpad);
+
+ if (skey)
+ {
+ release_mpi_array (skey);
+ gcry_free (skey);
+ }
+
+ mpi_free (plain);
+
+ if (data)
+ {
+ release_mpi_array (data);
+ gcry_free (data);
+ }
+
+ if (module_key || module_enc)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ if (module_key)
+ _gcry_module_release (module_key);
+ if (module_enc)
+ _gcry_module_release (module_enc);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+
+ gcry_free (ctx.label);
+
+ return gcry_error (rc);
+}
+
+
+
+/*
+ Create a signature.
+
+ Caller has to provide a secret key as the SEXP skey and data
+ expressed as a SEXP list hash with only one element which should
+ instantly be available as a MPI. Alternatively the structure given
+ below may be used for S_HASH, it provides the abiliy to pass flags
+ to the operation; the flags defined by now are "pkcs1" which does
+ PKCS#1 block type 1 style padding and "pss" for PSS encoding.
+
+ Returns: 0 or an errorcode.
+ In case of 0 the function returns a new SEXP with the
+ signature value; the structure of this signature depends on the
+ other arguments but is always suitable to be passed to
+ gcry_pk_verify
+
+ s_hash = See comment for sexp_data_to_mpi
+
+ s_skey = <key-as-defined-in-sexp_to_key>
+ r_sig = (sig-val
+ (<algo>
+ (<param_name1> <mpi>)
+ ...
+ (<param_namen> <mpi>))
+ [(hash algo)])
+
+ Note that (hash algo) in R_SIG is not used.
+*/
+gcry_error_t
+gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
+{
+ gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
+ gcry_pk_spec_t *pubkey = NULL;
+ gcry_module_t module = NULL;
+ const char *algo_name, *algo_elems;
+ struct pk_encoding_ctx ctx;
+ int i;
+ gcry_err_code_t rc;
+
+ *r_sig = NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
+ if (rc)
+ goto leave;
+
+ gcry_assert (module);
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+ if (!algo_name || !*algo_name)
+ algo_name = pubkey->name;
+
+ algo_elems = pubkey->elements_sig;
+
+ /* Get the stuff we want to sign. Note that pk_get_nbits does also
+ work on a private key. */
+ init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, gcry_pk_get_nbits (s_skey));
+ rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
+ if (rc)
+ goto leave;
+
+ result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
+ if (!result)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ rc = pubkey_sign (module->mod_id, result, hash, skey);
+ if (rc)
+ goto leave;
+
+ if (ctx.encoding == PUBKEY_ENC_PSS
+ || ctx.encoding == PUBKEY_ENC_PKCS1)
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. We know that this
+ encoding does only make sense with RSA thus we don't need to
+ build the S-expression on the fly. */
+ unsigned char *em;
+ size_t emlen = (ctx.nbits+7)/8;
+
+ rc = octet_string_from_mpi (&em, NULL, result[0], emlen);
+ if (rc)
+ goto leave;
+ rc = gcry_err_code (gcry_sexp_build (r_sig, NULL,
+ "(sig-val(%s(s%b)))",
+ algo_name, (int)emlen, em));
+ gcry_free (em);
+ if (rc)
+ goto leave;
+ }
+ else
+ {
+ /* General purpose output encoding. Do it on the fly. */
+ char *string, *p;
+ size_t nelem, needed = strlen (algo_name) + 20;
+ void **arg_list;
+
+ nelem = strlen (algo_elems);
+
+ /* Count elements, so that we can allocate enough space. */
+ needed += 10 * nelem;
+
+ /* Build the string. */
+ string = p = gcry_malloc (needed);
+ if (!string)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ p = stpcpy (p, "(sig-val(");
+ p = stpcpy (p, algo_name);
+ for (i = 0; algo_elems[i]; i++)
+ {
+ *p++ = '(';
+ *p++ = algo_elems[i];
+ p = stpcpy (p, "%M)");
+ }
+ strcpy (p, "))");
+
+ arg_list = malloc (nelem * sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ for (i = 0; i < nelem; i++)
+ arg_list[i] = result + i;
+
+ rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
+ free (arg_list);
+ if (rc)
+ BUG ();
+ gcry_free (string);
+ }
+
+ leave:
+ if (skey)
+ {
+ release_mpi_array (skey);
+ gcry_free (skey);
+ }
+
+ if (hash)
+ mpi_free (hash);
+
+ if (result)
+ {
+ release_mpi_array (result);
+ gcry_free (result);
+ }
+
+ return gcry_error (rc);
+}
+
+
+/*
+ Verify a signature.
+
+ Caller has to supply the public key pkey, the signature sig and his
+ hashvalue data. Public key has to be a standard public key given
+ as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
+ must be an S-Exp like the one in sign too. */
+gcry_error_t
+gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
+{
+ gcry_module_t module_key = NULL, module_sig = NULL;
+ gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
+ struct pk_encoding_ctx ctx;
+ gcry_err_code_t rc;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
+ if (rc)
+ goto leave;
+
+ rc = sexp_to_sig (s_sig, &sig, &module_sig);
+ if (rc)
+ goto leave;
+
+ /* Fixme: Check that the algorithm of S_SIG is compatible to the one
+ of S_PKEY. */
+
+ if (module_key->mod_id != module_sig->mod_id)
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ /* Get the stuff we want to verify. */
+ init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
+ rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
+ if (rc)
+ goto leave;
+
+ rc = pubkey_verify (module_key->mod_id, hash, sig, pkey,
+ ctx.verify_cmp, &ctx);
+
+ leave:
+ if (pkey)
+ {
+ release_mpi_array (pkey);
+ gcry_free (pkey);
+ }
+ if (sig)
+ {
+ release_mpi_array (sig);
+ gcry_free (sig);
+ }
+ if (hash)
+ mpi_free (hash);
+
+ if (module_key || module_sig)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ if (module_key)
+ _gcry_module_release (module_key);
+ if (module_sig)
+ _gcry_module_release (module_sig);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+
+ return gcry_error (rc);
+}
+
+
+/*
+ Test a key.
+
+ This may be used either for a public or a secret key to see whether
+ the internal structure is okay.
+
+ Returns: 0 or an errorcode.
+
+ s_key = <key-as-defined-in-sexp_to_key> */
+gcry_error_t
+gcry_pk_testkey (gcry_sexp_t s_key)
+{
+ gcry_module_t module = NULL;
+ gcry_mpi_t *key = NULL;
+ gcry_err_code_t rc;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ /* Note we currently support only secret key checking. */
+ rc = sexp_to_key (s_key, 1, NULL, &key, &module);
+ if (! rc)
+ {
+ rc = pubkey_check_secret_key (module->mod_id, key);
+ release_mpi_array (key);
+ gcry_free (key);
+ }
+ return gcry_error (rc);
+}
+
+
+/*
+ Create a public key pair and return it in r_key.
+ How the key is created depends on s_parms:
+ (genkey
+ (algo
+ (parameter_name_1 ....)
+ ....
+ (parameter_name_n ....)
+ ))
+ The key is returned in a format depending on the
+ algorithm. Both, private and secret keys are returned
+ and optionally some additional informatin.
+ For elgamal we return this structure:
+ (key-data
+ (public-key
+ (elg
+ (p <mpi>)
+ (g <mpi>)
+ (y <mpi>)
+ )
+ )
+ (private-key
+ (elg
+ (p <mpi>)
+ (g <mpi>)
+ (y <mpi>)
+ (x <mpi>)
+ )
+ )
+ (misc-key-info
+ (pm1-factors n1 n2 ... nn)
+ ))
+ */
+gcry_error_t
+gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+ gcry_pk_spec_t *pubkey = NULL;
+ gcry_module_t module = NULL;
+ gcry_sexp_t list = NULL;
+ gcry_sexp_t l2 = NULL;
+ gcry_sexp_t l3 = NULL;
+ char *name = NULL;
+ size_t n;
+ gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+ int i, j;
+ const char *algo_name = NULL;
+ int algo;
+ const char *sec_elems = NULL, *pub_elems = NULL;
+ gcry_mpi_t skey[12];
+ gcry_mpi_t *factors = NULL;
+ gcry_sexp_t extrainfo = NULL;
+ unsigned int nbits = 0;
+ unsigned long use_e = 0;
+
+ skey[0] = NULL;
+ *r_key = NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ list = gcry_sexp_find_token (s_parms, "genkey", 0);
+ if (!list)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
+ goto leave;
+ }
+
+ l2 = gcry_sexp_cadr (list);
+ gcry_sexp_release (list);
+ list = l2;
+ l2 = NULL;
+ if (! list)
+ {
+ rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
+ goto leave;
+ }
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ {
+ rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
+ goto leave;
+ }
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ gcry_free (name);
+ name = NULL;
+ if (!module)
+ {
+ rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+ goto leave;
+ }
+
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ algo = module->mod_id;
+ algo_name = pubkey->aliases? *pubkey->aliases : NULL;
+ if (!algo_name || !*algo_name)
+ algo_name = pubkey->name;
+ pub_elems = pubkey->elements_pkey;
+ sec_elems = pubkey->elements_skey;
+ if (strlen (sec_elems) >= DIM(skey))
+ BUG ();
+
+ /* Handle the optional rsa-use-e element. Actually this belong into
+ the algorithm module but we have this parameter in the public
+ module API, so we need to parse it right here. */
+ l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
+ if (l2)
+ {
+ char buf[50];
+ const char *s;
+
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if ( !s || n >= DIM (buf) - 1 )
+ {
+ rc = GPG_ERR_INV_OBJ; /* No value or value too large. */
+ goto leave;
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ use_e = strtoul (buf, NULL, 0);
+ gcry_sexp_release (l2);
+ l2 = NULL;
+ }
+ else
+ use_e = 65537; /* Not given, use the value generated by old versions. */
+
+
+ /* Get the "nbits" parameter. */
+ l2 = gcry_sexp_find_token (list, "nbits", 0);
+ if (l2)
+ {
+ char buf[50];
+ const char *s;
+
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
+ {
+ rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr. */
+ goto leave;
+ }
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ nbits = (unsigned int)strtoul (buf, NULL, 0);
+ gcry_sexp_release (l2); l2 = NULL;
+ }
+ else
+ nbits = 0;
+
+ /* Pass control to the algorithm module. */
+ rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
+ &factors, &extrainfo);
+ gcry_sexp_release (list); list = NULL;
+ if (rc)
+ goto leave;
+
+ /* Key generation succeeded: Build an S-expression. */
+ {
+ char *string, *p;
+ size_t nelem=0, nelem_cp = 0, needed=0;
+ gcry_mpi_t mpis[30];
+ int percent_s_idx = -1;
+
+ /* Estimate size of format string. */
+ nelem = strlen (pub_elems) + strlen (sec_elems);
+ if (factors)
+ {
+ for (i = 0; factors[i]; i++)
+ nelem++;
+ }
+ nelem_cp = nelem;
+
+ needed += nelem * 10;
+ /* (+5 is for EXTRAINFO ("%S")). */
+ needed += 2 * strlen (algo_name) + 300 + 5;
+ if (nelem > DIM (mpis))
+ BUG ();
+
+ /* Build the string. */
+ nelem = 0;
+ string = p = gcry_malloc (needed);
+ if (!string)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ p = stpcpy (p, "(key-data");
+ p = stpcpy (p, "(public-key(");
+ p = stpcpy (p, algo_name);
+ for(i = 0; pub_elems[i]; i++)
+ {
+ *p++ = '(';
+ *p++ = pub_elems[i];
+ p = stpcpy (p, "%m)");
+ mpis[nelem++] = skey[i];
+ }
+ if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+ {
+ /* Very ugly hack to insert the used curve parameter into the
+ list of public key parameters. */
+ percent_s_idx = nelem;
+ p = stpcpy (p, "%S");
+ }
+ p = stpcpy (p, "))");
+ p = stpcpy (p, "(private-key(");
+ p = stpcpy (p, algo_name);
+ for (i = 0; sec_elems[i]; i++)
+ {
+ *p++ = '(';
+ *p++ = sec_elems[i];
+ p = stpcpy (p, "%m)");
+ mpis[nelem++] = skey[i];
+ }
+ p = stpcpy (p, "))");
+
+ /* Hack to make release_mpi_array() work. */
+ skey[i] = NULL;
+
+ if (extrainfo && percent_s_idx == -1)
+ {
+ /* If we have extrainfo we should not have any factors. */
+ p = stpcpy (p, "%S");
+ }
+ else if (factors && factors[0])
+ {
+ p = stpcpy (p, "(misc-key-info(pm1-factors");
+ for(i = 0; factors[i]; i++)
+ {
+ p = stpcpy (p, "%m");
+ mpis[nelem++] = factors[i];
+ }
+ p = stpcpy (p, "))");
+ }
+ strcpy (p, ")");
+ gcry_assert (p - string < needed);
+
+ while (nelem < DIM (mpis))
+ mpis[nelem++] = NULL;
+
+ {
+ int elem_n = strlen (pub_elems) + strlen (sec_elems);
+ void **arg_list;
+
+ /* Allocate one extra for EXTRAINFO ("%S"). */
+ arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ for (i = j = 0; i < elem_n; i++)
+ {
+ if (i == percent_s_idx)
+ arg_list[j++] = &extrainfo;
+ arg_list[j++] = mpis + i;
+ }
+ if (extrainfo && percent_s_idx == -1)
+ arg_list[j] = &extrainfo;
+ else if (factors && factors[0])
+ {
+ for (; i < nelem_cp; i++)
+ arg_list[j++] = factors + i - elem_n;
+ }
+ rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
+ gcry_free (arg_list);
+ if (rc)
+ BUG ();
+ gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
+ the array gets increased if
+ new parameters are added. */
+ }
+ gcry_free (string);
+ }
+
+ leave:
+ gcry_free (name);
+ gcry_sexp_release (extrainfo);
+ release_mpi_array (skey);
+ /* Don't free SKEY itself, it is an stack allocated array. */
+
+ if (factors)
+ {
+ release_mpi_array ( factors );
+ gcry_free (factors);
+ }
+
+ gcry_sexp_release (l3);
+ gcry_sexp_release (l2);
+ gcry_sexp_release (list);
+
+ if (module)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+
+ return gcry_error (rc);
+}
+
+
+/*
+ Get the number of nbits from the public key.
+
+ Hmmm: Should we have really this function or is it better to have a
+ more general function to retrieve different properties of the key? */
+unsigned int
+gcry_pk_get_nbits (gcry_sexp_t key)
+{
+ gcry_module_t module = NULL;
+ gcry_pk_spec_t *pubkey;
+ gcry_mpi_t *keyarr = NULL;
+ unsigned int nbits = 0;
+ gcry_err_code_t rc;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
+ if (rc == GPG_ERR_INV_OBJ)
+ rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
+ if (rc)
+ return 0; /* Error - 0 is a suitable indication for that. */
+
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ release_mpi_array (keyarr);
+ gcry_free (keyarr);
+
+ return nbits;
+}
+
+
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+ key parameters expressed in a way depending on the algorithm.
+
+ ARRAY must either be 20 bytes long or NULL; in the latter case a
+ newly allocated array of that size is returned, otherwise ARRAY or
+ NULL is returned to indicate an error which is most likely an
+ unknown algorithm. The function accepts public or secret keys. */
+unsigned char *
+gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+ gcry_sexp_t list = NULL, l2 = NULL;
+ gcry_pk_spec_t *pubkey = NULL;
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec;
+ const char *s;
+ char *name = NULL;
+ int idx;
+ const char *elems;
+ gcry_md_hd_t md = NULL;
+ int okay = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token (key, "public-key", 0);
+ if (! list)
+ list = gcry_sexp_find_token (key, "private-key", 0);
+ if (! list)
+ list = gcry_sexp_find_token (key, "protected-private-key", 0);
+ if (! list)
+ list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
+ if (! list)
+ return NULL; /* No public- or private-key object. */
+
+ l2 = gcry_sexp_cadr (list);
+ gcry_sexp_release (list);
+ list = l2;
+ l2 = NULL;
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ goto fail; /* Invalid structure of object. */
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name (name);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ if (!module)
+ goto fail; /* Unknown algorithm. */
+
+ pubkey = (gcry_pk_spec_t *) module->spec;
+ extraspec = module->extraspec;
+
+ elems = pubkey->elements_grip;
+ if (!elems)
+ goto fail; /* No grip parameter. */
+
+ if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
+ goto fail;
+
+ if (extraspec && extraspec->comp_keygrip)
+ {
+ /* Module specific method to compute a keygrip. */
+ if (extraspec->comp_keygrip (md, list))
+ goto fail;
+ }
+ else
+ {
+ /* Generic method to compute a keygrip. */
+ for (idx = 0, s = elems; *s; s++, idx++)
+ {
+ const char *data;
+ size_t datalen;
+ char buf[30];
+
+ l2 = gcry_sexp_find_token (list, s, 1);
+ if (! l2)
+ goto fail;
+ data = gcry_sexp_nth_data (l2, 1, &datalen);
+ if (! data)
+ goto fail;
+
+ snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
+ gcry_md_write (md, buf, strlen (buf));
+ gcry_md_write (md, data, datalen);
+ gcry_sexp_release (l2);
+ l2 = NULL;
+ gcry_md_write (md, ")", 1);
+ }
+ }
+
+ if (!array)
+ {
+ array = gcry_malloc (20);
+ if (! array)
+ goto fail;
+ }
+
+ memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
+ okay = 1;
+
+ fail:
+ gcry_free (name);
+ gcry_sexp_release (l2);
+ gcry_md_close (md);
+ gcry_sexp_release (list);
+ return okay? array : NULL;
+}
+
+
+\f
+const char *
+gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ gcry_mpi_t *pkey = NULL;
+ gcry_sexp_t list = NULL;
+ gcry_sexp_t l2;
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec;
+ char *name = NULL;
+ const char *result = NULL;
+ int want_private = 1;
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ if (key)
+ {
+ iterator = 0;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token (key, "public-key", 0);
+ if (list)
+ want_private = 0;
+ if (!list)
+ list = gcry_sexp_find_token (key, "private-key", 0);
+ if (!list)
+ return NULL; /* No public- or private-key object. */
+
+ l2 = gcry_sexp_cadr (list);
+ gcry_sexp_release (list);
+ list = l2;
+ l2 = NULL;
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ goto leave; /* Invalid structure of object. */
+
+ /* Get the key. We pass the names of the parameters for
+ override_elems; this allows to call this function without the
+ actual public key parameter. */
+ if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
+ goto leave;
+ }
+ else
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name ("ecc");
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ if (!module)
+ goto leave;
+ }
+
+ extraspec = module->extraspec;
+ if (!extraspec || !extraspec->get_curve)
+ goto leave;
+
+ result = extraspec->get_curve (pkey, iterator, r_nbits);
+
+ leave:
+ if (pkey)
+ {
+ release_mpi_array (pkey);
+ gcry_free (pkey);
+ }
+ if (module)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ gcry_free (name);
+ gcry_sexp_release (list);
+ return result;
+}
+
+
+\f
+gcry_sexp_t
+gcry_pk_get_param (int algo, const char *name)
+{
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec;
+ gcry_sexp_t result = NULL;
+
+ if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
+ return NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name ("ecc");
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ if (module)
+ {
+ extraspec = module->extraspec;
+ if (extraspec && extraspec->get_curve_param)
+ result = extraspec->get_curve_param (name);
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ return result;
+}
+
+
+\f
+gcry_error_t
+gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ switch (cmd)
+ {
+ case GCRYCTL_DISABLE_ALGO:
+ /* This one expects a buffer pointing to an integer with the
+ algo number. */
+ if ((! buffer) || (buflen != sizeof (int)))
+ err = GPG_ERR_INV_ARG;
+ else
+ disable_pubkey_algo (*((int *) buffer));
+ break;
+
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* Return information about the given algorithm
+
+ WHAT selects the kind of information returned:
+
+ GCRYCTL_TEST_ALGO:
+ Returns 0 when the specified algorithm is available for use.
+ Buffer must be NULL, nbytes may have the address of a variable
+ with the required usage of the algorithm. It may be 0 for don't
+ care or a combination of the GCRY_PK_USAGE_xxx flags;
+
+ GCRYCTL_GET_ALGO_USAGE:
+ Return the usage flags for the given algo. An invalid algo
+ returns 0. Disabled algos are ignored here because we
+ only want to know whether the algo is at all capable of
+ the usage.
+
+ Note: Because this function is in most cases used to return an
+ integer value, we can make it easier for the caller to just look at
+ the return value. The caller will in all cases consult the value
+ and thereby detecting whether a error occurred or not (i.e. while
+ checking the block size) */
+gcry_error_t
+gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ switch (what)
+ {
+ case GCRYCTL_TEST_ALGO:
+ {
+ int use = nbytes ? *nbytes : 0;
+ if (buffer)
+ err = GPG_ERR_INV_ARG;
+ else if (check_pubkey_algo (algorithm, use))
+ err = GPG_ERR_PUBKEY_ALGO;
+ break;
+ }
+
+ case GCRYCTL_GET_ALGO_USAGE:
+ {
+ gcry_module_t pubkey;
+ int use = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ {
+ use = ((gcry_pk_spec_t *) pubkey->spec)->use;
+ _gcry_module_release (pubkey);
+ }
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ /* FIXME? */
+ *nbytes = use;
+
+ break;
+ }
+
+ case GCRYCTL_GET_ALGO_NPKEY:
+ {
+ /* FIXME? */
+ int npkey = pubkey_get_npkey (algorithm);
+ *nbytes = npkey;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NSKEY:
+ {
+ /* FIXME? */
+ int nskey = pubkey_get_nskey (algorithm);
+ *nbytes = nskey;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NSIGN:
+ {
+ /* FIXME? */
+ int nsign = pubkey_get_nsig (algorithm);
+ *nbytes = nsign;
+ break;
+ }
+ case GCRYCTL_GET_ALGO_NENCR:
+ {
+ /* FIXME? */
+ int nencr = pubkey_get_nenc (algorithm);
+ *nbytes = nencr;
+ break;
+ }
+
+ default:
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* Explicitly initialize this module. */
+gcry_err_code_t
+_gcry_pk_init (void)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ return err;
+}
+
+
+gcry_err_code_t
+_gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t pubkey;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
+ if (pubkey)
+ *module = pubkey;
+ else
+ err = GPG_ERR_PUBKEY_ALGO;
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return err;
+}
+
+
+void
+_gcry_pk_module_release (gcry_module_t module)
+{
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+}
+
+/* Get a list consisting of the IDs of the loaded pubkey modules. If
+ LIST is zero, write the number of loaded pubkey modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less pubkey modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t
+gcry_pk_list (int *list, int *list_length)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ err = _gcry_module_list (pubkeys_registered, list, list_length);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+
+ return err;
+}
+
+
+/* Run the selftests for pubkey algorithm ALGO with optional reporting
+ function REPORT. */
+gpg_error_t
+_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
+{
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec = NULL;
+ gcry_err_code_t ec = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = _gcry_module_lookup_id (pubkeys_registered, algo);
+ if (module && !(module->flags & FLAG_MODULE_DISABLED))
+ extraspec = module->extraspec;
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ if (extraspec && extraspec->selftest)
+ ec = extraspec->selftest (algo, extended, report);
+ else
+ {
+ ec = GPG_ERR_PUBKEY_ALGO;
+ if (report)
+ report ("pubkey", algo, "module",
+ module && !(module->flags & FLAG_MODULE_DISABLED)?
+ "no selftest available" :
+ module? "algorithm disabled" : "algorithm not found");
+ }
+
+ if (module)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ return gpg_error (ec);
+}
+
+
+/* This function is only used by ac.c! */
+gcry_err_code_t
+_gcry_pk_get_elements (int algo, char **enc, char **sig)
+{
+ gcry_module_t pubkey;
+ gcry_pk_spec_t *spec;
+ gcry_err_code_t err;
+ char *enc_cp;
+ char *sig_cp;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ enc_cp = NULL;
+ sig_cp = NULL;
+ spec = NULL;
+
+ pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
+ if (! pubkey)
+ {
+ err = GPG_ERR_INTERNAL;
+ goto out;
+ }
+ spec = pubkey->spec;
+
+ if (enc)
+ {
+ enc_cp = strdup (spec->elements_enc);
+ if (! enc_cp)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto out;
+ }
+ }
+
+ if (sig)
+ {
+ sig_cp = strdup (spec->elements_sig);
+ if (! sig_cp)
+ {
+ err = gpg_err_code_from_syserror ();
+ goto out;
+ }
+ }
+
+ if (enc)
+ *enc = enc_cp;
+ if (sig)
+ *sig = sig_cp;
+ err = 0;
+
+ out:
+
+ _gcry_module_release (pubkey);
+ if (err)
+ {
+ free (enc_cp);
+ free (sig_cp);
+ }
+
+ return err;
+}
--- /dev/null
+/* rfc2268.c - The cipher described in rfc2268; aka Ron's Cipher 2.
+ * Copyright (C) 2003 Nikos Mavroyanopoulos
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* This implementation was written by Nikos Mavroyanopoulos for GNUTLS
+ * as a Libgcrypt module (gnutls/lib/x509/rc2.c) and later adapted for
+ * direct use by Libgcrypt by Werner Koch. This implementation is
+ * only useful for pkcs#12 decryption.
+ *
+ * The implementation here is based on Peter Gutmann's RRC.2 paper.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "g10lib.h"
+#include "types.h"
+#include "cipher.h"
+
+#define RFC2268_BLOCKSIZE 8
+
+typedef struct
+{
+ u16 S[64];
+} RFC2268_context;
+
+static const unsigned char rfc2268_sbox[] = {
+ 217, 120, 249, 196, 25, 221, 181, 237,
+ 40, 233, 253, 121, 74, 160, 216, 157,
+ 198, 126, 55, 131, 43, 118, 83, 142,
+ 98, 76, 100, 136, 68, 139, 251, 162,
+ 23, 154, 89, 245, 135, 179, 79, 19,
+ 97, 69, 109, 141, 9, 129, 125, 50,
+ 189, 143, 64, 235, 134, 183, 123, 11,
+ 240, 149, 33, 34, 92, 107, 78, 130,
+ 84, 214, 101, 147, 206, 96, 178, 28,
+ 115, 86, 192, 20, 167, 140, 241, 220,
+ 18, 117, 202, 31, 59, 190, 228, 209,
+ 66, 61, 212, 48, 163, 60, 182, 38,
+ 111, 191, 14, 218, 70, 105, 7, 87,
+ 39, 242, 29, 155, 188, 148, 67, 3,
+ 248, 17, 199, 246, 144, 239, 62, 231,
+ 6, 195, 213, 47, 200, 102, 30, 215,
+ 8, 232, 234, 222, 128, 82, 238, 247,
+ 132, 170, 114, 172, 53, 77, 106, 42,
+ 150, 26, 210, 113, 90, 21, 73, 116,
+ 75, 159, 208, 94, 4, 24, 164, 236,
+ 194, 224, 65, 110, 15, 81, 203, 204,
+ 36, 145, 175, 80, 161, 244, 112, 57,
+ 153, 124, 58, 133, 35, 184, 180, 122,
+ 252, 2, 54, 91, 37, 85, 151, 49,
+ 45, 93, 250, 152, 227, 138, 146, 174,
+ 5, 223, 41, 16, 103, 108, 186, 201,
+ 211, 0, 230, 207, 225, 158, 168, 44,
+ 99, 22, 1, 63, 88, 226, 137, 169,
+ 13, 56, 52, 27, 171, 51, 255, 176,
+ 187, 72, 12, 95, 185, 177, 205, 46,
+ 197, 243, 219, 71, 229, 165, 156, 119,
+ 10, 166, 32, 104, 254, 127, 193, 173
+};
+
+#define rotl16(x,n) (((x) << ((u16)(n))) | ((x) >> (16 - (u16)(n))))
+#define rotr16(x,n) (((x) >> ((u16)(n))) | ((x) << (16 - (u16)(n))))
+
+static const char *selftest (void);
+
+
+static void
+do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 0; i < 16; i++)
+ {
+ j = i * 4;
+ /* For some reason I cannot combine those steps. */
+ word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+ word0 = rotl16(word0, 1);
+
+ word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+ word1 = rotl16(word1, 2);
+
+ word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+ word2 = rotl16(word2, 3);
+
+ word3 += (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+ word3 = rotl16(word3, 5);
+
+ if (i == 4 || i == 10)
+ {
+ word0 += ctx->S[word3 & 63];
+ word1 += ctx->S[word0 & 63];
+ word2 += ctx->S[word1 & 63];
+ word3 += ctx->S[word2 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+static void
+do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ RFC2268_context *ctx = context;
+ register int i, j;
+ u16 word0 = 0, word1 = 0, word2 = 0, word3 = 0;
+
+ word0 = (word0 << 8) | inbuf[1];
+ word0 = (word0 << 8) | inbuf[0];
+ word1 = (word1 << 8) | inbuf[3];
+ word1 = (word1 << 8) | inbuf[2];
+ word2 = (word2 << 8) | inbuf[5];
+ word2 = (word2 << 8) | inbuf[4];
+ word3 = (word3 << 8) | inbuf[7];
+ word3 = (word3 << 8) | inbuf[6];
+
+ for (i = 15; i >= 0; i--)
+ {
+ j = i * 4;
+
+ word3 = rotr16(word3, 5);
+ word3 -= (word0 & ~word2) + (word1 & word2) + ctx->S[j + 3];
+
+ word2 = rotr16(word2, 3);
+ word2 -= (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
+
+ word1 = rotr16(word1, 2);
+ word1 -= (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
+
+ word0 = rotr16(word0, 1);
+ word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
+
+ if (i == 5 || i == 11)
+ {
+ word3 = word3 - ctx->S[word2 & 63];
+ word2 = word2 - ctx->S[word1 & 63];
+ word1 = word1 - ctx->S[word0 & 63];
+ word0 = word0 - ctx->S[word3 & 63];
+ }
+
+ }
+
+ outbuf[0] = word0 & 255;
+ outbuf[1] = word0 >> 8;
+ outbuf[2] = word1 & 255;
+ outbuf[3] = word1 >> 8;
+ outbuf[4] = word2 & 255;
+ outbuf[5] = word2 >> 8;
+ outbuf[6] = word3 & 255;
+ outbuf[7] = word3 >> 8;
+}
+
+
+static gpg_err_code_t
+setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
+{
+ static int initialized;
+ static const char *selftest_failed;
+ RFC2268_context *ctx = context;
+ unsigned int i;
+ unsigned char *S, x;
+ int len;
+ int bits = keylen * 8;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("RFC2268 selftest failed (%s).\n", selftest_failed);
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen < 40 / 8) /* We want at least 40 bits. */
+ return GPG_ERR_INV_KEYLEN;
+
+ S = (unsigned char *) ctx->S;
+
+ for (i = 0; i < keylen; i++)
+ S[i] = key[i];
+
+ for (i = keylen; i < 128; i++)
+ S[i] = rfc2268_sbox[(S[i - keylen] + S[i - 1]) & 255];
+
+ S[0] = rfc2268_sbox[S[0]];
+
+ /* Phase 2 - reduce effective key size to "bits". This was not
+ * discussed in Gutmann's paper. I've copied that from the public
+ * domain code posted in sci.crypt. */
+ if (with_phase2)
+ {
+ len = (bits + 7) >> 3;
+ i = 128 - len;
+ x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
+ S[i] = x;
+
+ while (i--)
+ {
+ x = rfc2268_sbox[x ^ S[i + len]];
+ S[i] = x;
+ }
+ }
+
+ /* Make the expanded key, endian independent. */
+ for (i = 0; i < 64; i++)
+ ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
+
+ return 0;
+}
+
+static gpg_err_code_t
+do_setkey (void *context, const unsigned char *key, unsigned int keylen)
+{
+ return setkey_core (context, key, keylen, 1);
+}
+
+static const char *
+selftest (void)
+{
+ RFC2268_context ctx;
+ unsigned char scratch[16];
+
+ /* Test vectors from Peter Gutmann's paper. */
+ static unsigned char key_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_1[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const unsigned char ciphertext_1[] =
+ { 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 };
+
+ static unsigned char key_2[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+ };
+ static unsigned char plaintext_2[] =
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_2[] =
+ { 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 };
+
+ /* This one was checked against libmcrypt's RFC2268. */
+ static unsigned char key_3[] =
+ { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ static unsigned char plaintext_3[] =
+ { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static unsigned char ciphertext_3[] =
+ { 0x8f, 0xd1, 0x03, 0x89, 0x33, 0x6b, 0xf9, 0x5e };
+
+
+ /* First test. */
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_encrypt (&ctx, scratch, plaintext_1);
+
+ if (memcmp (scratch, ciphertext_1, sizeof(ciphertext_1)))
+ return "RFC2268 encryption test 1 failed.";
+
+ setkey_core (&ctx, key_1, sizeof(key_1), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
+ return "RFC2268 decryption test 1 failed.";
+
+ /* Second test. */
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_encrypt (&ctx, scratch, plaintext_2);
+ if (memcmp (scratch, ciphertext_2, sizeof(ciphertext_2)))
+ return "RFC2268 encryption test 2 failed.";
+
+ setkey_core (&ctx, key_2, sizeof(key_2), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
+ return "RFC2268 decryption test 2 failed.";
+
+ /* Third test. */
+ setkey_core(&ctx, key_3, sizeof(key_3), 0);
+ do_encrypt(&ctx, scratch, plaintext_3);
+
+ if (memcmp(scratch, ciphertext_3, sizeof(ciphertext_3)))
+ return "RFC2268 encryption test 3 failed.";
+
+ setkey_core (&ctx, key_3, sizeof(key_3), 0);
+ do_decrypt (&ctx, scratch, scratch);
+ if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
+ return "RFC2268 decryption test 3 failed.";
+
+ return NULL;
+}
+
+
+
+static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
+ {
+ /*{ "1.2.840.113549.3.2", GCRY_CIPHER_MODE_CBC },*/
+ /* pbeWithSHAAnd40BitRC2_CBC */
+ { "1.2.840.113549.1.12.1.6", GCRY_CIPHER_MODE_CBC },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
+ "RFC2268_40", NULL, oids_rfc2268_40,
+ RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
+ do_setkey, do_encrypt, do_decrypt
+};
--- /dev/null
+/* rijndael-tables.h - Rijndael (AES) for GnuPG,
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* To keep the actual implementation at a readable size we use this
+ include file to define the tables. */
+
+static const unsigned char S[256] =
+ {
+ 99, 124, 119, 123, 242, 107, 111, 197,
+ 48, 1, 103, 43, 254, 215, 171, 118,
+ 202, 130, 201, 125, 250, 89, 71, 240,
+ 173, 212, 162, 175, 156, 164, 114, 192,
+ 183, 253, 147, 38, 54, 63, 247, 204,
+ 52, 165, 229, 241, 113, 216, 49, 21,
+ 4, 199, 35, 195, 24, 150, 5, 154,
+ 7, 18, 128, 226, 235, 39, 178, 117,
+ 9, 131, 44, 26, 27, 110, 90, 160,
+ 82, 59, 214, 179, 41, 227, 47, 132,
+ 83, 209, 0, 237, 32, 252, 177, 91,
+ 106, 203, 190, 57, 74, 76, 88, 207,
+ 208, 239, 170, 251, 67, 77, 51, 133,
+ 69, 249, 2, 127, 80, 60, 159, 168,
+ 81, 163, 64, 143, 146, 157, 56, 245,
+ 188, 182, 218, 33, 16, 255, 243, 210,
+ 205, 12, 19, 236, 95, 151, 68, 23,
+ 196, 167, 126, 61, 100, 93, 25, 115,
+ 96, 129, 79, 220, 34, 42, 144, 136,
+ 70, 238, 184, 20, 222, 94, 11, 219,
+ 224, 50, 58, 10, 73, 6, 36, 92,
+ 194, 211, 172, 98, 145, 149, 228, 121,
+ 231, 200, 55, 109, 141, 213, 78, 169,
+ 108, 86, 244, 234, 101, 122, 174, 8,
+ 186, 120, 37, 46, 28, 166, 180, 198,
+ 232, 221, 116, 31, 75, 189, 139, 138,
+ 112, 62, 181, 102, 72, 3, 246, 14,
+ 97, 53, 87, 185, 134, 193, 29, 158,
+ 225, 248, 152, 17, 105, 217, 142, 148,
+ 155, 30, 135, 233, 206, 85, 40, 223,
+ 140, 161, 137, 13, 191, 230, 66, 104,
+ 65, 153, 45, 15, 176, 84, 187, 22
+ };
+
+
+static const unsigned char T1[256][4] =
+ {
+ { 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 },
+ { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d },
+ { 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd },
+ { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 },
+ { 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 },
+ { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d },
+ { 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 },
+ { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a },
+ { 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d },
+ { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 },
+ { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb },
+ { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b },
+ { 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 },
+ { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea },
+ { 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 },
+ { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b },
+ { 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c },
+ { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a },
+ { 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 },
+ { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f },
+ { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 },
+ { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 },
+ { 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 },
+ { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f },
+ { 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 },
+ { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e },
+ { 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 },
+ { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 },
+ { 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 },
+ { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d },
+ { 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 },
+ { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f },
+ { 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e },
+ { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e },
+ { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 },
+ { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb },
+ { 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d },
+ { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce },
+ { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e },
+ { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 },
+ { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 },
+ { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c },
+ { 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f },
+ { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed },
+ { 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 },
+ { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b },
+ { 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 },
+ { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a },
+ { 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a },
+ { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 },
+ { 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 },
+ { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 },
+ { 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 },
+ { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 },
+ { 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 },
+ { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 },
+ { 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe },
+ { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a },
+ { 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc },
+ { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 },
+ { 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 },
+ { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 },
+ { 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a },
+ { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d },
+ { 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 },
+ { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f },
+ { 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 },
+ { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 },
+ { 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 },
+ { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 },
+ { 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 },
+ { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 },
+ { 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 },
+ { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f },
+ { 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e },
+ { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 },
+ { 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 },
+ { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c },
+ { 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 },
+ { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 },
+ { 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 },
+ { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e },
+ { 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a },
+ { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 },
+ { 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e },
+ { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 },
+ { 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 },
+ { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b },
+ { 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 },
+ { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 },
+ { 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 },
+ { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 },
+ { 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa },
+ { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 },
+ { 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e },
+ { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 },
+ { 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 },
+ { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 },
+ { 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 },
+ { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 },
+ { 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c },
+ { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 },
+ { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc },
+ { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 },
+ { 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 },
+ { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa },
+ { 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 },
+ { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 },
+ { 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f },
+ { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 },
+ { 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 },
+ { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 },
+ { 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 },
+ { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 },
+ { 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 },
+ { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 },
+ { 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 },
+ { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 },
+ { 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff },
+ { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a },
+ { 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 },
+ { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 },
+ { 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 },
+ { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 },
+ { 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 },
+ { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 },
+ { 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc },
+ { 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a }
+ };
+
+static const unsigned char T2[256][4] =
+ {
+ { 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c },
+ { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b },
+ { 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b },
+ { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 },
+ { 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 },
+ { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b },
+ { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 },
+ { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 },
+ { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 },
+ { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d },
+ { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 },
+ { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 },
+ { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 },
+ { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf },
+ { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 },
+ { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 },
+ { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd },
+ { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 },
+ { 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f },
+ { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc },
+ { 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 },
+ { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 },
+ { 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 },
+ { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 },
+ { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 },
+ { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 },
+ { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 },
+ { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a },
+ { 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 },
+ { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 },
+ { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 },
+ { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 },
+ { 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 },
+ { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a },
+ { 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e },
+ { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 },
+ { 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b },
+ { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 },
+ { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 },
+ { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 },
+ { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 },
+ { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed },
+ { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc },
+ { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b },
+ { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb },
+ { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 },
+ { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c },
+ { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf },
+ { 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef },
+ { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb },
+ { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d },
+ { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 },
+ { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 },
+ { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f },
+ { 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c },
+ { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 },
+ { 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 },
+ { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f },
+ { 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d },
+ { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 },
+ { 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 },
+ { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 },
+ { 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff },
+ { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 },
+ { 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c },
+ { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec },
+ { 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 },
+ { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 },
+ { 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 },
+ { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d },
+ { 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d },
+ { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 },
+ { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 },
+ { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc },
+ { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a },
+ { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 },
+ { 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee },
+ { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 },
+ { 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e },
+ { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb },
+ { 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 },
+ { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a },
+ { 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 },
+ { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c },
+ { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 },
+ { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 },
+ { 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 },
+ { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 },
+ { 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 },
+ { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d },
+ { 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 },
+ { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 },
+ { 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 },
+ { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea },
+ { 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a },
+ { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 },
+ { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 },
+ { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e },
+ { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 },
+ { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 },
+ { 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd },
+ { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f },
+ { 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd },
+ { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a },
+ { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e },
+ { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 },
+ { 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 },
+ { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e },
+ { 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 },
+ { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 },
+ { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 },
+ { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e },
+ { 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 },
+ { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 },
+ { 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 },
+ { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 },
+ { 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e },
+ { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 },
+ { 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 },
+ { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf },
+ { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 },
+ { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d },
+ { 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 },
+ { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 },
+ { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 },
+ { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f },
+ { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 },
+ { 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 }
+ };
+
+static const unsigned char T3[256][4] =
+ {
+ { 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c },
+ { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b },
+ { 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b },
+ { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 },
+ { 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 },
+ { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b },
+ { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 },
+ { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 },
+ { 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 },
+ { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d },
+ { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 },
+ { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 },
+ { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 },
+ { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf },
+ { 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 },
+ { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 },
+ { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd },
+ { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 },
+ { 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f },
+ { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc },
+ { 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 },
+ { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 },
+ { 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 },
+ { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 },
+ { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 },
+ { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 },
+ { 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 },
+ { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a },
+ { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 },
+ { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 },
+ { 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 },
+ { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 },
+ { 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 },
+ { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a },
+ { 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e },
+ { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 },
+ { 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b },
+ { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 },
+ { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 },
+ { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 },
+ { 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 },
+ { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed },
+ { 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc },
+ { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b },
+ { 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb },
+ { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 },
+ { 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c },
+ { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf },
+ { 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef },
+ { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb },
+ { 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d },
+ { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 },
+ { 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 },
+ { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f },
+ { 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c },
+ { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 },
+ { 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 },
+ { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f },
+ { 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d },
+ { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 },
+ { 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 },
+ { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 },
+ { 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff },
+ { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 },
+ { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c },
+ { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec },
+ { 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 },
+ { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 },
+ { 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 },
+ { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d },
+ { 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d },
+ { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 },
+ { 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 },
+ { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc },
+ { 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a },
+ { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 },
+ { 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee },
+ { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 },
+ { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e },
+ { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb },
+ { 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 },
+ { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a },
+ { 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 },
+ { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c },
+ { 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 },
+ { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 },
+ { 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 },
+ { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 },
+ { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 },
+ { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d },
+ { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 },
+ { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 },
+ { 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 },
+ { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea },
+ { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a },
+ { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 },
+ { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 },
+ { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e },
+ { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 },
+ { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 },
+ { 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd },
+ { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f },
+ { 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd },
+ { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a },
+ { 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e },
+ { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 },
+ { 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 },
+ { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e },
+ { 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 },
+ { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 },
+ { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 },
+ { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e },
+ { 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 },
+ { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 },
+ { 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 },
+ { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 },
+ { 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e },
+ { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 },
+ { 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 },
+ { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf },
+ { 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 },
+ { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d },
+ { 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 },
+ { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 },
+ { 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 },
+ { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f },
+ { 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 },
+ { 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 }
+ };
+
+static const unsigned char T4[256][4] =
+ {
+ { 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 },
+ { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 },
+ { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 },
+ { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 },
+ { 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 },
+ { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 },
+ { 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 },
+ { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec },
+ { 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f },
+ { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa },
+ { 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 },
+ { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb },
+ { 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 },
+ { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 },
+ { 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 },
+ { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b },
+ { 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 },
+ { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c },
+ { 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e },
+ { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 },
+ { 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 },
+ { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 },
+ { 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab },
+ { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a },
+ { 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 },
+ { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d },
+ { 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 },
+ { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f },
+ { 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 },
+ { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf },
+ { 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e },
+ { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea },
+ { 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d },
+ { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 },
+ { 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc },
+ { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b },
+ { 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 },
+ { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d },
+ { 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd },
+ { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 },
+ { 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 },
+ { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 },
+ { 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 },
+ { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 },
+ { 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d },
+ { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 },
+ { 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 },
+ { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 },
+ { 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 },
+ { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed },
+ { 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a },
+ { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 },
+ { 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 },
+ { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe },
+ { 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 },
+ { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b },
+ { 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d },
+ { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 },
+ { 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 },
+ { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 },
+ { 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 },
+ { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 },
+ { 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 },
+ { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf },
+ { 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 },
+ { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 },
+ { 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 },
+ { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e },
+ { 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 },
+ { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a },
+ { 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba },
+ { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 },
+ { 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 },
+ { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 },
+ { 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 },
+ { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b },
+ { 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 },
+ { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 },
+ { 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc },
+ { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad },
+ { 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 },
+ { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 },
+ { 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c },
+ { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 },
+ { 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd },
+ { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 },
+ { 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 },
+ { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 },
+ { 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b },
+ { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda },
+ { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 },
+ { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 },
+ { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac },
+ { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf },
+ { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 },
+ { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 },
+ { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 },
+ { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c },
+ { 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 },
+ { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 },
+ { 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 },
+ { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e },
+ { 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 },
+ { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f },
+ { 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c },
+ { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc },
+ { 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 },
+ { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c },
+ { 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a },
+ { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 },
+ { 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 },
+ { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 },
+ { 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb },
+ { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 },
+ { 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 },
+ { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 },
+ { 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c },
+ { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 },
+ { 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa },
+ { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 },
+ { 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 },
+ { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a },
+ { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 },
+ { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 },
+ { 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 },
+ { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e },
+ { 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 },
+ { 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c }
+ };
+
+static const unsigned char T5[256][4] =
+ {
+ { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 },
+ { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 },
+ { 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 },
+ { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 },
+ { 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 },
+ { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 },
+ { 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 },
+ { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f },
+ { 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 },
+ { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 },
+ { 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 },
+ { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 },
+ { 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 },
+ { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda },
+ { 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 },
+ { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 },
+ { 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 },
+ { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd },
+ { 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 },
+ { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 },
+ { 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 },
+ { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 },
+ { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 },
+ { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 },
+ { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 },
+ { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 },
+ { 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 },
+ { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a },
+ { 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 },
+ { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 },
+ { 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 },
+ { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c },
+ { 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 },
+ { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 },
+ { 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 },
+ { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a },
+ { 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 },
+ { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 },
+ { 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa },
+ { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 },
+ { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d },
+ { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 },
+ { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 },
+ { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff },
+ { 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 },
+ { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 },
+ { 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 },
+ { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb },
+ { 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 },
+ { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 },
+ { 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 },
+ { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e },
+ { 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 },
+ { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 },
+ { 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 },
+ { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a },
+ { 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f },
+ { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e },
+ { 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 },
+ { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 },
+ { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 },
+ { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d },
+ { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad },
+ { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 },
+ { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c },
+ { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd },
+ { 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc },
+ { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 },
+ { 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc },
+ { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 },
+ { 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 },
+ { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 },
+ { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 },
+ { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d },
+ { 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 },
+ { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 },
+ { 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 },
+ { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 },
+ { 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a },
+ { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef },
+ { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 },
+ { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 },
+ { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 },
+ { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 },
+ { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d },
+ { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 },
+ { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 },
+ { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 },
+ { 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c },
+ { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 },
+ { 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 },
+ { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b },
+ { 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 },
+ { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 },
+ { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e },
+ { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 },
+ { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce },
+ { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 },
+ { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 },
+ { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 },
+ { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 },
+ { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 },
+ { 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 },
+ { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f },
+ { 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d },
+ { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf },
+ { 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b },
+ { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f },
+ { 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d },
+ { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e },
+ { 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 },
+ { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 },
+ { 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a },
+ { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 },
+ { 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 },
+ { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c },
+ { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f },
+ { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf },
+ { 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b },
+ { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 },
+ { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e },
+ { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f },
+ { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c },
+ { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 },
+ { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde },
+ { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 },
+ { 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 },
+ { 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 }
+ };
+
+static const unsigned char T6[256][4] =
+ {
+ { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 },
+ { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e },
+ { 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 },
+ { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 },
+ { 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d },
+ { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c },
+ { 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb },
+ { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 },
+ { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b },
+ { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 },
+ { 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 },
+ { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 },
+ { 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c },
+ { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 },
+ { 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 },
+ { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 },
+ { 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 },
+ { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 },
+ { 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad },
+ { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a },
+ { 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 },
+ { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f },
+ { 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae },
+ { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b },
+ { 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd },
+ { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 },
+ { 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 },
+ { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab },
+ { 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 },
+ { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 },
+ { 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 },
+ { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 },
+ { 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 },
+ { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 },
+ { 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe },
+ { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe },
+ { 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 },
+ { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb },
+ { 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef },
+ { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 },
+ { 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 },
+ { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd },
+ { 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d },
+ { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 },
+ { 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 },
+ { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e },
+ { 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b },
+ { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee },
+ { 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f },
+ { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 },
+ { 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed },
+ { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 },
+ { 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 },
+ { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 },
+ { 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 },
+ { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e },
+ { 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 },
+ { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 },
+ { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 },
+ { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a },
+ { 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a },
+ { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 },
+ { 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 },
+ { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 },
+ { 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 },
+ { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 },
+ { 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 },
+ { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e },
+ { 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 },
+ { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 },
+ { 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 },
+ { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 },
+ { 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d },
+ { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 },
+ { 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 },
+ { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 },
+ { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 },
+ { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 },
+ { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f },
+ { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 },
+ { 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 },
+ { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b },
+ { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde },
+ { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf },
+ { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 },
+ { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 },
+ { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 },
+ { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf },
+ { 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 },
+ { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 },
+ { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d },
+ { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb },
+ { 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 },
+ { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a },
+ { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 },
+ { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 },
+ { 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 },
+ { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c },
+ { 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 },
+ { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 },
+ { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca },
+ { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 },
+ { 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda },
+ { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 },
+ { 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 },
+ { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 },
+ { 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 },
+ { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 },
+ { 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 },
+ { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 },
+ { 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 },
+ { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 },
+ { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c },
+ { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c },
+ { 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 },
+ { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 },
+ { 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 },
+ { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 },
+ { 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa },
+ { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb },
+ { 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 },
+ { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 },
+ { 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 },
+ { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 },
+ { 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 },
+ { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 },
+ { 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 },
+ { 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 }
+ };
+
+static const unsigned char T7[256][4] =
+ {
+ { 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 },
+ { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 },
+ { 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d },
+ { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 },
+ { 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 },
+ { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 },
+ { 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a },
+ { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 },
+ { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba },
+ { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe },
+ { 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c },
+ { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 },
+ { 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 },
+ { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 },
+ { 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 },
+ { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 },
+ { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e },
+ { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 },
+ { 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 },
+ { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce },
+ { 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a },
+ { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 },
+ { 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b },
+ { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 },
+ { 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 },
+ { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b },
+ { 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b },
+ { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 },
+ { 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 },
+ { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 },
+ { 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf },
+ { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 },
+ { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 },
+ { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 },
+ { 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 },
+ { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 },
+ { 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 },
+ { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 },
+ { 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 },
+ { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e },
+ { 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd },
+ { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 },
+ { 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 },
+ { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 },
+ { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd },
+ { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 },
+ { 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 },
+ { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 },
+ { 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 },
+ { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 },
+ { 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b },
+ { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a },
+ { 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 },
+ { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d },
+ { 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c },
+ { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 },
+ { 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 },
+ { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b },
+ { 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc },
+ { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 },
+ { 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 },
+ { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b },
+ { 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b },
+ { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e },
+ { 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 },
+ { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f },
+ { 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 },
+ { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb },
+ { 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 },
+ { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 },
+ { 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 },
+ { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 },
+ { 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb },
+ { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 },
+ { 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 },
+ { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 },
+ { 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 },
+ { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 },
+ { 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 },
+ { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 },
+ { 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 },
+ { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 },
+ { 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a },
+ { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad },
+ { 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 },
+ { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e },
+ { 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 },
+ { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 },
+ { 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 },
+ { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 },
+ { 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 },
+ { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b },
+ { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 },
+ { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f },
+ { 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff },
+ { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 },
+ { 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f },
+ { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 },
+ { 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f },
+ { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 },
+ { 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 },
+ { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 },
+ { 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec },
+ { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 },
+ { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef },
+ { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 },
+ { 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a },
+ { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 },
+ { 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c },
+ { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b },
+ { 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb },
+ { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 },
+ { 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 },
+ { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 },
+ { 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 },
+ { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 },
+ { 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 },
+ { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 },
+ { 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd },
+ { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 },
+ { 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 },
+ { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 },
+ { 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 },
+ { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d },
+ { 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c },
+ { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 },
+ { 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 },
+ { 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 }
+ };
+
+static const unsigned char T8[256][4] =
+ {
+ { 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e },
+ { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a },
+ { 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f },
+ { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b },
+ { 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad },
+ { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 },
+ { 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 },
+ { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 },
+ { 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 },
+ { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d },
+ { 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 },
+ { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b },
+ { 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 },
+ { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 },
+ { 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 },
+ { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e },
+ { 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 },
+ { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 },
+ { 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 },
+ { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d },
+ { 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 },
+ { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 },
+ { 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb },
+ { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 },
+ { 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f },
+ { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 },
+ { 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 },
+ { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 },
+ { 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f },
+ { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 },
+ { 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 },
+ { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed },
+ { 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 },
+ { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e },
+ { 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 },
+ { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 },
+ { 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 },
+ { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 },
+ { 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 },
+ { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd },
+ { 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 },
+ { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d },
+ { 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 },
+ { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 },
+ { 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 },
+ { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 },
+ { 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 },
+ { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 },
+ { 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c },
+ { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 },
+ { 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 },
+ { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c },
+ { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f },
+ { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 },
+ { 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 },
+ { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 },
+ { 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 },
+ { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b },
+ { 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 },
+ { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c },
+ { 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 },
+ { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 },
+ { 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 },
+ { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 },
+ { 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf },
+ { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 },
+ { 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c },
+ { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b },
+ { 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb },
+ { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 },
+ { 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 },
+ { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 },
+ { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 },
+ { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 },
+ { 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc },
+ { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 },
+ { 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 },
+ { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 },
+ { 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 },
+ { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 },
+ { 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 },
+ { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 },
+ { 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 },
+ { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f },
+ { 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 },
+ { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 },
+ { 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 },
+ { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 },
+ { 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 },
+ { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf },
+ { 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 },
+ { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb },
+ { 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e },
+ { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 },
+ { 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa },
+ { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef },
+ { 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a },
+ { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 },
+ { 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a },
+ { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 },
+ { 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc },
+ { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 },
+ { 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 },
+ { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 },
+ { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 },
+ { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 },
+ { 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c },
+ { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 },
+ { 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 },
+ { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb },
+ { 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 },
+ { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d },
+ { 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 },
+ { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb },
+ { 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 },
+ { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a },
+ { 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 },
+ { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 },
+ { 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f },
+ { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 },
+ { 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 },
+ { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 },
+ { 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc },
+ { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff },
+ { 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 },
+ { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 },
+ { 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 },
+ { 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 }
+ };
+
+static const unsigned char S5[256] =
+ {
+ 0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
+ 0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
+ 0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,
+ 0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,
+ 0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,
+ 0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,
+ 0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,
+ 0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,
+ 0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,
+ 0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,
+ 0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,
+ 0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,
+ 0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,
+ 0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,
+ 0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,
+ 0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,
+ 0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,
+ 0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,
+ 0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,
+ 0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,
+ 0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,
+ 0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,
+ 0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,
+ 0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,
+ 0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,
+ 0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,
+ 0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,
+ 0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,
+ 0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,
+ 0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,
+ 0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,
+ 0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
+ };
+
+static const unsigned char U1[256][4] =
+ {
+ { 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b },
+ { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d },
+ { 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 },
+ { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 },
+ { 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 },
+ { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 },
+ { 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f },
+ { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 },
+ { 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb },
+ { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad },
+ { 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 },
+ { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 },
+ { 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 },
+ { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 },
+ { 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf },
+ { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 },
+ { 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 },
+ { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 },
+ { 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c },
+ { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a },
+ { 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 },
+ { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e },
+ { 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 },
+ { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 },
+ { 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 },
+ { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 },
+ { 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec },
+ { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa },
+ { 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 },
+ { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e },
+ { 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 },
+ { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 },
+ { 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd },
+ { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb },
+ { 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 },
+ { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 },
+ { 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 },
+ { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 },
+ { 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 },
+ { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f },
+ { 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d },
+ { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b },
+ { 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 },
+ { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 },
+ { 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 },
+ { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 },
+ { 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 },
+ { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f },
+ { 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 },
+ { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 },
+ { 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa },
+ { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc },
+ { 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde },
+ { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 },
+ { 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 },
+ { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 },
+ { 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 },
+ { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 },
+ { 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a },
+ { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c },
+ { 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e },
+ { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 },
+ { 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 },
+ { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 },
+ { 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc },
+ { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea },
+ { 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 },
+ { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 },
+ { 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 },
+ { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 },
+ { 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 },
+ { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e },
+ { 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c },
+ { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a },
+ { 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 },
+ { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 },
+ { 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 },
+ { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 },
+ { 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 },
+ { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e },
+ { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 },
+ { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 },
+ { 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab },
+ { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd },
+ { 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf },
+ { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 },
+ { 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 },
+ { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 },
+ { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 },
+ { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 },
+ { 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b },
+ { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d },
+ { 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f },
+ { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 },
+ { 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 },
+ { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 },
+ { 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a },
+ { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c },
+ { 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 },
+ { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 },
+ { 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 },
+ { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 },
+ { 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e },
+ { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 },
+ { 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba },
+ { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac },
+ { 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 },
+ { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 },
+ { 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 },
+ { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 },
+ { 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce },
+ { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 },
+ { 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 },
+ { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 },
+ { 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d },
+ { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b },
+ { 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 },
+ { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f },
+ { 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 },
+ { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 },
+ { 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 },
+ { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 },
+ { 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed },
+ { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb },
+ { 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 },
+ { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f },
+ { 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 },
+ { 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 }
+ };
+
+static const unsigned char U2[256][4] =
+ {
+ { 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d },
+ { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 },
+ { 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 },
+ { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 },
+ { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 },
+ { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f },
+ { 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 },
+ { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b },
+ { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd },
+ { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 },
+ { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 },
+ { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 },
+ { 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 },
+ { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf },
+ { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 },
+ { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b },
+ { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 },
+ { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac },
+ { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 },
+ { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 },
+ { 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde },
+ { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 },
+ { 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea },
+ { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 },
+ { 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 },
+ { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c },
+ { 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 },
+ { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 },
+ { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e },
+ { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 },
+ { 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a },
+ { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 },
+ { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 },
+ { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a },
+ { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 },
+ { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e },
+ { 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 },
+ { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 },
+ { 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c },
+ { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 },
+ { 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 },
+ { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa },
+ { 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 },
+ { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e },
+ { 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 },
+ { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 },
+ { 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec },
+ { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 },
+ { 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb },
+ { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 },
+ { 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef },
+ { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 },
+ { 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 },
+ { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 },
+ { 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 },
+ { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d },
+ { 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b },
+ { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 },
+ { 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f },
+ { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 },
+ { 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 },
+ { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 },
+ { 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 },
+ { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d },
+ { 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 },
+ { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd },
+ { 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 },
+ { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 },
+ { 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf },
+ { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 },
+ { 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b },
+ { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 },
+ { 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 },
+ { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d },
+ { 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 },
+ { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 },
+ { 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f },
+ { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 },
+ { 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b },
+ { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 },
+ { 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c },
+ { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 },
+ { 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 },
+ { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 },
+ { 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 },
+ { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e },
+ { 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 },
+ { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a },
+ { 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc },
+ { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 },
+ { 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 },
+ { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 },
+ { 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 },
+ { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce },
+ { 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 },
+ { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa },
+ { 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba },
+ { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 },
+ { 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e },
+ { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 },
+ { 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 },
+ { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 },
+ { 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 },
+ { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc },
+ { 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a },
+ { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 },
+ { 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e },
+ { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 },
+ { 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 },
+ { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 },
+ { 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 },
+ { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c },
+ { 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 },
+ { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b },
+ { 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 },
+ { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f },
+ { 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 },
+ { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 },
+ { 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d },
+ { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 },
+ { 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 },
+ { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb },
+ { 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 },
+ { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff },
+ { 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 },
+ { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 },
+ { 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d },
+ { 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 }
+ };
+
+static const unsigned char U3[256][4] =
+ {
+ { 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 },
+ { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b },
+ { 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d },
+ { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f },
+ { 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 },
+ { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 },
+ { 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 },
+ { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 },
+ { 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 },
+ { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b },
+ { 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd },
+ { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf },
+ { 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 },
+ { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 },
+ { 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 },
+ { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 },
+ { 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 },
+ { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 },
+ { 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 },
+ { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 },
+ { 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a },
+ { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 },
+ { 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e },
+ { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c },
+ { 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 },
+ { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 },
+ { 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 },
+ { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 },
+ { 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea },
+ { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 },
+ { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce },
+ { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc },
+ { 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f },
+ { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d },
+ { 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b },
+ { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 },
+ { 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 },
+ { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 },
+ { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 },
+ { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 },
+ { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef },
+ { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd },
+ { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb },
+ { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 },
+ { 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 },
+ { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 },
+ { 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 },
+ { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 },
+ { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 },
+ { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 },
+ { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 },
+ { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 },
+ { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c },
+ { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e },
+ { 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 },
+ { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a },
+ { 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 },
+ { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 },
+ { 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 },
+ { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 },
+ { 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c },
+ { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e },
+ { 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 },
+ { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa },
+ { 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 },
+ { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 },
+ { 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 },
+ { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 },
+ { 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad },
+ { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf },
+ { 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 },
+ { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b },
+ { 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 },
+ { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 },
+ { 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 },
+ { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 },
+ { 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d },
+ { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f },
+ { 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 },
+ { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b },
+ { 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde },
+ { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc },
+ { 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa },
+ { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 },
+ { 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 },
+ { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 },
+ { 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 },
+ { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 },
+ { 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e },
+ { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c },
+ { 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a },
+ { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 },
+ { 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 },
+ { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 },
+ { 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 },
+ { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 },
+ { 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 },
+ { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 },
+ { 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 },
+ { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 },
+ { 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb },
+ { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 },
+ { 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff },
+ { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed },
+ { 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 },
+ { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 },
+ { 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 },
+ { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 },
+ { 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b },
+ { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 },
+ { 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f },
+ { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d },
+ { 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 },
+ { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba },
+ { 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c },
+ { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e },
+ { 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 },
+ { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 },
+ { 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 },
+ { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 },
+ { 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 },
+ { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a },
+ { 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c },
+ { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e },
+ { 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 },
+ { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 },
+ { 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 },
+ { 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 }
+ };
+
+static const unsigned char U4[256][4] =
+ {
+ { 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e },
+ { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 },
+ { 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 },
+ { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a },
+ { 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e },
+ { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 },
+ { 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 },
+ { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a },
+ { 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee },
+ { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 },
+ { 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 },
+ { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca },
+ { 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e },
+ { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 },
+ { 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 },
+ { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba },
+ { 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 },
+ { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 },
+ { 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed },
+ { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 },
+ { 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 },
+ { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 },
+ { 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d },
+ { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 },
+ { 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 },
+ { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 },
+ { 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d },
+ { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 },
+ { 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 },
+ { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 },
+ { 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d },
+ { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 },
+ { 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 },
+ { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf },
+ { 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b },
+ { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 },
+ { 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 },
+ { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf },
+ { 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb },
+ { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 },
+ { 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 },
+ { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f },
+ { 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b },
+ { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 },
+ { 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 },
+ { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f },
+ { 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b },
+ { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 },
+ { 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 },
+ { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 },
+ { 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 },
+ { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c },
+ { 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 },
+ { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 },
+ { 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 },
+ { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c },
+ { 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 },
+ { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 },
+ { 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 },
+ { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc },
+ { 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 },
+ { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 },
+ { 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 },
+ { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc },
+ { 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f },
+ { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 },
+ { 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 },
+ { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b },
+ { 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f },
+ { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 },
+ { 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 },
+ { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b },
+ { 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf },
+ { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 },
+ { 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 },
+ { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b },
+ { 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf },
+ { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 },
+ { 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 },
+ { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb },
+ { 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 },
+ { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 },
+ { 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac },
+ { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 },
+ { 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 },
+ { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 },
+ { 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc },
+ { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 },
+ { 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 },
+ { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 },
+ { 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c },
+ { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 },
+ { 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 },
+ { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 },
+ { 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c },
+ { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 },
+ { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 },
+ { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe },
+ { 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda },
+ { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 },
+ { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 },
+ { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e },
+ { 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa },
+ { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 },
+ { 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 },
+ { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e },
+ { 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a },
+ { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 },
+ { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 },
+ { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e },
+ { 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a },
+ { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 },
+ { 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 },
+ { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 },
+ { 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 },
+ { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d },
+ { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 },
+ { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 },
+ { 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 },
+ { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d },
+ { 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 },
+ { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 },
+ { 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 },
+ { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd },
+ { 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 },
+ { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 },
+ { 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 },
+ { 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d }
+ };
+
+static const u32 rcon[30] =
+ {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
+ 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
+ 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
+ };
--- /dev/null
+/* Rijndael (AES) for GnuPG
+ * Copyright (C) 2000, 2001, 2002, 2003, 2007,
+ * 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *******************************************************************
+ * The code here is based on the optimized implementation taken from
+ * http://www.esat.kuleuven.ac.be/~rijmen/rijndael/ on Oct 2, 2000,
+ * which carries this notice:
+ *------------------------------------------
+ * rijndael-alg-fst.c v2.3 April '2000
+ *
+ * Optimised ANSI C code
+ *
+ * authors: v1.0: Antoon Bosselaers
+ * v2.0: Vincent Rijmen
+ * v2.3: Paulo Barreto
+ *
+ * This code is placed in the public domain.
+ *------------------------------------------
+ *
+ * The SP800-38a document is available at:
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#define MAXKC (256/32)
+#define MAXROUNDS 14
+#define BLOCKSIZE (128/8)
+
+
+/* Helper macro to force alignment to 16 bytes. */
+#ifdef __GNUC__
+# define ATTR_ALIGNED_16 __attribute__ ((aligned (16)))
+#else
+# define ATTR_ALIGNED_16
+#endif
+
+
+/* USE_PADLOCK indicates whether to compile the padlock specific
+ code. */
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+# define USE_PADLOCK 1
+# endif
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+
+/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We
+ need the vector-size attribute which seems to be available since
+ gcc 3. However, to be on the safe side we require at least gcc 4. */
+#undef USE_AESNI
+#ifdef ENABLE_AESNI_SUPPORT
+# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4
+# define USE_AESNI 1
+# endif
+#endif /* ENABLE_AESNI_SUPPORT */
+
+#ifdef USE_AESNI
+ typedef int m128i_t __attribute__ ((__vector_size__ (16)));
+#endif /*USE_AESNI*/
+
+/* Define an u32 variant for the sake of gcc 4.4's strict aliasing. */
+#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
+typedef u32 __attribute__ ((__may_alias__)) u32_a_t;
+#else
+typedef u32 u32_a_t;
+#endif
+
+
+\f
+/* Our context object. */
+typedef struct
+{
+ /* The first fields are the keyschedule arrays. This is so that
+ they are aligned on a 16 byte boundary if using gcc. This
+ alignment is required for the AES-NI code and a good idea in any
+ case. The alignment is guaranteed due to the way cipher.c
+ allocates the space for the context. The PROPERLY_ALIGNED_TYPE
+ hack is used to force a minimal alignment if not using gcc of if
+ the alignment requirement is higher that 16 bytes. */
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte keyschedule[MAXROUNDS+1][4][4];
+#ifdef USE_PADLOCK
+ /* The key as passed to the padlock engine. It is only used if
+ the padlock engine is used (USE_PADLOCK, below). */
+ unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#endif /*USE_PADLOCK*/
+ } u1;
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte keyschedule[MAXROUNDS+1][4][4];
+ } u2;
+ int rounds; /* Key-length-dependent number of rounds. */
+ int decryption_prepared; /* The decryption key schedule is available. */
+#ifdef USE_PADLOCK
+ int use_padlock; /* Padlock shall be used. */
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ int use_aesni; /* AES-NI shall be used. */
+#endif /*USE_AESNI*/
+} RIJNDAEL_context;
+
+/* Macros defining alias for the keyschedules. */
+#define keyschenc u1.keyschedule
+#define keyschdec u2.keyschedule
+#define padlockkey u1.padlock_key
+
+/* Two macros to be called prior and after the use of AESNI
+ instructions. There should be no external function calls between
+ the use of these macros. There purpose is to make sure that the
+ SSE regsiters are cleared and won't reveal any information about
+ the key or the data. */
+#ifdef USE_AESNI
+# define aesni_prepare() do { } while (0)
+# define aesni_cleanup() \
+ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \
+ "pxor %%xmm1, %%xmm1\n" :: ); \
+ } while (0)
+# define aesni_cleanup_2_4() \
+ do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n":: ); \
+ } while (0)
+#else
+# define aesni_prepare() do { } while (0)
+# define aesni_cleanup() do { } while (0)
+#endif
+
+
+/* All the numbers. */
+#include "rijndael-tables.h"
+
+
+\f
+/* Function prototypes. */
+#ifdef USE_AESNI
+/* We don't want to inline these functions to help gcc allocate enough
+ registers. */
+static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr,
+ unsigned char *b, const unsigned char *a)
+ __attribute__ ((__noinline__));
+static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr,
+ unsigned char *b, const unsigned char *a)
+ __attribute__ ((__noinline__));
+#endif /*USE_AESNI*/
+
+static const char *selftest(void);
+
+
+\f
+/* Perform the key setup. */
+static gcry_err_code_t
+do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
+{
+ static int initialized = 0;
+ static const char *selftest_failed=0;
+ int rounds;
+ int i,j, r, t, rconpointer = 0;
+ int KC;
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte k[MAXKC][4];
+ } k;
+#define k k.k
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte tk[MAXKC][4];
+ } tk;
+#define tk tk.tk
+
+ /* The on-the-fly self tests are only run in non-fips mode. In fips
+ mode explicit self-tests are required. Actually the on-the-fly
+ self-tests are not fully thread-safe and it might happen that a
+ failed self-test won't get noticed in another thread.
+
+ FIXME: We might want to have a central registry of succeeded
+ self-tests. */
+ if (!fips_mode () && !initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if (selftest_failed)
+ log_error ("%s\n", selftest_failed );
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ ctx->decryption_prepared = 0;
+#ifdef USE_PADLOCK
+ ctx->use_padlock = 0;
+#endif
+#ifdef USE_AESNI
+ ctx->use_aesni = 0;
+#endif
+
+ if( keylen == 128/8 )
+ {
+ rounds = 10;
+ KC = 4;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
+ {
+ ctx->use_padlock = 1;
+ memcpy (ctx->padlockkey, key, keylen);
+ }
+#endif
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
+ }
+#endif
+ }
+ else if ( keylen == 192/8 )
+ {
+ rounds = 12;
+ KC = 6;
+
+ if (0)
+ {
+ ;
+ }
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
+ }
+#endif
+ }
+ else if ( keylen == 256/8 )
+ {
+ rounds = 14;
+ KC = 8;
+
+ if (0)
+ {
+ ;
+ }
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
+ }
+#endif
+ }
+ else
+ return GPG_ERR_INV_KEYLEN;
+
+ ctx->rounds = rounds;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ {
+ /* Nothing to do as we support only hardware key generation for
+ now. */
+ }
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI_is_disabled_here
+ else if (ctx->use_aesni && ctx->rounds == 10)
+ {
+ /* Note: This code works for AES-128 but it is not much better
+ than using the standard key schedule. We disable it for
+ now and don't put any effort into implementing this for
+ AES-192 and AES-256. */
+ asm volatile ("movl %[key], %%esi\n\t"
+ "movdqu (%%esi), %%xmm1\n\t" /* xmm1 := key */
+ "movl %[ksch], %%esi\n\t"
+ "movdqa %%xmm1, (%%esi)\n\t" /* ksch[0] := xmm1 */
+ "aeskeygenassist $0x01, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x10(%%esi)\n\t" /* ksch[1] := xmm1 */
+ "aeskeygenassist $0x02, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x20(%%esi)\n\t" /* ksch[2] := xmm1 */
+ "aeskeygenassist $0x04, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x30(%%esi)\n\t" /* ksch[3] := xmm1 */
+ "aeskeygenassist $0x08, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x40(%%esi)\n\t" /* ksch[4] := xmm1 */
+ "aeskeygenassist $0x10, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x50(%%esi)\n\t" /* ksch[5] := xmm1 */
+ "aeskeygenassist $0x20, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x60(%%esi)\n\t" /* ksch[6] := xmm1 */
+ "aeskeygenassist $0x40, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x70(%%esi)\n\t" /* ksch[7] := xmm1 */
+ "aeskeygenassist $0x80, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x80(%%esi)\n\t" /* ksch[8] := xmm1 */
+ "aeskeygenassist $0x1b, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x90(%%esi)\n\t" /* ksch[9] := xmm1 */
+ "aeskeygenassist $0x36, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0xa0(%%esi)\n\t" /* ksch[10] := xmm1 */
+ "jmp .Lleave%=\n"
+
+ ".Lexpand128_%=:\n\t"
+ "pshufd $0xff, %%xmm2, %%xmm2\n\t"
+ "movdqa %%xmm1, %%xmm3\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm1\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm1\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm2\n\t"
+ "pxor %%xmm2, %%xmm1\n\t"
+ "ret\n"
+
+ ".Lleave%=:\n\t"
+ "pxor %%xmm1, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm2\n\t"
+ "pxor %%xmm3, %%xmm3\n"
+ :
+ : [key] "g" (key), [ksch] "g" (ctx->keyschenc)
+ : "%esi", "cc", "memory" );
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+#define W (ctx->keyschenc)
+ for (i = 0; i < keylen; i++)
+ {
+ k[i >> 2][i & 3] = key[i];
+ }
+
+ for (j = KC-1; j >= 0; j--)
+ {
+ *((u32*)tk[j]) = *((u32*)k[j]);
+ }
+ r = 0;
+ t = 0;
+ /* Copy values into round key array. */
+ for (j = 0; (j < KC) && (r < rounds + 1); )
+ {
+ for (; (j < KC) && (t < 4); j++, t++)
+ {
+ *((u32*)W[r][t]) = *((u32*)tk[j]);
+ }
+ if (t == 4)
+ {
+ r++;
+ t = 0;
+ }
+ }
+
+ while (r < rounds + 1)
+ {
+ /* While not enough round key material calculated calculate
+ new values. */
+ tk[0][0] ^= S[tk[KC-1][1]];
+ tk[0][1] ^= S[tk[KC-1][2]];
+ tk[0][2] ^= S[tk[KC-1][3]];
+ tk[0][3] ^= S[tk[KC-1][0]];
+ tk[0][0] ^= rcon[rconpointer++];
+
+ if (KC != 8)
+ {
+ for (j = 1; j < KC; j++)
+ {
+ *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+ }
+ }
+ else
+ {
+ for (j = 1; j < KC/2; j++)
+ {
+ *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+ }
+ tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
+ tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
+ tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
+ tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
+ for (j = KC/2 + 1; j < KC; j++)
+ {
+ *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+ }
+ }
+
+ /* Copy values into round key array. */
+ for (j = 0; (j < KC) && (r < rounds + 1); )
+ {
+ for (; (j < KC) && (t < 4); j++, t++)
+ {
+ *((u32*)W[r][t]) = *((u32*)tk[j]);
+ }
+ if (t == 4)
+ {
+ r++;
+ t = 0;
+ }
+ }
+ }
+#undef W
+ }
+
+ return 0;
+#undef tk
+#undef k
+}
+
+
+static gcry_err_code_t
+rijndael_setkey (void *context, const byte *key, const unsigned keylen)
+{
+ RIJNDAEL_context *ctx = context;
+
+ int rc = do_setkey (ctx, key, keylen);
+ _gcry_burn_stack ( 100 + 16*sizeof(int));
+ return rc;
+}
+
+
+/* Make a decryption key from an encryption key. */
+static void
+prepare_decryption( RIJNDAEL_context *ctx )
+{
+ int r;
+
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
+ {
+ /* The AES-NI decrypt instructions use the Equivalent Inverse
+ Cipher, thus we can't use the the standard decrypt key
+ preparation. */
+ m128i_t *ekey = (m128i_t*)ctx->keyschenc;
+ m128i_t *dkey = (m128i_t*)ctx->keyschdec;
+ int rr;
+
+ dkey[0] = ekey[ctx->rounds];
+ for (r=1, rr=ctx->rounds-1; r < ctx->rounds; r++, rr--)
+ {
+ asm volatile
+ ("movdqu %[ekey], %%xmm1\n\t"
+ /*"aesimc %%xmm1, %%xmm1\n\t"*/
+ ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t"
+ "movdqu %%xmm1, %[dkey]"
+ : [dkey] "=m" (dkey[r])
+ : [ekey] "m" (ekey[rr]) );
+ }
+ dkey[r] = ekey[0];
+ }
+ else
+#endif /*USE_AESNI*/
+ {
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte *w;
+ } w;
+#define w w.w
+
+ for (r=0; r < MAXROUNDS+1; r++ )
+ {
+ *((u32*)ctx->keyschdec[r][0]) = *((u32*)ctx->keyschenc[r][0]);
+ *((u32*)ctx->keyschdec[r][1]) = *((u32*)ctx->keyschenc[r][1]);
+ *((u32*)ctx->keyschdec[r][2]) = *((u32*)ctx->keyschenc[r][2]);
+ *((u32*)ctx->keyschdec[r][3]) = *((u32*)ctx->keyschenc[r][3]);
+ }
+#define W (ctx->keyschdec)
+ for (r = 1; r < ctx->rounds; r++)
+ {
+ w = W[r][0];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+
+ w = W[r][1];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+
+ w = W[r][2];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+
+ w = W[r][3];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+ }
+#undef W
+#undef w
+ }
+}
+
+\f
+/* Encrypt one block. A and B need to be aligned on a 4 byte
+ boundary. A and B may be the same. */
+static void
+do_encrypt_aligned (const RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define rk (ctx->keyschenc)
+ int rounds = ctx->rounds;
+ int r;
+ union
+ {
+ u32 tempu32[4]; /* Force correct alignment. */
+ byte temp[4][4];
+ } u;
+
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]);
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
+ ^ *((u32_a_t*)T2[u.temp[1][1]])
+ ^ *((u32_a_t*)T3[u.temp[2][2]])
+ ^ *((u32_a_t*)T4[u.temp[3][3]]));
+ *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
+ ^ *((u32_a_t*)T2[u.temp[2][1]])
+ ^ *((u32_a_t*)T3[u.temp[3][2]])
+ ^ *((u32_a_t*)T4[u.temp[0][3]]));
+ *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
+ ^ *((u32_a_t*)T2[u.temp[3][1]])
+ ^ *((u32_a_t*)T3[u.temp[0][2]])
+ ^ *((u32_a_t*)T4[u.temp[1][3]]));
+ *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
+ ^ *((u32_a_t*)T2[u.temp[0][1]])
+ ^ *((u32_a_t*)T3[u.temp[1][2]])
+ ^ *((u32_a_t*)T4[u.temp[2][3]]));
+
+ for (r = 1; r < rounds-1; r++)
+ {
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
+
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
+ ^ *((u32_a_t*)T2[u.temp[1][1]])
+ ^ *((u32_a_t*)T3[u.temp[2][2]])
+ ^ *((u32_a_t*)T4[u.temp[3][3]]));
+ *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
+ ^ *((u32_a_t*)T2[u.temp[2][1]])
+ ^ *((u32_a_t*)T3[u.temp[3][2]])
+ ^ *((u32_a_t*)T4[u.temp[0][3]]));
+ *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
+ ^ *((u32_a_t*)T2[u.temp[3][1]])
+ ^ *((u32_a_t*)T3[u.temp[0][2]])
+ ^ *((u32_a_t*)T4[u.temp[1][3]]));
+ *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
+ ^ *((u32_a_t*)T2[u.temp[0][1]])
+ ^ *((u32_a_t*)T3[u.temp[1][2]])
+ ^ *((u32_a_t*)T4[u.temp[2][3]]));
+ }
+
+ /* Last round is special. */
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[rounds-1][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[rounds-1][3]);
+ b[ 0] = T1[u.temp[0][0]][1];
+ b[ 1] = T1[u.temp[1][1]][1];
+ b[ 2] = T1[u.temp[2][2]][1];
+ b[ 3] = T1[u.temp[3][3]][1];
+ b[ 4] = T1[u.temp[1][0]][1];
+ b[ 5] = T1[u.temp[2][1]][1];
+ b[ 6] = T1[u.temp[3][2]][1];
+ b[ 7] = T1[u.temp[0][3]][1];
+ b[ 8] = T1[u.temp[2][0]][1];
+ b[ 9] = T1[u.temp[3][1]][1];
+ b[10] = T1[u.temp[0][2]][1];
+ b[11] = T1[u.temp[1][3]][1];
+ b[12] = T1[u.temp[3][0]][1];
+ b[13] = T1[u.temp[0][1]][1];
+ b[14] = T1[u.temp[1][2]][1];
+ b[15] = T1[u.temp[2][3]][1];
+ *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[rounds][0]);
+ *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]);
+ *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]);
+ *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]);
+#undef rk
+}
+
+
+static void
+do_encrypt (const RIJNDAEL_context *ctx,
+ unsigned char *bx, const unsigned char *ax)
+{
+ /* BX and AX are not necessary correctly aligned. Thus we might
+ need to copy them here. We try to align to a 16 bytes. */
+ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+ {
+ union
+ {
+ u32 dummy[4];
+ byte a[16] ATTR_ALIGNED_16;
+ } a;
+ union
+ {
+ u32 dummy[4];
+ byte b[16] ATTR_ALIGNED_16;
+ } b;
+
+ memcpy (a.a, ax, 16);
+ do_encrypt_aligned (ctx, b.b, a.a);
+ memcpy (bx, b.b, 16);
+ }
+ else
+ {
+ do_encrypt_aligned (ctx, bx, ax);
+ }
+}
+
+
+/* Encrypt or decrypt one block using the padlock engine. A and B may
+ be the same. */
+#ifdef USE_PADLOCK
+static void
+do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
+ unsigned char *bx, const unsigned char *ax)
+{
+ /* BX and AX are not necessary correctly aligned. Thus we need to
+ copy them here. */
+ unsigned char a[16] __attribute__ ((aligned (16)));
+ unsigned char b[16] __attribute__ ((aligned (16)));
+ unsigned int cword[4] __attribute__ ((aligned (16)));
+
+ /* The control word fields are:
+ 127:12 11:10 9 8 7 6 5 4 3:0
+ RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */
+ cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */
+ cword[1] = 0;
+ cword[2] = 0;
+ cword[3] = 0;
+ if (decrypt_flag)
+ cword[0] |= 0x00000200;
+
+ memcpy (a, ax, 16);
+
+ asm volatile
+ ("pushfl\n\t" /* Force key reload. */
+ "popfl\n\t"
+ "xchg %3, %%ebx\n\t" /* Load key. */
+ "movl $1, %%ecx\n\t" /* Init counter for just one block. */
+ ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XSTORE ECB. */
+ "xchg %3, %%ebx\n" /* Restore GOT register. */
+ : /* No output */
+ : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey)
+ : "%ecx", "cc", "memory"
+ );
+
+ memcpy (bx, b, 16);
+
+}
+#endif /*USE_PADLOCK*/
+
+
+#ifdef USE_AESNI
+/* Encrypt one block using the Intel AES-NI instructions. A and B may
+ be the same; they need to be properly aligned to 16 bytes.
+
+ Our problem here is that gcc does not allow the "x" constraint for
+ SSE registers in asm unless you compile with -msse. The common
+ wisdom is to use a separate file for SSE instructions and build it
+ separately. This would require a lot of extra build system stuff,
+ similar to what we do in mpi/ for the asm stuff. What we do
+ instead is to use standard registers and a bit more of plain asm
+ which copies the data and key stuff to the SSE registers and later
+ back. If we decide to implement some block modes with parallelized
+ AES instructions, it might indeed be better to use plain asm ala
+ mpi/. */
+static void
+do_aesni_enc_aligned (const RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ /* Note: For now we relax the alignment requirement for A and B: It
+ does not make much difference because in many case we would need
+ to memcpy them to an extra buffer; using the movdqu is much faster
+ that memcpy and movdqa. For CFB we know that the IV is properly
+ aligned but that is a special case. We should better implement
+ CFB direct in asm. */
+ asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %%xmm0, %[dst]\n"
+ : [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "r" (ctx->keyschenc),
+ [rounds] "r" (ctx->rounds)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+static void
+do_aesni_dec_aligned (const RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t"
+#define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t"
+ asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */
+ "movl %[key], %%esi\n\t"
+ "movdqa (%%esi), %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Ldeclast%=\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Ldeclast%=\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Ldeclast%=:\n\t"
+ aesdeclast_xmm1_xmm0
+ "movdqu %%xmm0, %[dst]\n"
+ : [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "r" (ctx->keyschdec),
+ [rounds] "r" (ctx->rounds)
+ : "%esi", "cc", "memory");
+#undef aesdec_xmm1_xmm0
+#undef aesdeclast_xmm1_xmm0
+}
+
+
+/* Perform a CFB encryption or decryption round using the
+ initialization vector IV and the input block A. Write the result
+ to the output block B and update IV. IV needs to be 16 byte
+ aligned. */
+static void
+do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag,
+ unsigned char *iv, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ asm volatile ("movdqa %[iv], %%xmm0\n\t" /* xmm0 := IV */
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %[src], %%xmm1\n\t" /* Save input. */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */
+
+ "cmp $1, %[decrypt]\n\t"
+ "jz .Ldecrypt_%=\n\t"
+ "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */
+ "jmp .Lleave_%=\n"
+ ".Ldecrypt_%=:\n\t"
+ "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */
+ ".Lleave_%=:\n\t"
+ "movdqu %%xmm0, %[dst]\n" /* Store output. */
+ : [iv] "+m" (*iv), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [decrypt] "m" (decrypt_flag)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+/* Perform a CTR encryption round using the counter CTR and the input
+ block A. Write the result to the output block B and update CTR.
+ CTR needs to be a 16 byte aligned little-endian value. */
+static void
+do_aesni_ctr (const RIJNDAEL_context *ctx,
+ unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */
+ "movaps %%xmm0, %%xmm2\n\t"
+ "mov $1, %%esi\n\t" /* xmm2++ (big-endian) */
+ "movd %%esi, %%xmm1\n\t"
+ "pshufb %[mask], %%xmm2\n\t"
+ "paddq %%xmm1, %%xmm2\n\t"
+ "pshufb %[mask], %%xmm2\n\t"
+ "movdqa %%xmm2, %[ctr]\n" /* Update CTR. */
+
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */
+ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */
+ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */
+
+ : [ctr] "+m" (*ctr), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [mask] "m" (*be_mask)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+/* Four blocks at a time variant of do_aesni_ctr. */
+static void
+do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
+ unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenc_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t"
+#define aesenc_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t"
+#define aesenc_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+#define aesenclast_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t"
+#define aesenclast_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
+#define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
+
+ static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ /* Register usage:
+ esi keyschedule
+ xmm0 CTR-0
+ xmm1 temp / round key
+ xmm2 CTR-1
+ xmm3 CTR-2
+ xmm4 CTR-3
+ xmm5 temp
+ */
+
+ asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */
+ "movaps %%xmm0, %%xmm2\n\t"
+ "mov $1, %%esi\n\t" /* xmm1 := 1 */
+ "movd %%esi, %%xmm1\n\t"
+ "pshufb %[mask], %%xmm2\n\t" /* xmm2 := le(xmm2) */
+ "paddq %%xmm1, %%xmm2\n\t" /* xmm2++ */
+ "movaps %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */
+ "paddq %%xmm1, %%xmm3\n\t" /* xmm3++ */
+ "movaps %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */
+ "paddq %%xmm1, %%xmm4\n\t" /* xmm4++ */
+ "movaps %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */
+ "paddq %%xmm1, %%xmm5\n\t" /* xmm5++ */
+ "pshufb %[mask], %%xmm2\n\t" /* xmm2 := be(xmm2) */
+ "pshufb %[mask], %%xmm3\n\t" /* xmm3 := be(xmm3) */
+ "pshufb %[mask], %%xmm4\n\t" /* xmm4 := be(xmm4) */
+ "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */
+ "movdqa %%xmm5, %[ctr]\n" /* Update CTR. */
+
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */
+ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */
+ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ aesenclast_xmm1_xmm2
+ aesenclast_xmm1_xmm3
+ aesenclast_xmm1_xmm4
+
+ "movdqu %[src], %%xmm1\n\t" /* Get block 1. */
+ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */
+ "movdqu %%xmm0, %[dst]\n\t" /* Store block 1 */
+
+ "movdqu (16)%[src], %%xmm1\n\t" /* Get block 2. */
+ "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */
+ "movdqu %%xmm2, (16)%[dst]\n\t" /* Store block 2. */
+
+ "movdqu (32)%[src], %%xmm1\n\t" /* Get block 3. */
+ "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */
+ "movdqu %%xmm3, (32)%[dst]\n\t" /* Store block 3. */
+
+ "movdqu (48)%[src], %%xmm1\n\t" /* Get block 4. */
+ "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */
+ "movdqu %%xmm4, (48)%[dst]" /* Store block 4. */
+
+ : [ctr] "+m" (*ctr), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [mask] "m" (*be_mask)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenc_xmm1_xmm2
+#undef aesenc_xmm1_xmm3
+#undef aesenc_xmm1_xmm4
+#undef aesenclast_xmm1_xmm0
+#undef aesenclast_xmm1_xmm2
+#undef aesenclast_xmm1_xmm3
+#undef aesenclast_xmm1_xmm4
+}
+
+
+static void
+do_aesni (RIJNDAEL_context *ctx, int decrypt_flag,
+ unsigned char *bx, const unsigned char *ax)
+{
+
+ if (decrypt_flag)
+ {
+ if (!ctx->decryption_prepared )
+ {
+ prepare_decryption ( ctx );
+ ctx->decryption_prepared = 1;
+ }
+ do_aesni_dec_aligned (ctx, bx, ax);
+ }
+ else
+ do_aesni_enc_aligned (ctx, bx, ax);
+}
+#endif /*USE_AESNI*/
+
+
+static void
+rijndael_encrypt (void *context, byte *b, const byte *a)
+{
+ RIJNDAEL_context *ctx = context;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ {
+ do_padlock (ctx, 0, b, a);
+ _gcry_burn_stack (48 + 15 /* possible padding for alignment */);
+ }
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ do_aesni (ctx, 0, b, a);
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ do_encrypt (ctx, b, a);
+ _gcry_burn_stack (56 + 2*sizeof(int));
+ }
+}
+
+
+/* Bulk encryption of complete blocks in CFB mode. Caller needs to
+ make sure that IV is aligned on an unsigned long boundary. This
+ function is only intended for the bulk encryption feature of
+ cipher.c. */
+void
+_gcry_aes_cfb_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *ivp;
+ int i;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ {
+ /* Fixme: Let Padlock do the CFBing. */
+ for ( ;nblocks; nblocks-- )
+ {
+ /* Encrypt the IV. */
+ do_padlock (ctx, 0, iv, iv);
+ /* XOR the input with the IV and store input into IV. */
+ for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ }
+ }
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_cfb (ctx, 0, iv, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ for ( ;nblocks; nblocks-- )
+ {
+ /* Encrypt the IV. */
+ do_encrypt_aligned (ctx, iv, iv);
+ /* XOR the input with the IV and store input into IV. */
+ for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+ *outbuf++ = (*ivp++ ^= *inbuf++);
+ }
+ }
+
+ _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk encryption of complete blocks in CBC mode. Caller needs to
+ make sure that IV is aligned on an unsigned long boundary. This
+ function is only intended for the bulk encryption feature of
+ cipher.c. */
+void
+_gcry_aes_cbc_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks, int cbc_mac)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *ivp;
+ int i;
+
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
+ outbuf[i] = inbuf[i] ^ *ivp++;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ do_padlock (ctx, 0, outbuf, outbuf);
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ do_aesni (ctx, 0, outbuf, outbuf);
+#endif /*USE_AESNI*/
+ else
+ do_encrypt (ctx, outbuf, outbuf );
+
+ memcpy (iv, outbuf, BLOCKSIZE);
+ inbuf += BLOCKSIZE;
+ if (!cbc_mac)
+ outbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+
+ _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk encryption of complete blocks in CTR mode. Caller needs to
+ make sure that CTR is aligned on a 16 byte boundary if AESNI; the
+ minimum alignment is for an u32. This function is only intended
+ for the bulk encryption feature of cipher.c. CTR is expected to be
+ of size BLOCKSIZE. */
+void
+_gcry_aes_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *p;
+ int i;
+
+ if (0)
+ ;
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks > 3 ; nblocks -= 4 )
+ {
+ do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf);
+ outbuf += 4*BLOCKSIZE;
+ inbuf += 4*BLOCKSIZE;
+ }
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_ctr (ctx, ctr, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ aesni_cleanup_2_4 ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ union { unsigned char x1[16]; u32 x32[4]; } tmp;
+
+ for ( ;nblocks; nblocks-- )
+ {
+ /* Encrypt the counter. */
+ do_encrypt_aligned (ctx, tmp.x1, ctr);
+ /* XOR the input with the encrypted counter and store in output. */
+ for (p=tmp.x1, i=0; i < BLOCKSIZE; i++)
+ *outbuf++ = (*p++ ^= *inbuf++);
+ /* Increment the counter. */
+ for (i = BLOCKSIZE; i > 0; i--)
+ {
+ ctr[i-1]++;
+ if (ctr[i-1])
+ break;
+ }
+ }
+ }
+
+ _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+\f
+/* Decrypt one block. A and B need to be aligned on a 4 byte boundary
+ and the decryption must have been prepared. A and B may be the
+ same. */
+static void
+do_decrypt_aligned (RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define rk (ctx->keyschdec)
+ int rounds = ctx->rounds;
+ int r;
+ union
+ {
+ u32 tempu32[4]; /* Force correct alignment. */
+ byte temp[4][4];
+ } u;
+
+
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[rounds][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]);
+
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]])
+ ^ *((u32_a_t*)T6[u.temp[3][1]])
+ ^ *((u32_a_t*)T7[u.temp[2][2]])
+ ^ *((u32_a_t*)T8[u.temp[1][3]]));
+ *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]])
+ ^ *((u32_a_t*)T6[u.temp[0][1]])
+ ^ *((u32_a_t*)T7[u.temp[3][2]])
+ ^ *((u32_a_t*)T8[u.temp[2][3]]));
+ *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]])
+ ^ *((u32_a_t*)T6[u.temp[1][1]])
+ ^ *((u32_a_t*)T7[u.temp[0][2]])
+ ^ *((u32_a_t*)T8[u.temp[3][3]]));
+ *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]])
+ ^ *((u32_a_t*)T6[u.temp[2][1]])
+ ^ *((u32_a_t*)T7[u.temp[1][2]])
+ ^ *((u32_a_t*)T8[u.temp[0][3]]));
+
+ for (r = rounds-1; r > 1; r--)
+ {
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]])
+ ^ *((u32_a_t*)T6[u.temp[3][1]])
+ ^ *((u32_a_t*)T7[u.temp[2][2]])
+ ^ *((u32_a_t*)T8[u.temp[1][3]]));
+ *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]])
+ ^ *((u32_a_t*)T6[u.temp[0][1]])
+ ^ *((u32_a_t*)T7[u.temp[3][2]])
+ ^ *((u32_a_t*)T8[u.temp[2][3]]));
+ *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]])
+ ^ *((u32_a_t*)T6[u.temp[1][1]])
+ ^ *((u32_a_t*)T7[u.temp[0][2]])
+ ^ *((u32_a_t*)T8[u.temp[3][3]]));
+ *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]])
+ ^ *((u32_a_t*)T6[u.temp[2][1]])
+ ^ *((u32_a_t*)T7[u.temp[1][2]])
+ ^ *((u32_a_t*)T8[u.temp[0][3]]));
+ }
+
+ /* Last round is special. */
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]);
+ b[ 0] = S5[u.temp[0][0]];
+ b[ 1] = S5[u.temp[3][1]];
+ b[ 2] = S5[u.temp[2][2]];
+ b[ 3] = S5[u.temp[1][3]];
+ b[ 4] = S5[u.temp[1][0]];
+ b[ 5] = S5[u.temp[0][1]];
+ b[ 6] = S5[u.temp[3][2]];
+ b[ 7] = S5[u.temp[2][3]];
+ b[ 8] = S5[u.temp[2][0]];
+ b[ 9] = S5[u.temp[1][1]];
+ b[10] = S5[u.temp[0][2]];
+ b[11] = S5[u.temp[3][3]];
+ b[12] = S5[u.temp[3][0]];
+ b[13] = S5[u.temp[2][1]];
+ b[14] = S5[u.temp[1][2]];
+ b[15] = S5[u.temp[0][3]];
+ *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]);
+ *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]);
+ *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]);
+ *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]);
+#undef rk
+}
+
+
+/* Decrypt one block. AX and BX may be the same. */
+static void
+do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
+{
+ if ( !ctx->decryption_prepared )
+ {
+ prepare_decryption ( ctx );
+ _gcry_burn_stack (64);
+ ctx->decryption_prepared = 1;
+ }
+
+ /* BX and AX are not necessary correctly aligned. Thus we might
+ need to copy them here. We try to align to a 16 bytes. */
+ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+ {
+ union
+ {
+ u32 dummy[4];
+ byte a[16] ATTR_ALIGNED_16;
+ } a;
+ union
+ {
+ u32 dummy[4];
+ byte b[16] ATTR_ALIGNED_16;
+ } b;
+
+ memcpy (a.a, ax, 16);
+ do_decrypt_aligned (ctx, b.b, a.a);
+ memcpy (bx, b.b, 16);
+ }
+ else
+ {
+ do_decrypt_aligned (ctx, bx, ax);
+ }
+}
+
+
+
+
+static void
+rijndael_decrypt (void *context, byte *b, const byte *a)
+{
+ RIJNDAEL_context *ctx = context;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ {
+ do_padlock (ctx, 1, b, a);
+ _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */);
+ }
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ do_aesni (ctx, 1, b, a);
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ do_decrypt (ctx, b, a);
+ _gcry_burn_stack (56+2*sizeof(int));
+ }
+}
+
+
+/* Bulk decryption of complete blocks in CFB mode. Caller needs to
+ make sure that IV is aligned on an unisgned lonhg boundary. This
+ function is only intended for the bulk encryption feature of
+ cipher.c. */
+void
+_gcry_aes_cfb_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *ivp;
+ unsigned char temp;
+ int i;
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ {
+ /* Fixme: Let Padlock do the CFBing. */
+ for ( ;nblocks; nblocks-- )
+ {
+ do_padlock (ctx, 0, iv, iv);
+ for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ }
+ }
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_cfb (ctx, 1, iv, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ for ( ;nblocks; nblocks-- )
+ {
+ do_encrypt_aligned (ctx, iv, iv);
+ for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
+ {
+ temp = *inbuf++;
+ *outbuf++ = *ivp ^ temp;
+ *ivp++ = temp;
+ }
+ }
+ }
+
+ _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk decryption of complete blocks in CBC mode. Caller needs to
+ make sure that IV is aligned on an unsigned long boundary. This
+ function is only intended for the bulk encryption feature of
+ cipher.c. */
+void
+_gcry_aes_cbc_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *ivp;
+ int i;
+ unsigned char savebuf[BLOCKSIZE];
+
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ /* We need to save INBUF away because it may be identical to
+ OUTBUF. */
+ memcpy (savebuf, inbuf, BLOCKSIZE);
+
+ if (0)
+ ;
+#ifdef USE_PADLOCK
+ else if (ctx->use_padlock)
+ do_padlock (ctx, 1, outbuf, inbuf);
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ do_aesni (ctx, 1, outbuf, inbuf);
+#endif /*USE_AESNI*/
+ else
+ do_decrypt (ctx, outbuf, inbuf);
+
+ for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
+ outbuf[i] ^= *ivp++;
+ memcpy (iv, savebuf, BLOCKSIZE);
+ inbuf += BLOCKSIZE;
+ outbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+
+ _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*));
+}
+
+
+
+\f
+/* Run the self-tests for AES 128. Returns NULL on success. */
+static const char*
+selftest_basic_128 (void)
+{
+ RIJNDAEL_context ctx;
+ unsigned char scratch[16];
+
+ /* The test vectors are from the AES supplied ones; more or less
+ randomly taken from ecb_tbl.txt (I=42,81,14) */
+#if 1
+ static const unsigned char plaintext_128[16] =
+ {
+ 0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,
+ 0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A
+ };
+ static const unsigned char key_128[16] =
+ {
+ 0xE8,0xE9,0xEA,0xEB,0xED,0xEE,0xEF,0xF0,
+ 0xF2,0xF3,0xF4,0xF5,0xF7,0xF8,0xF9,0xFA
+ };
+ static const unsigned char ciphertext_128[16] =
+ {
+ 0x67,0x43,0xC3,0xD1,0x51,0x9A,0xB4,0xF2,
+ 0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD
+ };
+#else
+ /* Test vectors from fips-197, appendix C. */
+# warning debug test vectors in use
+ static const unsigned char plaintext_128[16] =
+ {
+ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
+ 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
+ };
+ static const unsigned char key_128[16] =
+ {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ /* 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, */
+ /* 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c */
+ };
+ static const unsigned char ciphertext_128[16] =
+ {
+ 0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30,
+ 0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a
+ };
+#endif
+
+ rijndael_setkey (&ctx, key_128, sizeof (key_128));
+ rijndael_encrypt (&ctx, scratch, plaintext_128);
+ if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
+ return "AES-128 test encryption failed.";
+ rijndael_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
+ return "AES-128 test decryption failed.";
+
+ return NULL;
+}
+
+/* Run the self-tests for AES 192. Returns NULL on success. */
+static const char*
+selftest_basic_192 (void)
+{
+ RIJNDAEL_context ctx;
+ unsigned char scratch[16];
+
+ static unsigned char plaintext_192[16] =
+ {
+ 0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4,
+ 0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72
+ };
+ static unsigned char key_192[24] =
+ {
+ 0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,
+ 0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,
+ 0x18,0x19,0x1A,0x1B,0x1D,0x1E,0x1F,0x20
+ };
+ static const unsigned char ciphertext_192[16] =
+ {
+ 0x5D,0x1E,0xF2,0x0D,0xCE,0xD6,0xBC,0xBC,
+ 0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
+ };
+
+ rijndael_setkey (&ctx, key_192, sizeof(key_192));
+ rijndael_encrypt (&ctx, scratch, plaintext_192);
+ if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
+ return "AES-192 test encryption failed.";
+ rijndael_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
+ return "AES-192 test decryption failed.";
+
+ return NULL;
+}
+
+
+/* Run the self-tests for AES 256. Returns NULL on success. */
+static const char*
+selftest_basic_256 (void)
+{
+ RIJNDAEL_context ctx;
+ unsigned char scratch[16];
+
+ static unsigned char plaintext_256[16] =
+ {
+ 0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+ 0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
+ };
+ static unsigned char key_256[32] =
+ {
+ 0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,
+ 0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,
+ 0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,
+ 0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E
+ };
+ static const unsigned char ciphertext_256[16] =
+ {
+ 0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,
+ 0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
+ };
+
+ rijndael_setkey (&ctx, key_256, sizeof(key_256));
+ rijndael_encrypt (&ctx, scratch, plaintext_256);
+ if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+ return "AES-256 test encryption failed.";
+ rijndael_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+ return "AES-256 test decryption failed.";
+
+ return NULL;
+}
+
+/* Run all the self-tests and return NULL on success. This function
+ is used for the on-the-fly self-tests. */
+static const char *
+selftest (void)
+{
+ const char *r;
+
+ if ( (r = selftest_basic_128 ())
+ || (r = selftest_basic_192 ())
+ || (r = selftest_basic_256 ()) )
+ return r;
+
+ return r;
+}
+
+
+/* SP800-38a.pdf for AES-128. */
+static const char *
+selftest_fips_128_38a (int requested_mode)
+{
+ struct tv
+ {
+ int mode;
+ const unsigned char key[16];
+ const unsigned char iv[16];
+ struct
+ {
+ const unsigned char input[16];
+ const unsigned char output[16];
+ } data[4];
+ } tv[2] =
+ {
+ {
+ GCRY_CIPHER_MODE_CFB, /* F.3.13, CFB128-AES128 */
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ {
+ { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+ { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+
+ { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+ { 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
+ 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } },
+
+ { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+ { 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40,
+ 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } },
+
+ { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ { 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e,
+ 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6 } }
+ }
+ },
+ {
+ GCRY_CIPHER_MODE_OFB,
+ { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ {
+ { { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+ { 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
+
+ { { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
+ 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
+ { 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
+ 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } },
+
+ { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+ 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
+ { 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
+ 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc } },
+
+ { { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+ 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+ { 0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78,
+ 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e } },
+ }
+ }
+ };
+ unsigned char scratch[16];
+ gpg_error_t err;
+ int tvi, idx;
+ gcry_cipher_hd_t hdenc = NULL;
+ gcry_cipher_hd_t hddec = NULL;
+
+#define Fail(a) do { \
+ _gcry_cipher_close (hdenc); \
+ _gcry_cipher_close (hddec); \
+ return a; \
+ } while (0)
+
+ gcry_assert (sizeof tv[0].data[0].input == sizeof scratch);
+ gcry_assert (sizeof tv[0].data[0].output == sizeof scratch);
+
+ for (tvi=0; tvi < DIM (tv); tvi++)
+ if (tv[tvi].mode == requested_mode)
+ break;
+ if (tvi == DIM (tv))
+ Fail ("no test data for this mode");
+
+ err = _gcry_cipher_open (&hdenc, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+ if (err)
+ Fail ("open");
+ err = _gcry_cipher_open (&hddec, GCRY_CIPHER_AES, tv[tvi].mode, 0);
+ if (err)
+ Fail ("open");
+ err = _gcry_cipher_setkey (hdenc, tv[tvi].key, sizeof tv[tvi].key);
+ if (!err)
+ err = _gcry_cipher_setkey (hddec, tv[tvi].key, sizeof tv[tvi].key);
+ if (err)
+ Fail ("set key");
+ err = _gcry_cipher_setiv (hdenc, tv[tvi].iv, sizeof tv[tvi].iv);
+ if (!err)
+ err = _gcry_cipher_setiv (hddec, tv[tvi].iv, sizeof tv[tvi].iv);
+ if (err)
+ Fail ("set IV");
+ for (idx=0; idx < DIM (tv[tvi].data); idx++)
+ {
+ err = _gcry_cipher_encrypt (hdenc, scratch, sizeof scratch,
+ tv[tvi].data[idx].input,
+ sizeof tv[tvi].data[idx].input);
+ if (err)
+ Fail ("encrypt command");
+ if (memcmp (scratch, tv[tvi].data[idx].output, sizeof scratch))
+ Fail ("encrypt mismatch");
+ err = _gcry_cipher_decrypt (hddec, scratch, sizeof scratch,
+ tv[tvi].data[idx].output,
+ sizeof tv[tvi].data[idx].output);
+ if (err)
+ Fail ("decrypt command");
+ if (memcmp (scratch, tv[tvi].data[idx].input, sizeof scratch))
+ Fail ("decrypt mismatch");
+ }
+
+#undef Fail
+ _gcry_cipher_close (hdenc);
+ _gcry_cipher_close (hddec);
+ return NULL;
+}
+
+
+/* Complete selftest for AES-128 with all modes and driver code. */
+static gpg_err_code_t
+selftest_fips_128 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "low-level";
+ errtxt = selftest_basic_128 ();
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "cfb";
+ errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB);
+ if (errtxt)
+ goto failed;
+
+ what = "ofb";
+ errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES128, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+/* Complete selftest for AES-192. */
+static gpg_err_code_t
+selftest_fips_192 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ (void)extended; /* No extended tests available. */
+
+ what = "low-level";
+ errtxt = selftest_basic_192 ();
+ if (errtxt)
+ goto failed;
+
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES192, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Complete selftest for AES-256. */
+static gpg_err_code_t
+selftest_fips_256 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ (void)extended; /* No extended tests available. */
+
+ what = "low-level";
+ errtxt = selftest_basic_256 ();
+ if (errtxt)
+ goto failed;
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("cipher", GCRY_CIPHER_AES256, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_CIPHER_AES128:
+ ec = selftest_fips_128 (extended, report);
+ break;
+ case GCRY_CIPHER_AES192:
+ ec = selftest_fips_192 (extended, report);
+ break;
+ case GCRY_CIPHER_AES256:
+ ec = selftest_fips_256 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_CIPHER_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+\f
+
+static const char *rijndael_names[] =
+ {
+ "RIJNDAEL",
+ "AES128",
+ "AES-128",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.1", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.2", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.3", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.4", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes =
+ {
+ "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+ };
+cipher_extra_spec_t _gcry_cipher_extraspec_aes =
+ {
+ run_selftests
+ };
+
+static const char *rijndael192_names[] =
+ {
+ "RIJNDAEL192",
+ "AES-192",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael192_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.21", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.22", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.23", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.24", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes192 =
+ {
+ "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+ };
+cipher_extra_spec_t _gcry_cipher_extraspec_aes192 =
+ {
+ run_selftests
+ };
+
+static const char *rijndael256_names[] =
+ {
+ "RIJNDAEL256",
+ "AES-256",
+ NULL
+ };
+
+static gcry_cipher_oid_spec_t rijndael256_oids[] =
+ {
+ { "2.16.840.1.101.3.4.1.41", GCRY_CIPHER_MODE_ECB },
+ { "2.16.840.1.101.3.4.1.42", GCRY_CIPHER_MODE_CBC },
+ { "2.16.840.1.101.3.4.1.43", GCRY_CIPHER_MODE_OFB },
+ { "2.16.840.1.101.3.4.1.44", GCRY_CIPHER_MODE_CFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_aes256 =
+ {
+ "AES256", rijndael256_names, rijndael256_oids, 16, 256,
+ sizeof (RIJNDAEL_context),
+ rijndael_setkey, rijndael_encrypt, rijndael_decrypt
+ };
+
+cipher_extra_spec_t _gcry_cipher_extraspec_aes256 =
+ {
+ run_selftests
+ };
--- /dev/null
+/* rmd.h - RIPE-MD hash functions
+ * Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_RMD_H
+#define G10_RMD_H
+
+
+/* We need this here because random.c must have direct access. */
+typedef struct
+{
+ u32 h0,h1,h2,h3,h4;
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} RMD160_CONTEXT;
+
+void _gcry_rmd160_init ( void *context );
+void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
+
+#endif /*G10_RMD_H*/
--- /dev/null
+/* rmd160.c - RIPE-MD160
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "rmd.h"
+#include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
+
+#include "bithelp.h"
+
+/*********************************
+ * RIPEMD-160 is not patented, see (as of 25.10.97)
+ * http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html
+ * Note that the code uses Little Endian byteorder, which is good for
+ * 386 etc, but we must add some conversion when used on a big endian box.
+ *
+ *
+ * Pseudo-code for RIPEMD-160
+ *
+ * RIPEMD-160 is an iterative hash function that operates on 32-bit words.
+ * The round function takes as input a 5-word chaining variable and a 16-word
+ * message block and maps this to a new chaining variable. All operations are
+ * defined on 32-bit words. Padding is identical to that of MD4.
+ *
+ *
+ * RIPEMD-160: definitions
+ *
+ *
+ * nonlinear functions at bit level: exor, mux, -, mux, -
+ *
+ * f(j, x, y, z) = x XOR y XOR z (0 <= j <= 15)
+ * f(j, x, y, z) = (x AND y) OR (NOT(x) AND z) (16 <= j <= 31)
+ * f(j, x, y, z) = (x OR NOT(y)) XOR z (32 <= j <= 47)
+ * f(j, x, y, z) = (x AND z) OR (y AND NOT(z)) (48 <= j <= 63)
+ * f(j, x, y, z) = x XOR (y OR NOT(z)) (64 <= j <= 79)
+ *
+ *
+ * added constants (hexadecimal)
+ *
+ * K(j) = 0x00000000 (0 <= j <= 15)
+ * K(j) = 0x5A827999 (16 <= j <= 31) int(2**30 x sqrt(2))
+ * K(j) = 0x6ED9EBA1 (32 <= j <= 47) int(2**30 x sqrt(3))
+ * K(j) = 0x8F1BBCDC (48 <= j <= 63) int(2**30 x sqrt(5))
+ * K(j) = 0xA953FD4E (64 <= j <= 79) int(2**30 x sqrt(7))
+ * K'(j) = 0x50A28BE6 (0 <= j <= 15) int(2**30 x cbrt(2))
+ * K'(j) = 0x5C4DD124 (16 <= j <= 31) int(2**30 x cbrt(3))
+ * K'(j) = 0x6D703EF3 (32 <= j <= 47) int(2**30 x cbrt(5))
+ * K'(j) = 0x7A6D76E9 (48 <= j <= 63) int(2**30 x cbrt(7))
+ * K'(j) = 0x00000000 (64 <= j <= 79)
+ *
+ *
+ * selection of message word
+ *
+ * r(j) = j (0 <= j <= 15)
+ * r(16..31) = 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8
+ * r(32..47) = 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12
+ * r(48..63) = 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2
+ * r(64..79) = 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+ * r0(0..15) = 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12
+ * r0(16..31)= 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2
+ * r0(32..47)= 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13
+ * r0(48..63)= 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14
+ * r0(64..79)= 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+ *
+ *
+ * amount for rotate left (rol)
+ *
+ * s(0..15) = 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8
+ * s(16..31) = 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12
+ * s(32..47) = 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5
+ * s(48..63) = 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12
+ * s(64..79) = 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+ * s'(0..15) = 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6
+ * s'(16..31)= 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11
+ * s'(32..47)= 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5
+ * s'(48..63)= 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8
+ * s'(64..79)= 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+ *
+ *
+ * initial value (hexadecimal)
+ *
+ * h0 = 0x67452301; h1 = 0xEFCDAB89; h2 = 0x98BADCFE; h3 = 0x10325476;
+ * h4 = 0xC3D2E1F0;
+ *
+ *
+ * RIPEMD-160: pseudo-code
+ *
+ * It is assumed that the message after padding consists of t 16-word blocks
+ * that will be denoted with X[i][j], with 0 <= i <= t-1 and 0 <= j <= 15.
+ * The symbol [+] denotes addition modulo 2**32 and rol_s denotes cyclic left
+ * shift (rotate) over s positions.
+ *
+ *
+ * for i := 0 to t-1 {
+ * A := h0; B := h1; C := h2; D = h3; E = h4;
+ * A' := h0; B' := h1; C' := h2; D' = h3; E' = h4;
+ * for j := 0 to 79 {
+ * T := rol_s(j)(A [+] f(j, B, C, D) [+] X[i][r(j)] [+] K(j)) [+] E;
+ * A := E; E := D; D := rol_10(C); C := B; B := T;
+ * T := rol_s'(j)(A' [+] f(79-j, B', C', D') [+] X[i][r'(j)]
+ [+] K'(j)) [+] E';
+ * A' := E'; E' := D'; D' := rol_10(C'); C' := B'; B' := T;
+ * }
+ * T := h1 [+] C [+] D'; h1 := h2 [+] D [+] E'; h2 := h3 [+] E [+] A';
+ * h3 := h4 [+] A [+] B'; h4 := h0 [+] B [+] C'; h0 := T;
+ * }
+ */
+
+/* Some examples:
+ * "" 9c1185a5c5e9fc54612808977ee8f548b2258d31
+ * "a" 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe
+ * "abc" 8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
+ * "message digest" 5d0689ef49d2fae572b881b123a85ffa21595f36
+ * "a...z" f71c27109c692c1b56bbdceb5b9d2865b3708dbc
+ * "abcdbcde...nopq" 12a053384a9c0c88e405a06c27dcf49ada62eb2b
+ * "A...Za...z0...9" b0e20b6e3116640286ed3a87a5713079b21f5189
+ * 8 times "1234567890" 9b752e45573d4b39f4dbd3323cab82bf63326bfb
+ * 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
+ */
+
+
+void
+_gcry_rmd160_init (void *context)
+{
+ RMD160_CONTEXT *hd = context;
+
+ hd->h0 = 0x67452301;
+ hd->h1 = 0xEFCDAB89;
+ hd->h2 = 0x98BADCFE;
+ hd->h3 = 0x10325476;
+ hd->h4 = 0xC3D2E1F0;
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+
+
+/****************
+ * Transform the message X which consists of 16 32-bit-words
+ */
+static void
+transform ( RMD160_CONTEXT *hd, const unsigned char *data )
+{
+ register u32 a,b,c,d,e;
+ u32 aa,bb,cc,dd,ee,t;
+#ifdef WORDS_BIGENDIAN
+ u32 x[16];
+ {
+ int i;
+ byte *p2, *p1;
+ for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *p1++;
+ p2[2] = *p1++;
+ p2[1] = *p1++;
+ p2[0] = *p1++;
+ }
+ }
+#else
+ /* This version is better because it is always aligned;
+ * The performance penalty on a 586-100 is about 6% which
+ * is acceptable - because the data is more local it might
+ * also be possible that this is faster on some machines.
+ * This function (when compiled with -02 on gcc 2.7.2)
+ * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
+ * [measured with a 4MB data and "gpgm --print-md rmd160"] */
+ u32 x[16];
+ memcpy( x, data, 64 );
+#endif
+
+
+#define K0 0x00000000
+#define K1 0x5A827999
+#define K2 0x6ED9EBA1
+#define K3 0x8F1BBCDC
+#define K4 0xA953FD4E
+#define KK0 0x50A28BE6
+#define KK1 0x5C4DD124
+#define KK2 0x6D703EF3
+#define KK3 0x7A6D76E9
+#define KK4 0x00000000
+#define F0(x,y,z) ( (x) ^ (y) ^ (z) )
+#define F1(x,y,z) ( ((x) & (y)) | (~(x) & (z)) )
+#define F2(x,y,z) ( ((x) | ~(y)) ^ (z) )
+#define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) )
+#define F4(x,y,z) ( (x) ^ ((y) | ~(z)) )
+#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \
+ a = rol(t,s) + e; \
+ c = rol(c,10); \
+ } while(0)
+
+ /* left lane */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ R( a, b, c, d, e, F0, K0, 0, 11 );
+ R( e, a, b, c, d, F0, K0, 1, 14 );
+ R( d, e, a, b, c, F0, K0, 2, 15 );
+ R( c, d, e, a, b, F0, K0, 3, 12 );
+ R( b, c, d, e, a, F0, K0, 4, 5 );
+ R( a, b, c, d, e, F0, K0, 5, 8 );
+ R( e, a, b, c, d, F0, K0, 6, 7 );
+ R( d, e, a, b, c, F0, K0, 7, 9 );
+ R( c, d, e, a, b, F0, K0, 8, 11 );
+ R( b, c, d, e, a, F0, K0, 9, 13 );
+ R( a, b, c, d, e, F0, K0, 10, 14 );
+ R( e, a, b, c, d, F0, K0, 11, 15 );
+ R( d, e, a, b, c, F0, K0, 12, 6 );
+ R( c, d, e, a, b, F0, K0, 13, 7 );
+ R( b, c, d, e, a, F0, K0, 14, 9 );
+ R( a, b, c, d, e, F0, K0, 15, 8 );
+ R( e, a, b, c, d, F1, K1, 7, 7 );
+ R( d, e, a, b, c, F1, K1, 4, 6 );
+ R( c, d, e, a, b, F1, K1, 13, 8 );
+ R( b, c, d, e, a, F1, K1, 1, 13 );
+ R( a, b, c, d, e, F1, K1, 10, 11 );
+ R( e, a, b, c, d, F1, K1, 6, 9 );
+ R( d, e, a, b, c, F1, K1, 15, 7 );
+ R( c, d, e, a, b, F1, K1, 3, 15 );
+ R( b, c, d, e, a, F1, K1, 12, 7 );
+ R( a, b, c, d, e, F1, K1, 0, 12 );
+ R( e, a, b, c, d, F1, K1, 9, 15 );
+ R( d, e, a, b, c, F1, K1, 5, 9 );
+ R( c, d, e, a, b, F1, K1, 2, 11 );
+ R( b, c, d, e, a, F1, K1, 14, 7 );
+ R( a, b, c, d, e, F1, K1, 11, 13 );
+ R( e, a, b, c, d, F1, K1, 8, 12 );
+ R( d, e, a, b, c, F2, K2, 3, 11 );
+ R( c, d, e, a, b, F2, K2, 10, 13 );
+ R( b, c, d, e, a, F2, K2, 14, 6 );
+ R( a, b, c, d, e, F2, K2, 4, 7 );
+ R( e, a, b, c, d, F2, K2, 9, 14 );
+ R( d, e, a, b, c, F2, K2, 15, 9 );
+ R( c, d, e, a, b, F2, K2, 8, 13 );
+ R( b, c, d, e, a, F2, K2, 1, 15 );
+ R( a, b, c, d, e, F2, K2, 2, 14 );
+ R( e, a, b, c, d, F2, K2, 7, 8 );
+ R( d, e, a, b, c, F2, K2, 0, 13 );
+ R( c, d, e, a, b, F2, K2, 6, 6 );
+ R( b, c, d, e, a, F2, K2, 13, 5 );
+ R( a, b, c, d, e, F2, K2, 11, 12 );
+ R( e, a, b, c, d, F2, K2, 5, 7 );
+ R( d, e, a, b, c, F2, K2, 12, 5 );
+ R( c, d, e, a, b, F3, K3, 1, 11 );
+ R( b, c, d, e, a, F3, K3, 9, 12 );
+ R( a, b, c, d, e, F3, K3, 11, 14 );
+ R( e, a, b, c, d, F3, K3, 10, 15 );
+ R( d, e, a, b, c, F3, K3, 0, 14 );
+ R( c, d, e, a, b, F3, K3, 8, 15 );
+ R( b, c, d, e, a, F3, K3, 12, 9 );
+ R( a, b, c, d, e, F3, K3, 4, 8 );
+ R( e, a, b, c, d, F3, K3, 13, 9 );
+ R( d, e, a, b, c, F3, K3, 3, 14 );
+ R( c, d, e, a, b, F3, K3, 7, 5 );
+ R( b, c, d, e, a, F3, K3, 15, 6 );
+ R( a, b, c, d, e, F3, K3, 14, 8 );
+ R( e, a, b, c, d, F3, K3, 5, 6 );
+ R( d, e, a, b, c, F3, K3, 6, 5 );
+ R( c, d, e, a, b, F3, K3, 2, 12 );
+ R( b, c, d, e, a, F4, K4, 4, 9 );
+ R( a, b, c, d, e, F4, K4, 0, 15 );
+ R( e, a, b, c, d, F4, K4, 5, 5 );
+ R( d, e, a, b, c, F4, K4, 9, 11 );
+ R( c, d, e, a, b, F4, K4, 7, 6 );
+ R( b, c, d, e, a, F4, K4, 12, 8 );
+ R( a, b, c, d, e, F4, K4, 2, 13 );
+ R( e, a, b, c, d, F4, K4, 10, 12 );
+ R( d, e, a, b, c, F4, K4, 14, 5 );
+ R( c, d, e, a, b, F4, K4, 1, 12 );
+ R( b, c, d, e, a, F4, K4, 3, 13 );
+ R( a, b, c, d, e, F4, K4, 8, 14 );
+ R( e, a, b, c, d, F4, K4, 11, 11 );
+ R( d, e, a, b, c, F4, K4, 6, 8 );
+ R( c, d, e, a, b, F4, K4, 15, 5 );
+ R( b, c, d, e, a, F4, K4, 13, 6 );
+
+ aa = a; bb = b; cc = c; dd = d; ee = e;
+
+ /* right lane */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ R( a, b, c, d, e, F4, KK0, 5, 8);
+ R( e, a, b, c, d, F4, KK0, 14, 9);
+ R( d, e, a, b, c, F4, KK0, 7, 9);
+ R( c, d, e, a, b, F4, KK0, 0, 11);
+ R( b, c, d, e, a, F4, KK0, 9, 13);
+ R( a, b, c, d, e, F4, KK0, 2, 15);
+ R( e, a, b, c, d, F4, KK0, 11, 15);
+ R( d, e, a, b, c, F4, KK0, 4, 5);
+ R( c, d, e, a, b, F4, KK0, 13, 7);
+ R( b, c, d, e, a, F4, KK0, 6, 7);
+ R( a, b, c, d, e, F4, KK0, 15, 8);
+ R( e, a, b, c, d, F4, KK0, 8, 11);
+ R( d, e, a, b, c, F4, KK0, 1, 14);
+ R( c, d, e, a, b, F4, KK0, 10, 14);
+ R( b, c, d, e, a, F4, KK0, 3, 12);
+ R( a, b, c, d, e, F4, KK0, 12, 6);
+ R( e, a, b, c, d, F3, KK1, 6, 9);
+ R( d, e, a, b, c, F3, KK1, 11, 13);
+ R( c, d, e, a, b, F3, KK1, 3, 15);
+ R( b, c, d, e, a, F3, KK1, 7, 7);
+ R( a, b, c, d, e, F3, KK1, 0, 12);
+ R( e, a, b, c, d, F3, KK1, 13, 8);
+ R( d, e, a, b, c, F3, KK1, 5, 9);
+ R( c, d, e, a, b, F3, KK1, 10, 11);
+ R( b, c, d, e, a, F3, KK1, 14, 7);
+ R( a, b, c, d, e, F3, KK1, 15, 7);
+ R( e, a, b, c, d, F3, KK1, 8, 12);
+ R( d, e, a, b, c, F3, KK1, 12, 7);
+ R( c, d, e, a, b, F3, KK1, 4, 6);
+ R( b, c, d, e, a, F3, KK1, 9, 15);
+ R( a, b, c, d, e, F3, KK1, 1, 13);
+ R( e, a, b, c, d, F3, KK1, 2, 11);
+ R( d, e, a, b, c, F2, KK2, 15, 9);
+ R( c, d, e, a, b, F2, KK2, 5, 7);
+ R( b, c, d, e, a, F2, KK2, 1, 15);
+ R( a, b, c, d, e, F2, KK2, 3, 11);
+ R( e, a, b, c, d, F2, KK2, 7, 8);
+ R( d, e, a, b, c, F2, KK2, 14, 6);
+ R( c, d, e, a, b, F2, KK2, 6, 6);
+ R( b, c, d, e, a, F2, KK2, 9, 14);
+ R( a, b, c, d, e, F2, KK2, 11, 12);
+ R( e, a, b, c, d, F2, KK2, 8, 13);
+ R( d, e, a, b, c, F2, KK2, 12, 5);
+ R( c, d, e, a, b, F2, KK2, 2, 14);
+ R( b, c, d, e, a, F2, KK2, 10, 13);
+ R( a, b, c, d, e, F2, KK2, 0, 13);
+ R( e, a, b, c, d, F2, KK2, 4, 7);
+ R( d, e, a, b, c, F2, KK2, 13, 5);
+ R( c, d, e, a, b, F1, KK3, 8, 15);
+ R( b, c, d, e, a, F1, KK3, 6, 5);
+ R( a, b, c, d, e, F1, KK3, 4, 8);
+ R( e, a, b, c, d, F1, KK3, 1, 11);
+ R( d, e, a, b, c, F1, KK3, 3, 14);
+ R( c, d, e, a, b, F1, KK3, 11, 14);
+ R( b, c, d, e, a, F1, KK3, 15, 6);
+ R( a, b, c, d, e, F1, KK3, 0, 14);
+ R( e, a, b, c, d, F1, KK3, 5, 6);
+ R( d, e, a, b, c, F1, KK3, 12, 9);
+ R( c, d, e, a, b, F1, KK3, 2, 12);
+ R( b, c, d, e, a, F1, KK3, 13, 9);
+ R( a, b, c, d, e, F1, KK3, 9, 12);
+ R( e, a, b, c, d, F1, KK3, 7, 5);
+ R( d, e, a, b, c, F1, KK3, 10, 15);
+ R( c, d, e, a, b, F1, KK3, 14, 8);
+ R( b, c, d, e, a, F0, KK4, 12, 8);
+ R( a, b, c, d, e, F0, KK4, 15, 5);
+ R( e, a, b, c, d, F0, KK4, 10, 12);
+ R( d, e, a, b, c, F0, KK4, 4, 9);
+ R( c, d, e, a, b, F0, KK4, 1, 12);
+ R( b, c, d, e, a, F0, KK4, 5, 5);
+ R( a, b, c, d, e, F0, KK4, 8, 14);
+ R( e, a, b, c, d, F0, KK4, 7, 6);
+ R( d, e, a, b, c, F0, KK4, 6, 8);
+ R( c, d, e, a, b, F0, KK4, 2, 13);
+ R( b, c, d, e, a, F0, KK4, 13, 6);
+ R( a, b, c, d, e, F0, KK4, 14, 5);
+ R( e, a, b, c, d, F0, KK4, 0, 15);
+ R( d, e, a, b, c, F0, KK4, 3, 13);
+ R( c, d, e, a, b, F0, KK4, 9, 11);
+ R( b, c, d, e, a, F0, KK4, 11, 11);
+
+
+ t = hd->h1 + d + cc;
+ hd->h1 = hd->h2 + e + dd;
+ hd->h2 = hd->h3 + a + ee;
+ hd->h3 = hd->h4 + b + aa;
+ hd->h4 = hd->h0 + c + bb;
+ hd->h0 = t;
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ RMD160_CONTEXT *hd = context;
+
+ if( hd->count == 64 ) /* flush the buffer */
+ {
+ transform( hd, hd->buf );
+ _gcry_burn_stack (108+5*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+ if( hd->count )
+ {
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ rmd160_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+
+ while( inlen >= 64 )
+ {
+ transform( hd, inbuf );
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ _gcry_burn_stack (108+5*sizeof(void*));
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+/****************
+ * Apply the rmd160 transform function on the buffer which must have
+ * a length 64 bytes. Do not use this function together with the
+ * other functions, use rmd160_init to initialize internal variables.
+ * Returns: 16 bytes in buffer with the mixed contentes of buffer.
+ */
+void
+_gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte )
+{
+ char *p = blockof64byte;
+
+ transform ( hd, blockof64byte );
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+}
+
+
+/* The routine terminates the computation
+ */
+
+static void
+rmd160_final( void *context )
+{
+ RMD160_CONTEXT *hd = context;
+ u32 t, msb, lsb;
+ byte *p;
+
+ rmd160_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) /* enough room */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else /* need one extra block */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ rmd160_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform( hd, hd->buf );
+ _gcry_burn_stack (108+5*sizeof(void*));
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
+ *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
+#else /* little endian */
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#endif
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+}
+
+static byte *
+rmd160_read( void *context )
+{
+ RMD160_CONTEXT *hd = context;
+
+ return hd->buf;
+}
+
+
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
+{
+ RMD160_CONTEXT hd;
+
+ _gcry_rmd160_init ( &hd );
+ rmd160_write ( &hd, buffer, length );
+ rmd160_final ( &hd );
+ memcpy ( outbuf, hd.buf, 20 );
+}
+
+static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
+ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03,
+ 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_rmd160[] =
+ {
+ /* rsaSignatureWithripemd160 */
+ { "1.3.36.3.3.1.2" },
+ /* TeleTrust hash algorithm. */
+ { "1.3.36.3.2.1" },
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_rmd160 =
+ {
+ "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
+ _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
+ sizeof (RMD160_CONTEXT)
+ };
--- /dev/null
+/* rsa.c - RSA implementation
+ * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn)
+ * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This code uses an algorithm protected by U.S. Patent #4,405,829
+ which expired on September 20, 2000. The patent holder placed that
+ patent into the public domain on Sep 6th, 2000.
+*/
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+
+
+typedef struct
+{
+ gcry_mpi_t n; /* modulus */
+ gcry_mpi_t e; /* exponent */
+} RSA_public_key;
+
+
+typedef struct
+{
+ gcry_mpi_t n; /* public modulus */
+ gcry_mpi_t e; /* public exponent */
+ gcry_mpi_t d; /* exponent */
+ gcry_mpi_t p; /* prime p. */
+ gcry_mpi_t q; /* prime q. */
+ gcry_mpi_t u; /* inverse of p mod q. */
+} RSA_secret_key;
+
+
+/* A sample 1024 bit RSA key used for the selftests. */
+static const char sample_secret_key[] =
+"(private-key"
+" (rsa"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
+" (e #010001#)"
+" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11"
+" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd"
+" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21"
+" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)"
+" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
+/* A sample 1024 bit RSA key used for the selftests (public only). */
+static const char sample_public_key[] =
+"(public-key"
+" (rsa"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
+" (e #010001#)))";
+
+
+
+\f
+static int test_keys (RSA_secret_key *sk, unsigned nbits);
+static int check_secret_key (RSA_secret_key *sk);
+static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
+static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
+
+
+/* Check that a freshly generated key actually works. Returns 0 on success. */
+static int
+test_keys (RSA_secret_key *sk, unsigned int nbits)
+{
+ int result = -1; /* Default to failure. */
+ RSA_public_key pk;
+ gcry_mpi_t plaintext = gcry_mpi_new (nbits);
+ gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
+ gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
+ gcry_mpi_t signature = gcry_mpi_new (nbits);
+
+ /* Put the relevant parameters into a public key structure. */
+ pk.n = sk->n;
+ pk.e = sk->e;
+
+ /* Create a random plaintext. */
+ gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+ /* Encrypt using the public key. */
+ public (ciphertext, plaintext, &pk);
+
+ /* Check that the cipher text does not match the plaintext. */
+ if (!gcry_mpi_cmp (ciphertext, plaintext))
+ goto leave; /* Ciphertext is identical to the plaintext. */
+
+ /* Decrypt using the secret key. */
+ secret (decr_plaintext, ciphertext, sk);
+
+ /* Check that the decrypted plaintext matches the original plaintext. */
+ if (gcry_mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Plaintext does not match. */
+
+ /* Create another random plaintext as data for signature checking. */
+ gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+ /* Use the RSA secret function to create a signature of the plaintext. */
+ secret (signature, plaintext, sk);
+
+ /* Use the RSA public function to verify this signature. */
+ public (decr_plaintext, signature, &pk);
+ if (gcry_mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Signature does not match. */
+
+ /* Modify the signature and check that the signing fails. */
+ gcry_mpi_add_ui (signature, signature, 1);
+ public (decr_plaintext, signature, &pk);
+ if (!gcry_mpi_cmp (decr_plaintext, plaintext))
+ goto leave; /* Signature matches but should not. */
+
+ result = 0; /* All tests succeeded. */
+
+ leave:
+ gcry_mpi_release (signature);
+ gcry_mpi_release (decr_plaintext);
+ gcry_mpi_release (ciphertext);
+ gcry_mpi_release (plaintext);
+ return result;
+}
+
+
+/* Callback used by the prime generation to test whether the exponent
+ is suitable. Returns 0 if the test has been passed. */
+static int
+check_exponent (void *arg, gcry_mpi_t a)
+{
+ gcry_mpi_t e = arg;
+ gcry_mpi_t tmp;
+ int result;
+
+ mpi_sub_ui (a, a, 1);
+ tmp = _gcry_mpi_alloc_like (a);
+ result = !gcry_mpi_gcd(tmp, e, a); /* GCD is not 1. */
+ gcry_mpi_release (tmp);
+ mpi_add_ui (a, a, 1);
+ return result;
+}
+
+/****************
+ * Generate a key pair with a key of size NBITS.
+ * USE_E = 0 let Libcgrypt decide what exponent to use.
+ * = 1 request the use of a "secure" exponent; this is required by some
+ * specification to be 65537.
+ * > 2 Use this public exponent. If the given exponent
+ * is not odd one is internally added to it.
+ * TRANSIENT_KEY: If true, generate the primes using the standard RNG.
+ * Returns: 2 structures filled with all needed values
+ */
+static gpg_err_code_t
+generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+ int transient_key)
+{
+ gcry_mpi_t p, q; /* the two primes */
+ gcry_mpi_t d; /* the private key */
+ gcry_mpi_t u;
+ gcry_mpi_t t1, t2;
+ gcry_mpi_t n; /* the public key */
+ gcry_mpi_t e; /* the exponent */
+ gcry_mpi_t phi; /* helper: (p-1)(q-1) */
+ gcry_mpi_t g;
+ gcry_mpi_t f;
+ gcry_random_level_t random_level;
+
+ if (fips_mode ())
+ {
+ if (nbits < 1024)
+ return GPG_ERR_INV_VALUE;
+ if (transient_key)
+ return GPG_ERR_INV_VALUE;
+ }
+
+ /* The random quality depends on the transient_key flag. */
+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
+ /* Make sure that nbits is even so that we generate p, q of equal size. */
+ if ( (nbits&1) )
+ nbits++;
+
+ if (use_e == 1) /* Alias for a secure value */
+ use_e = 65537; /* as demanded by Sphinx. */
+
+ /* Public exponent:
+ In general we use 41 as this is quite fast and more secure than the
+ commonly used 17. Benchmarking the RSA verify function
+ with a 1024 bit key yields (2001-11-08):
+ e=17 0.54 ms
+ e=41 0.75 ms
+ e=257 0.95 ms
+ e=65537 1.80 ms
+ */
+ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+ if (!use_e)
+ mpi_set_ui (e, 41); /* This is a reasonable secure and fast value */
+ else
+ {
+ use_e |= 1; /* make sure this is odd */
+ mpi_set_ui (e, use_e);
+ }
+
+ n = gcry_mpi_new (nbits);
+
+ p = q = NULL;
+ do
+ {
+ /* select two (very secret) primes */
+ if (p)
+ gcry_mpi_release (p);
+ if (q)
+ gcry_mpi_release (q);
+ if (use_e)
+ { /* Do an extra test to ensure that the given exponent is
+ suitable. */
+ p = _gcry_generate_secret_prime (nbits/2, random_level,
+ check_exponent, e);
+ q = _gcry_generate_secret_prime (nbits/2, random_level,
+ check_exponent, e);
+ }
+ else
+ { /* We check the exponent later. */
+ p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+ q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+ }
+ if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/
+ mpi_swap(p,q);
+ /* calculate the modulus */
+ mpi_mul( n, p, q );
+ }
+ while ( mpi_get_nbits(n) != nbits );
+
+ /* calculate Euler totient: phi = (p-1)(q-1) */
+ t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+ t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
+ phi = gcry_mpi_snew ( nbits );
+ g = gcry_mpi_snew ( nbits );
+ f = gcry_mpi_snew ( nbits );
+ mpi_sub_ui( t1, p, 1 );
+ mpi_sub_ui( t2, q, 1 );
+ mpi_mul( phi, t1, t2 );
+ gcry_mpi_gcd(g, t1, t2);
+ mpi_fdiv_q(f, phi, g);
+
+ while (!gcry_mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
+ {
+ if (use_e)
+ BUG (); /* The prime generator already made sure that we
+ never can get to here. */
+ mpi_add_ui (e, e, 2);
+ }
+
+ /* calculate the secret key d = e^1 mod phi */
+ d = gcry_mpi_snew ( nbits );
+ mpi_invm(d, e, f );
+ /* calculate the inverse of p and q (used for chinese remainder theorem)*/
+ u = gcry_mpi_snew ( nbits );
+ mpi_invm(u, p, q );
+
+ if( DBG_CIPHER )
+ {
+ log_mpidump(" p= ", p );
+ log_mpidump(" q= ", q );
+ log_mpidump("phi= ", phi );
+ log_mpidump(" g= ", g );
+ log_mpidump(" f= ", f );
+ log_mpidump(" n= ", n );
+ log_mpidump(" e= ", e );
+ log_mpidump(" d= ", d );
+ log_mpidump(" u= ", u );
+ }
+
+ gcry_mpi_release (t1);
+ gcry_mpi_release (t2);
+ gcry_mpi_release (phi);
+ gcry_mpi_release (f);
+ gcry_mpi_release (g);
+
+ sk->n = n;
+ sk->e = e;
+ sk->p = p;
+ sk->q = q;
+ sk->d = d;
+ sk->u = u;
+
+ /* Now we can test our keys. */
+ if (test_keys (sk, nbits - 64))
+ {
+ gcry_mpi_release (sk->n); sk->n = NULL;
+ gcry_mpi_release (sk->e); sk->e = NULL;
+ gcry_mpi_release (sk->p); sk->p = NULL;
+ gcry_mpi_release (sk->q); sk->q = NULL;
+ gcry_mpi_release (sk->d); sk->d = NULL;
+ gcry_mpi_release (sk->u); sk->u = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+
+ return 0;
+}
+
+
+/* Helper for generate_x931. */
+static gcry_mpi_t
+gen_x931_parm_xp (unsigned int nbits)
+{
+ gcry_mpi_t xp;
+
+ xp = gcry_mpi_snew (nbits);
+ gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
+
+ /* The requirement for Xp is:
+
+ sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
+
+ We set the two high order bits to 1 to satisfy the lower bound.
+ By using mpi_set_highbit we make sure that the upper bound is
+ satisfied as well. */
+ mpi_set_highbit (xp, nbits-1);
+ mpi_set_bit (xp, nbits-2);
+ gcry_assert ( mpi_get_nbits (xp) == nbits );
+
+ return xp;
+}
+
+
+/* Helper for generate_x931. */
+static gcry_mpi_t
+gen_x931_parm_xi (void)
+{
+ gcry_mpi_t xi;
+
+ xi = gcry_mpi_snew (101);
+ gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
+ mpi_set_highbit (xi, 100);
+ gcry_assert ( mpi_get_nbits (xi) == 101 );
+
+ return xi;
+}
+
+
+
+/* Variant of the standard key generation code using the algorithm
+ from X9.31. Using this algorithm has the advantage that the
+ generation can be made deterministic which is required for CAVS
+ testing. */
+static gpg_err_code_t
+generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
+ gcry_sexp_t deriveparms, int *swapped)
+{
+ gcry_mpi_t p, q; /* The two primes. */
+ gcry_mpi_t e; /* The public exponent. */
+ gcry_mpi_t n; /* The public key. */
+ gcry_mpi_t d; /* The private key */
+ gcry_mpi_t u; /* The inverse of p and q. */
+ gcry_mpi_t pm1; /* p - 1 */
+ gcry_mpi_t qm1; /* q - 1 */
+ gcry_mpi_t phi; /* Euler totient. */
+ gcry_mpi_t f, g; /* Helper. */
+
+ *swapped = 0;
+
+ if (e_value == 1) /* Alias for a secure value. */
+ e_value = 65537;
+
+ /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */
+ if (nbits < 1024 || (nbits % 256))
+ return GPG_ERR_INV_VALUE;
+
+ /* Point 2: 2 <= bitlength(e) < 2^{k-2}
+ Note that we do not need to check the upper bound because we use
+ an unsigned long for E and thus there is no way for E to reach
+ that limit. */
+ if (e_value < 3)
+ return GPG_ERR_INV_VALUE;
+
+ /* Our implementaion requires E to be odd. */
+ if (!(e_value & 1))
+ return GPG_ERR_INV_VALUE;
+
+ /* Point 3: e > 0 or e 0 if it is to be randomly generated.
+ We support only a fixed E and thus there is no need for an extra test. */
+
+
+ /* Compute or extract the derive parameters. */
+ {
+ gcry_mpi_t xp1 = NULL;
+ gcry_mpi_t xp2 = NULL;
+ gcry_mpi_t xp = NULL;
+ gcry_mpi_t xq1 = NULL;
+ gcry_mpi_t xq2 = NULL;
+ gcry_mpi_t xq = NULL;
+ gcry_mpi_t tmpval;
+
+ if (!deriveparms)
+ {
+ /* Not given: Generate them. */
+ xp = gen_x931_parm_xp (nbits/2);
+ /* Make sure that |xp - xq| > 2^{nbits - 100} holds. */
+ tmpval = gcry_mpi_snew (nbits/2);
+ do
+ {
+ gcry_mpi_release (xq);
+ xq = gen_x931_parm_xp (nbits/2);
+ mpi_sub (tmpval, xp, xq);
+ }
+ while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
+ gcry_mpi_release (tmpval);
+
+ xp1 = gen_x931_parm_xi ();
+ xp2 = gen_x931_parm_xi ();
+ xq1 = gen_x931_parm_xi ();
+ xq2 = gen_x931_parm_xi ();
+
+ }
+ else
+ {
+ /* Parameters to derive the key are given. */
+ /* Note that we explicitly need to setup the values of tbl
+ because some compilers (e.g. OpenWatcom, IRIX) don't allow
+ to initialize a structure with automatic variables. */
+ struct { const char *name; gcry_mpi_t *value; } tbl[] = {
+ { "Xp1" },
+ { "Xp2" },
+ { "Xp" },
+ { "Xq1" },
+ { "Xq2" },
+ { "Xq" },
+ { NULL }
+ };
+ int idx;
+ gcry_sexp_t oneparm;
+
+ tbl[0].value = &xp1;
+ tbl[1].value = &xp2;
+ tbl[2].value = &xp;
+ tbl[3].value = &xq1;
+ tbl[4].value = &xq2;
+ tbl[5].value = &xq;
+
+ for (idx=0; tbl[idx].name; idx++)
+ {
+ oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
+ if (oneparm)
+ {
+ *tbl[idx].value = gcry_sexp_nth_mpi (oneparm, 1,
+ GCRYMPI_FMT_USG);
+ gcry_sexp_release (oneparm);
+ }
+ }
+ for (idx=0; tbl[idx].name; idx++)
+ if (!*tbl[idx].value)
+ break;
+ if (tbl[idx].name)
+ {
+ /* At least one parameter is missing. */
+ for (idx=0; tbl[idx].name; idx++)
+ gcry_mpi_release (*tbl[idx].value);
+ return GPG_ERR_MISSING_VALUE;
+ }
+ }
+
+ e = mpi_alloc_set_ui (e_value);
+
+ /* Find two prime numbers. */
+ p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
+ q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL);
+ gcry_mpi_release (xp); xp = NULL;
+ gcry_mpi_release (xp1); xp1 = NULL;
+ gcry_mpi_release (xp2); xp2 = NULL;
+ gcry_mpi_release (xq); xq = NULL;
+ gcry_mpi_release (xq1); xq1 = NULL;
+ gcry_mpi_release (xq2); xq2 = NULL;
+ if (!p || !q)
+ {
+ gcry_mpi_release (p);
+ gcry_mpi_release (q);
+ gcry_mpi_release (e);
+ return GPG_ERR_NO_PRIME;
+ }
+ }
+
+
+ /* Compute the public modulus. We make sure that p is smaller than
+ q to allow the use of the CRT. */
+ if (mpi_cmp (p, q) > 0 )
+ {
+ mpi_swap (p, q);
+ *swapped = 1;
+ }
+ n = gcry_mpi_new (nbits);
+ mpi_mul (n, p, q);
+
+ /* Compute the Euler totient: phi = (p-1)(q-1) */
+ pm1 = gcry_mpi_snew (nbits/2);
+ qm1 = gcry_mpi_snew (nbits/2);
+ phi = gcry_mpi_snew (nbits);
+ mpi_sub_ui (pm1, p, 1);
+ mpi_sub_ui (qm1, q, 1);
+ mpi_mul (phi, pm1, qm1);
+
+ g = gcry_mpi_snew (nbits);
+ gcry_assert (gcry_mpi_gcd (g, e, phi));
+
+ /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
+ gcry_mpi_gcd (g, pm1, qm1);
+ f = pm1; pm1 = NULL;
+ gcry_mpi_release (qm1); qm1 = NULL;
+ mpi_fdiv_q (f, phi, g);
+ gcry_mpi_release (phi); phi = NULL;
+ d = g; g = NULL;
+ /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */
+ mpi_invm (d, e, f);
+
+ /* Compute the inverse of p and q. */
+ u = f; f = NULL;
+ mpi_invm (u, p, q );
+
+ if( DBG_CIPHER )
+ {
+ if (*swapped)
+ log_debug ("p and q are swapped\n");
+ log_mpidump(" p", p );
+ log_mpidump(" q", q );
+ log_mpidump(" n", n );
+ log_mpidump(" e", e );
+ log_mpidump(" d", d );
+ log_mpidump(" u", u );
+ }
+
+
+ sk->n = n;
+ sk->e = e;
+ sk->p = p;
+ sk->q = q;
+ sk->d = d;
+ sk->u = u;
+
+ /* Now we can test our keys. */
+ if (test_keys (sk, nbits - 64))
+ {
+ gcry_mpi_release (sk->n); sk->n = NULL;
+ gcry_mpi_release (sk->e); sk->e = NULL;
+ gcry_mpi_release (sk->p); sk->p = NULL;
+ gcry_mpi_release (sk->q); sk->q = NULL;
+ gcry_mpi_release (sk->d); sk->d = NULL;
+ gcry_mpi_release (sk->u); sk->u = NULL;
+ fips_signal_error ("self-test after key generation failed");
+ return GPG_ERR_SELFTEST_FAILED;
+ }
+
+ return 0;
+}
+
+
+/****************
+ * Test whether the secret key is valid.
+ * Returns: true if this is a valid key.
+ */
+static int
+check_secret_key( RSA_secret_key *sk )
+{
+ int rc;
+ gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
+
+ mpi_mul(temp, sk->p, sk->q );
+ rc = mpi_cmp( temp, sk->n );
+ mpi_free(temp);
+ return !rc;
+}
+
+
+
+/****************
+ * Public key operation. Encrypt INPUT with PKEY and put result into OUTPUT.
+ *
+ * c = m^e mod n
+ *
+ * Where c is OUTPUT, m is INPUT and e,n are elements of PKEY.
+ */
+static void
+public(gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *pkey )
+{
+ if( output == input ) /* powm doesn't like output and input the same */
+ {
+ gcry_mpi_t x = mpi_alloc( mpi_get_nlimbs(input)*2 );
+ mpi_powm( x, input, pkey->e, pkey->n );
+ mpi_set(output, x);
+ mpi_free(x);
+ }
+ else
+ mpi_powm( output, input, pkey->e, pkey->n );
+}
+
+#if 0
+static void
+stronger_key_check ( RSA_secret_key *skey )
+{
+ gcry_mpi_t t = mpi_alloc_secure ( 0 );
+ gcry_mpi_t t1 = mpi_alloc_secure ( 0 );
+ gcry_mpi_t t2 = mpi_alloc_secure ( 0 );
+ gcry_mpi_t phi = mpi_alloc_secure ( 0 );
+
+ /* check that n == p * q */
+ mpi_mul( t, skey->p, skey->q);
+ if (mpi_cmp( t, skey->n) )
+ log_info ( "RSA Oops: n != p * q\n" );
+
+ /* check that p is less than q */
+ if( mpi_cmp( skey->p, skey->q ) > 0 )
+ {
+ log_info ("RSA Oops: p >= q - fixed\n");
+ _gcry_mpi_swap ( skey->p, skey->q);
+ }
+
+ /* check that e divides neither p-1 nor q-1 */
+ mpi_sub_ui(t, skey->p, 1 );
+ mpi_fdiv_r(t, t, skey->e );
+ if ( !mpi_cmp_ui( t, 0) )
+ log_info ( "RSA Oops: e divides p-1\n" );
+ mpi_sub_ui(t, skey->q, 1 );
+ mpi_fdiv_r(t, t, skey->e );
+ if ( !mpi_cmp_ui( t, 0) )
+ log_info ( "RSA Oops: e divides q-1\n" );
+
+ /* check that d is correct */
+ mpi_sub_ui( t1, skey->p, 1 );
+ mpi_sub_ui( t2, skey->q, 1 );
+ mpi_mul( phi, t1, t2 );
+ gcry_mpi_gcd(t, t1, t2);
+ mpi_fdiv_q(t, phi, t);
+ mpi_invm(t, skey->e, t );
+ if ( mpi_cmp(t, skey->d ) )
+ {
+ log_info ( "RSA Oops: d is wrong - fixed\n");
+ mpi_set (skey->d, t);
+ _gcry_log_mpidump (" fixed d", skey->d);
+ }
+
+ /* check for correctness of u */
+ mpi_invm(t, skey->p, skey->q );
+ if ( mpi_cmp(t, skey->u ) )
+ {
+ log_info ( "RSA Oops: u is wrong - fixed\n");
+ mpi_set (skey->u, t);
+ _gcry_log_mpidump (" fixed u", skey->u);
+ }
+
+ log_info ( "RSA secret key check finished\n");
+
+ mpi_free (t);
+ mpi_free (t1);
+ mpi_free (t2);
+ mpi_free (phi);
+}
+#endif
+
+
+
+/****************
+ * Secret key operation. Encrypt INPUT with SKEY and put result into OUTPUT.
+ *
+ * m = c^d mod n
+ *
+ * Or faster:
+ *
+ * m1 = c ^ (d mod (p-1)) mod p
+ * m2 = c ^ (d mod (q-1)) mod q
+ * h = u * (m2 - m1) mod q
+ * m = m1 + h * p
+ *
+ * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
+ */
+static void
+secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
+{
+ if (!skey->p || !skey->q || !skey->u)
+ {
+ mpi_powm (output, input, skey->d, skey->n);
+ }
+ else
+ {
+ gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+ gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+ gcry_mpi_t h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
+
+ /* m1 = c ^ (d mod (p-1)) mod p */
+ mpi_sub_ui( h, skey->p, 1 );
+ mpi_fdiv_r( h, skey->d, h );
+ mpi_powm( m1, input, h, skey->p );
+ /* m2 = c ^ (d mod (q-1)) mod q */
+ mpi_sub_ui( h, skey->q, 1 );
+ mpi_fdiv_r( h, skey->d, h );
+ mpi_powm( m2, input, h, skey->q );
+ /* h = u * ( m2 - m1 ) mod q */
+ mpi_sub( h, m2, m1 );
+ if ( mpi_is_neg( h ) )
+ mpi_add ( h, h, skey->q );
+ mpi_mulm( h, skey->u, h, skey->q );
+ /* m = m2 + h * p */
+ mpi_mul ( h, h, skey->p );
+ mpi_add ( output, m1, h );
+
+ mpi_free ( h );
+ mpi_free ( m1 );
+ mpi_free ( m2 );
+ }
+}
+
+
+
+/* Perform RSA blinding. */
+static gcry_mpi_t
+rsa_blind (gcry_mpi_t x, gcry_mpi_t r, gcry_mpi_t e, gcry_mpi_t n)
+{
+ /* A helper. */
+ gcry_mpi_t a;
+
+ /* Result. */
+ gcry_mpi_t y;
+
+ a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+ y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+
+ /* Now we calculate: y = (x * r^e) mod n, where r is the random
+ number, e is the public exponent, x is the non-blinded data and n
+ is the RSA modulus. */
+ gcry_mpi_powm (a, r, e, n);
+ gcry_mpi_mulm (y, a, x, n);
+
+ gcry_mpi_release (a);
+
+ return y;
+}
+
+/* Undo RSA blinding. */
+static gcry_mpi_t
+rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
+{
+ gcry_mpi_t y;
+
+ y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
+
+ /* Here we calculate: y = (x * r^-1) mod n, where x is the blinded
+ decrypted data, ri is the modular multiplicative inverse of r and
+ n is the RSA modulus. */
+
+ gcry_mpi_mulm (y, ri, x, n);
+
+ return y;
+}
+
+/*********************************************
+ ************** interface ******************
+ *********************************************/
+
+static gcry_err_code_t
+rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
+ const gcry_sexp_t genparms,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors,
+ gcry_sexp_t *r_extrainfo)
+{
+ RSA_secret_key sk;
+ gpg_err_code_t ec;
+ gcry_sexp_t deriveparms;
+ int transient_key = 0;
+ int use_x931 = 0;
+ gcry_sexp_t l1;
+
+ (void)algo;
+
+ *retfactors = NULL; /* We don't return them. */
+
+ deriveparms = (genparms?
+ gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
+ if (!deriveparms)
+ {
+ /* Parse the optional "use-x931" flag. */
+ l1 = gcry_sexp_find_token (genparms, "use-x931", 0);
+ if (l1)
+ {
+ use_x931 = 1;
+ gcry_sexp_release (l1);
+ }
+ }
+
+ if (deriveparms || use_x931 || fips_mode ())
+ {
+ int swapped;
+ ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
+ gcry_sexp_release (deriveparms);
+ if (!ec && r_extrainfo && swapped)
+ {
+ ec = gcry_sexp_new (r_extrainfo,
+ "(misc-key-info(p-q-swapped))", 0, 1);
+ if (ec)
+ {
+ gcry_mpi_release (sk.n); sk.n = NULL;
+ gcry_mpi_release (sk.e); sk.e = NULL;
+ gcry_mpi_release (sk.p); sk.p = NULL;
+ gcry_mpi_release (sk.q); sk.q = NULL;
+ gcry_mpi_release (sk.d); sk.d = NULL;
+ gcry_mpi_release (sk.u); sk.u = NULL;
+ }
+ }
+ }
+ else
+ {
+ /* Parse the optional "transient-key" flag. */
+ l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+ if (l1)
+ {
+ transient_key = 1;
+ gcry_sexp_release (l1);
+ }
+ /* Generate. */
+ ec = generate_std (&sk, nbits, evalue, transient_key);
+ }
+
+ if (!ec)
+ {
+ skey[0] = sk.n;
+ skey[1] = sk.e;
+ skey[2] = sk.d;
+ skey[3] = sk.p;
+ skey[4] = sk.q;
+ skey[5] = sk.u;
+ }
+
+ return ec;
+}
+
+
+static gcry_err_code_t
+rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
+ gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+ return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
+}
+
+
+static gcry_err_code_t
+rsa_check_secret_key (int algo, gcry_mpi_t *skey)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ RSA_secret_key sk;
+
+ (void)algo;
+
+ sk.n = skey[0];
+ sk.e = skey[1];
+ sk.d = skey[2];
+ sk.p = skey[3];
+ sk.q = skey[4];
+ sk.u = skey[5];
+
+ if (!sk.p || !sk.q || !sk.u)
+ err = GPG_ERR_NO_OBJ; /* To check the key we need the optional
+ parameters. */
+ else if (!check_secret_key (&sk))
+ err = GPG_ERR_BAD_SECKEY;
+
+ return err;
+}
+
+
+static gcry_err_code_t
+rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *pkey, int flags)
+{
+ RSA_public_key pk;
+
+ (void)algo;
+ (void)flags;
+
+ pk.n = pkey[0];
+ pk.e = pkey[1];
+ resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.n));
+ public (resarr[0], data, &pk);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags)
+{
+ RSA_secret_key sk;
+ gcry_mpi_t r = MPI_NULL; /* Random number needed for blinding. */
+ gcry_mpi_t ri = MPI_NULL; /* Modular multiplicative inverse of
+ r. */
+ gcry_mpi_t x = MPI_NULL; /* Data to decrypt. */
+ gcry_mpi_t y; /* Result. */
+
+ (void)algo;
+
+ /* Extract private key. */
+ sk.n = skey[0];
+ sk.e = skey[1];
+ sk.d = skey[2];
+ sk.p = skey[3]; /* Optional. */
+ sk.q = skey[4]; /* Optional. */
+ sk.u = skey[5]; /* Optional. */
+
+ y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+
+ /* We use blinding by default to mitigate timing attacks which can
+ be practically mounted over the network as shown by Brumley and
+ Boney in 2003. */
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ {
+ /* Initialize blinding. */
+
+ /* First, we need a random number r between 0 and n - 1, which
+ is relatively prime to n (i.e. it is neither p nor q). The
+ random number needs to be only unpredictable, thus we employ
+ the gcry_create_nonce function by using GCRY_WEAK_RANDOM with
+ gcry_mpi_randomize. */
+ r = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+ ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+
+ gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
+ gcry_mpi_mod (r, r, sk.n);
+
+ /* Calculate inverse of r. It practically impossible that the
+ following test fails, thus we do not add code to release
+ allocated resources. */
+ if (!gcry_mpi_invm (ri, r, sk.n))
+ return GPG_ERR_INTERNAL;
+ }
+
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ x = rsa_blind (data[0], r, sk.e, sk.n);
+ else
+ x = data[0];
+
+ /* Do the encryption. */
+ secret (y, x, &sk);
+
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ {
+ /* Undo blinding. */
+ gcry_mpi_t a = gcry_mpi_copy (y);
+
+ gcry_mpi_release (y);
+ y = rsa_unblind (a, ri, sk.n);
+
+ gcry_mpi_release (a);
+ }
+
+ if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+ {
+ /* Deallocate resources needed for blinding. */
+ gcry_mpi_release (x);
+ gcry_mpi_release (r);
+ gcry_mpi_release (ri);
+ }
+
+ /* Copy out result. */
+ *result = y;
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+{
+ RSA_secret_key sk;
+
+ (void)algo;
+
+ sk.n = skey[0];
+ sk.e = skey[1];
+ sk.d = skey[2];
+ sk.p = skey[3];
+ sk.q = skey[4];
+ sk.u = skey[5];
+ resarr[0] = mpi_alloc( mpi_get_nlimbs (sk.n));
+ secret (resarr[0], data, &sk);
+
+ return GPG_ERR_NO_ERROR;
+}
+
+
+static gcry_err_code_t
+rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
+ int (*cmp) (void *opaque, gcry_mpi_t tmp),
+ void *opaquev)
+{
+ RSA_public_key pk;
+ gcry_mpi_t result;
+ gcry_err_code_t rc;
+
+ (void)algo;
+ (void)cmp;
+ (void)opaquev;
+
+ pk.n = pkey[0];
+ pk.e = pkey[1];
+ result = gcry_mpi_new ( 160 );
+ public( result, data[0], &pk );
+#ifdef IS_DEVELOPMENT_VERSION
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("rsa verify result:", result );
+ log_mpidump (" hash:", hash );
+ }
+#endif /*IS_DEVELOPMENT_VERSION*/
+ if (cmp)
+ rc = (*cmp) (opaquev, result);
+ else
+ rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+ gcry_mpi_release (result);
+
+ return rc;
+}
+
+
+static unsigned int
+rsa_get_nbits (int algo, gcry_mpi_t *pkey)
+{
+ (void)algo;
+
+ return mpi_get_nbits (pkey[0]);
+}
+
+
+/* Compute a keygrip. MD is the hash context which we are going to
+ update. KEYPARAM is an S-expression with the key parameters, this
+ is usually a public key but may also be a secret key. An example
+ of such an S-expression is:
+
+ (rsa
+ (n #00B...#)
+ (e #010001#))
+
+ PKCS-15 says that for RSA only the modulus should be hashed -
+ however, it is not clear whether this is meant to use the raw bytes
+ (assuming this is an unsigned integer) or whether the DER required
+ 0 should be prefixed. We hash the raw bytes. */
+static gpg_err_code_t
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+{
+ gcry_sexp_t l1;
+ const char *data;
+ size_t datalen;
+
+ l1 = gcry_sexp_find_token (keyparam, "n", 1);
+ if (!l1)
+ return GPG_ERR_NO_OBJ;
+
+ data = gcry_sexp_nth_data (l1, 1, &datalen);
+ if (!data)
+ {
+ gcry_sexp_release (l1);
+ return GPG_ERR_NO_OBJ;
+ }
+
+ gcry_md_write (md, data, datalen);
+ gcry_sexp_release (l1);
+
+ return 0;
+}
+
+
+
+\f
+/*
+ Self-test section.
+ */
+
+static const char *
+selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ static const char sample_data[] =
+ "(data (flags pkcs1)"
+ " (hash sha1 #11223344556677889900aabbccddeeff10203040#))";
+ static const char sample_data_bad[] =
+ "(data (flags pkcs1)"
+ " (hash sha1 #11223344556677889900aabbccddeeff80203040#))";
+
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ gcry_sexp_t data = NULL;
+ gcry_sexp_t data_bad = NULL;
+ gcry_sexp_t sig = NULL;
+
+ err = gcry_sexp_sscan (&data, NULL,
+ sample_data, strlen (sample_data));
+ if (!err)
+ err = gcry_sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ err = gcry_pk_sign (&sig, data, skey);
+ if (err)
+ {
+ errtxt = "signing failed";
+ goto leave;
+ }
+ err = gcry_pk_verify (sig, data, pkey);
+ if (err)
+ {
+ errtxt = "verify failed";
+ goto leave;
+ }
+ err = gcry_pk_verify (sig, data_bad, pkey);
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
+ {
+ errtxt = "bad signature not detected";
+ goto leave;
+ }
+
+
+ leave:
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data_bad);
+ gcry_sexp_release (data);
+ return errtxt;
+}
+
+
+
+/* Given an S-expression ENCR_DATA of the form:
+
+ (enc-val
+ (rsa
+ (a a-value)))
+
+ as returned by gcry_pk_decrypt, return the the A-VALUE. On error,
+ return NULL. */
+static gcry_mpi_t
+extract_a_from_sexp (gcry_sexp_t encr_data)
+{
+ gcry_sexp_t l1, l2, l3;
+ gcry_mpi_t a_value;
+
+ l1 = gcry_sexp_find_token (encr_data, "enc-val", 0);
+ if (!l1)
+ return NULL;
+ l2 = gcry_sexp_find_token (l1, "rsa", 0);
+ gcry_sexp_release (l1);
+ if (!l2)
+ return NULL;
+ l3 = gcry_sexp_find_token (l2, "a", 0);
+ gcry_sexp_release (l2);
+ if (!l3)
+ return NULL;
+ a_value = gcry_sexp_nth_mpi (l3, 1, 0);
+ gcry_sexp_release (l3);
+
+ return a_value;
+}
+
+
+static const char *
+selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
+{
+ const char *errtxt = NULL;
+ gcry_error_t err;
+ const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */
+ gcry_mpi_t plaintext = NULL;
+ gcry_sexp_t plain = NULL;
+ gcry_sexp_t encr = NULL;
+ gcry_mpi_t ciphertext = NULL;
+ gcry_sexp_t decr = NULL;
+ gcry_mpi_t decr_plaintext = NULL;
+ gcry_sexp_t tmplist = NULL;
+
+ /* Create plaintext. The plaintext is actually a big integer number. */
+ plaintext = gcry_mpi_new (nbits);
+ gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+ /* Put the plaintext into an S-expression. */
+ err = gcry_sexp_build (&plain, NULL,
+ "(data (flags raw) (value %m))", plaintext);
+ if (err)
+ {
+ errtxt = "converting data failed";
+ goto leave;
+ }
+
+ /* Encrypt. */
+ err = gcry_pk_encrypt (&encr, plain, pkey);
+ if (err)
+ {
+ errtxt = "encrypt failed";
+ goto leave;
+ }
+
+ /* Extraxt the ciphertext from the returned S-expression. */
+ /*gcry_sexp_dump (encr);*/
+ ciphertext = extract_a_from_sexp (encr);
+ if (!ciphertext)
+ {
+ errtxt = "gcry_pk_decrypt returned garbage";
+ goto leave;
+ }
+
+ /* Check that the ciphertext does no match the plaintext. */
+ /* _gcry_log_mpidump ("plaintext", plaintext); */
+ /* _gcry_log_mpidump ("ciphertxt", ciphertext); */
+ if (!gcry_mpi_cmp (plaintext, ciphertext))
+ {
+ errtxt = "ciphertext matches plaintext";
+ goto leave;
+ }
+
+ /* Decrypt. */
+ err = gcry_pk_decrypt (&decr, encr, skey);
+ if (err)
+ {
+ errtxt = "decrypt failed";
+ goto leave;
+ }
+
+ /* Extract the decrypted data from the S-expression. Note that the
+ output of gcry_pk_decrypt depends on whether a flags lists occurs
+ in its input data. Because we passed the output of
+ gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value
+ won't be there as of today. To be prepared for future changes we
+ take care of it anyway. */
+ tmplist = gcry_sexp_find_token (decr, "value", 0);
+ if (tmplist)
+ decr_plaintext = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
+ else
+ decr_plaintext = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
+ if (!decr_plaintext)
+ {
+ errtxt = "decrypt returned no plaintext";
+ goto leave;
+ }
+
+ /* Check that the decrypted plaintext matches the original plaintext. */
+ if (gcry_mpi_cmp (plaintext, decr_plaintext))
+ {
+ errtxt = "mismatch";
+ goto leave;
+ }
+
+ leave:
+ gcry_sexp_release (tmplist);
+ gcry_mpi_release (decr_plaintext);
+ gcry_sexp_release (decr);
+ gcry_mpi_release (ciphertext);
+ gcry_sexp_release (encr);
+ gcry_sexp_release (plain);
+ gcry_mpi_release (plaintext);
+ return errtxt;
+}
+
+
+static gpg_err_code_t
+selftests_rsa (selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+ gcry_error_t err;
+ gcry_sexp_t skey = NULL;
+ gcry_sexp_t pkey = NULL;
+
+ /* Convert the S-expressions into the internal representation. */
+ what = "convert";
+ err = gcry_sexp_sscan (&skey, NULL,
+ sample_secret_key, strlen (sample_secret_key));
+ if (!err)
+ err = gcry_sexp_sscan (&pkey, NULL,
+ sample_public_key, strlen (sample_public_key));
+ if (err)
+ {
+ errtxt = gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "key consistency";
+ err = gcry_pk_testkey (skey);
+ if (err)
+ {
+ errtxt = gcry_strerror (err);
+ goto failed;
+ }
+
+ what = "sign";
+ errtxt = selftest_sign_1024 (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ what = "encrypt";
+ errtxt = selftest_encr_1024 (pkey, skey);
+ if (errtxt)
+ goto failed;
+
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ return 0; /* Succeeded. */
+
+ failed:
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ if (report)
+ report ("pubkey", GCRY_PK_RSA, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ (void)extended;
+
+ switch (algo)
+ {
+ case GCRY_PK_RSA:
+ ec = selftests_rsa (report);
+ break;
+ default:
+ ec = GPG_ERR_PUBKEY_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static const char *rsa_names[] =
+ {
+ "rsa",
+ "openpgp-rsa",
+ "oid.1.2.840.113549.1.1.1",
+ NULL,
+ };
+
+gcry_pk_spec_t _gcry_pubkey_spec_rsa =
+ {
+ "RSA", rsa_names,
+ "ne", "nedpqu", "a", "s", "n",
+ GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
+ rsa_generate,
+ rsa_check_secret_key,
+ rsa_encrypt,
+ rsa_decrypt,
+ rsa_sign,
+ rsa_verify,
+ rsa_get_nbits,
+ };
+pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
+ {
+ run_selftests,
+ rsa_generate_ext,
+ compute_keygrip
+ };
--- /dev/null
+/* SEED for libgcrypt
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * --
+ * This implementation was provided for libgcrypt in public domain
+ * by Hye-Shik Chang <perky@FreeBSD.org>, July 2006.
+ */
+\f
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+#define NUMKC 16
+
+#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
+ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
+#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
+ (ct)[1] = (byte)((st) >> 16); \
+ (ct)[2] = (byte)((st) >> 8); \
+ (ct)[3] = (byte)(st); }
+
+union wordbuf
+{
+ u32 w;
+ byte b[4];
+};
+
+#ifdef WORDS_BIGENDIAN
+#define b0 b[3]
+#define b1 b[2]
+#define b2 b[1]
+#define b3 b[0]
+#else
+#define b0 b[0]
+#define b1 b[1]
+#define b2 b[2]
+#define b3 b[3]
+#endif
+
+static const char *selftest(void);
+
+typedef struct
+{
+ u32 keyschedule[32];
+} SEED_context;
+
+static const u32 SS0[256] = {
+ 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c,
+ 0x2c8ca0ac, 0x25052124, 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c,
+ 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, 0x28082028, 0x04444044,
+ 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
+ 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310,
+ 0x12c2d2d0, 0x2ecee2ec, 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8,
+ 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, 0x2ccce0ec, 0x15859194,
+ 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
+ 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc,
+ 0x32c2f2f0, 0x19c9d1d8, 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380,
+ 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, 0x20406060, 0x10405050,
+ 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
+ 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210,
+ 0x2f8fa3ac, 0x15c5d1d4, 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140,
+ 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, 0x1f0f131c, 0x19899198,
+ 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
+ 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388,
+ 0x0e0e020c, 0x2b8ba3a8, 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c,
+ 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, 0x3f8fb3bc, 0x2fcfe3ec,
+ 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
+ 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120,
+ 0x2b4b6368, 0x26466264, 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288,
+ 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, 0x3a4a7278, 0x07474344,
+ 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
+ 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114,
+ 0x22022220, 0x38083038, 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c,
+ 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, 0x35053134, 0x0bcbc3c8,
+ 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
+ 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158,
+ 0x02828280, 0x04c4c0c4, 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364,
+ 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, 0x0f0f030c, 0x0e8e828c,
+ 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
+ 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c,
+ 0x2d0d212c, 0x00404040, 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0,
+ 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, 0x3b0b3338, 0x1cccd0dc,
+ 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
+ 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328,
+ 0x25456164, 0x3acaf2f8, 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c,
+ 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, 0x31013130, 0x2acae2e8,
+ 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
+ 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128,
+ 0x07070304, 0x33033330, 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178,
+ 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298,
+};
+
+static const u32 SS1[256] = {
+ 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2,
+ 0xb03383b3, 0xb83888b0, 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3,
+ 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, 0xc003c3c3, 0x60224262,
+ 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
+ 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0,
+ 0x34360632, 0x480b4b43, 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0,
+ 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, 0xc002c2c2, 0x44054541,
+ 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
+ 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1,
+ 0x0c0d0d01, 0xdc1fcfd3, 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72,
+ 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, 0x40024242, 0xd414c4d0,
+ 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
+ 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20,
+ 0xa82a8aa2, 0x34340430, 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1,
+ 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, 0x54174753, 0xac2e8ea2,
+ 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
+ 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82,
+ 0x682a4a62, 0xb03181b1, 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202,
+ 0x20220222, 0x04040400, 0x68284860, 0x70314171, 0x04070703, 0xd81bcbd3,
+ 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
+ 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3,
+ 0xa82b8ba3, 0xd010c0d0, 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12,
+ 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, 0x94168692, 0x783b4b73,
+ 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
+ 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22,
+ 0xb83a8ab2, 0x6c2e4e62, 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292,
+ 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, 0x14150511, 0xf83bcbf3,
+ 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
+ 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0,
+ 0xe82acae2, 0x08090901, 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040,
+ 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, 0xf83acaf2, 0x00010101,
+ 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
+ 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1,
+ 0x48084840, 0x78394971, 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282,
+ 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, 0x74374773, 0x54144450,
+ 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
+ 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2,
+ 0xc809c9c1, 0xfc3dcdf1, 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30,
+ 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, 0x0c0e0e02, 0x50104050,
+ 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
+ 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353,
+ 0x080a0a02, 0x84078783, 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83,
+ 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3,
+};
+
+static const u32 SS2[256] = {
+ 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d,
+ 0xa0ac2c8c, 0x21242505, 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e,
+ 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, 0x20282808, 0x40440444,
+ 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
+ 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303,
+ 0xd2d012c2, 0xe2ec2ece, 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888,
+ 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, 0xe0ec2ccc, 0x91941585,
+ 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
+ 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc,
+ 0xf2f032c2, 0xd1d819c9, 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383,
+ 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, 0x60602040, 0x50501040,
+ 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
+ 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202,
+ 0xa3ac2f8f, 0xd1d415c5, 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141,
+ 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, 0x131c1f0f, 0x91981989,
+ 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
+ 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b,
+ 0x020c0e0e, 0xa3a82b8b, 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d,
+ 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, 0xb3bc3f8f, 0xe3ec2fcf,
+ 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
+ 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101,
+ 0x63682b4b, 0x62642646, 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a,
+ 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, 0x72783a4a, 0x43440747,
+ 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
+ 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505,
+ 0x22202202, 0x30383808, 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c,
+ 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, 0x31343505, 0xc3c80bcb,
+ 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
+ 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949,
+ 0x82800282, 0xc0c404c4, 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747,
+ 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, 0x030c0f0f, 0x828c0e8e,
+ 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
+ 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d,
+ 0x212c2d0d, 0x40400040, 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1,
+ 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, 0x33383b0b, 0xd0dc1ccc,
+ 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
+ 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b,
+ 0x61642545, 0xf2f83aca, 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f,
+ 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, 0x31303101, 0xe2e82aca,
+ 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
+ 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909,
+ 0x03040707, 0x33303303, 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949,
+ 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a,
+};
+
+static const u32 SS3[256] = {
+ 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e,
+ 0x83b3b033, 0x88b0b838, 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407,
+ 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, 0xc3c3c003, 0x42626022,
+ 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
+ 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c,
+ 0x06323436, 0x4b43480b, 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828,
+ 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, 0xc2c2c002, 0x45414405,
+ 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
+ 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839,
+ 0x0d010c0d, 0xcfd3dc1f, 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a,
+ 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, 0x42424002, 0xc4d0d414,
+ 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
+ 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c,
+ 0x8aa2a82a, 0x04303434, 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829,
+ 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, 0x47535417, 0x8ea2ac2e,
+ 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
+ 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a,
+ 0x4a62682a, 0x81b1b031, 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002,
+ 0x02222022, 0x04000404, 0x48606828, 0x41717031, 0x07030407, 0xcbd3d81b,
+ 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
+ 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023,
+ 0x8ba3a82b, 0xc0d0d010, 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a,
+ 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, 0x86929416, 0x4b73783b,
+ 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
+ 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e,
+ 0x8ab2b83a, 0x4e626c2e, 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012,
+ 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, 0x05111415, 0xcbf3f83b,
+ 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
+ 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434,
+ 0xcae2e82a, 0x09010809, 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000,
+ 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, 0xcaf2f83a, 0x01010001,
+ 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
+ 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425,
+ 0x48404808, 0x49717839, 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002,
+ 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, 0x47737437, 0x44505414,
+ 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
+ 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a,
+ 0xc9c1c809, 0xcdf1fc3d, 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c,
+ 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, 0x0e020c0e, 0x40505010,
+ 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
+ 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013,
+ 0x0a02080a, 0x87838407, 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f,
+ 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437,
+};
+
+static const u32 KC[NUMKC] = {
+ 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
+ 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
+ 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
+ 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b,
+};
+\f
+
+
+/* Perform the key setup.
+ */
+static gcry_err_code_t
+do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
+{
+ static int initialized = 0;
+ static const char *selftest_failed=0;
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+ u32 *keyout = ctx->keyschedule;
+ int i;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if( selftest_failed )
+ log_error ("%s\n", selftest_failed );
+ }
+ if (selftest_failed)
+ return GPG_ERR_SELFTEST_FAILED;
+
+ if (keylen != 16)
+ return GPG_ERR_INV_KEYLEN;
+
+ x1 = GETU32 (key);
+ x2 = GETU32 (key+4);
+ x3 = GETU32 (key+8);
+ x4 = GETU32 (key+12);
+
+ for (i = 0; i < NUMKC; i++)
+ {
+ t0.w = x1 + x3 - KC[i];
+ t1.w = x2 + KC[i] - x4;
+ *(keyout++) = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3];
+ *(keyout++) = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3];
+
+ if (i % 2 == 0)
+ {
+ t0.w = x1;
+ x1 = (x1>>8) ^ (x2<<24);
+ x2 = (x2>>8) ^ (t0.w<<24);
+ }
+ else
+ {
+ t0.w = x3;
+ x3 = (x3<<8) ^ (x4>>24);
+ x4 = (x4<<8) ^ (t0.w>>24);
+ }
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t
+seed_setkey (void *context, const byte *key, const unsigned keylen)
+{
+ SEED_context *ctx = context;
+
+ int rc = do_setkey (ctx, key, keylen);
+ _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2);
+ return rc;
+}
+
+
+\f
+#define OP(X1, X2, X3, X4, rbase) \
+ t0.w = X3 ^ ctx->keyschedule[rbase]; \
+ t1.w = X4 ^ ctx->keyschedule[rbase+1]; \
+ t1.w ^= t0.w; \
+ t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
+ t0.w += t1.w; \
+ t0.w = SS0[t0.b0] ^ SS1[t0.b1] ^ SS2[t0.b2] ^ SS3[t0.b3]; \
+ t1.w += t0.w; \
+ t1.w = SS0[t1.b0] ^ SS1[t1.b1] ^ SS2[t1.b2] ^ SS3[t1.b3]; \
+ t0.w += t1.w; \
+ X1 ^= t0.w; \
+ X2 ^= t1.w;
+
+/* Encrypt one block. inbuf and outbuf may be the same. */
+static void
+do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+
+ x1 = GETU32 (inbuf);
+ x2 = GETU32 (inbuf+4);
+ x3 = GETU32 (inbuf+8);
+ x4 = GETU32 (inbuf+12);
+
+ OP (x1, x2, x3, x4, 0);
+ OP (x3, x4, x1, x2, 2);
+ OP (x1, x2, x3, x4, 4);
+ OP (x3, x4, x1, x2, 6);
+ OP (x1, x2, x3, x4, 8);
+ OP (x3, x4, x1, x2, 10);
+ OP (x1, x2, x3, x4, 12);
+ OP (x3, x4, x1, x2, 14);
+ OP (x1, x2, x3, x4, 16);
+ OP (x3, x4, x1, x2, 18);
+ OP (x1, x2, x3, x4, 20);
+ OP (x3, x4, x1, x2, 22);
+ OP (x1, x2, x3, x4, 24);
+ OP (x3, x4, x1, x2, 26);
+ OP (x1, x2, x3, x4, 28);
+ OP (x3, x4, x1, x2, 30);
+
+ PUTU32 (outbuf, x3);
+ PUTU32 (outbuf+4, x4);
+ PUTU32 (outbuf+8, x1);
+ PUTU32 (outbuf+12, x2);
+}
+
+static void
+seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+ SEED_context *ctx = context;
+
+ do_encrypt (ctx, outbuf, inbuf);
+ _gcry_burn_stack (4*6);
+}
+
+
+\f
+/* Decrypt one block. inbuf and outbuf may be the same. */
+static void
+do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
+{
+ u32 x1, x2, x3, x4;
+ union wordbuf t0, t1;
+
+ x1 = GETU32 (inbuf);
+ x2 = GETU32 (inbuf+4);
+ x3 = GETU32 (inbuf+8);
+ x4 = GETU32 (inbuf+12);
+
+ OP (x1, x2, x3, x4, 30);
+ OP (x3, x4, x1, x2, 28);
+ OP (x1, x2, x3, x4, 26);
+ OP (x3, x4, x1, x2, 24);
+ OP (x1, x2, x3, x4, 22);
+ OP (x3, x4, x1, x2, 20);
+ OP (x1, x2, x3, x4, 18);
+ OP (x3, x4, x1, x2, 16);
+ OP (x1, x2, x3, x4, 14);
+ OP (x3, x4, x1, x2, 12);
+ OP (x1, x2, x3, x4, 10);
+ OP (x3, x4, x1, x2, 8);
+ OP (x1, x2, x3, x4, 6);
+ OP (x3, x4, x1, x2, 4);
+ OP (x1, x2, x3, x4, 2);
+ OP (x3, x4, x1, x2, 0);
+
+ PUTU32 (outbuf, x3);
+ PUTU32 (outbuf+4, x4);
+ PUTU32 (outbuf+8, x1);
+ PUTU32 (outbuf+12, x2);
+}
+
+static void
+seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
+{
+ SEED_context *ctx = context;
+
+ do_decrypt (ctx, outbuf, inbuf);
+ _gcry_burn_stack (4*6);
+}
+
+\f
+/* Test a single encryption and decryption with each key size. */
+static const char*
+selftest (void)
+{
+ SEED_context ctx;
+ byte scratch[16];
+
+ /* The test vector is taken from the appendix section B.3 of RFC4269.
+ */
+ static const byte plaintext[16] = {
+ 0x83, 0xA2, 0xF8, 0xA2, 0x88, 0x64, 0x1F, 0xB9,
+ 0xA4, 0xE9, 0xA5, 0xCC, 0x2F, 0x13, 0x1C, 0x7D
+ };
+ static const byte key[16] = {
+ 0x47, 0x06, 0x48, 0x08, 0x51, 0xE6, 0x1B, 0xE8,
+ 0x5D, 0x74, 0xBF, 0xB3, 0xFD, 0x95, 0x61, 0x85
+ };
+ static const byte ciphertext[16] = {
+ 0xEE, 0x54, 0xD1, 0x3E, 0xBC, 0xAE, 0x70, 0x6D,
+ 0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A,
+ };
+
+ seed_setkey (&ctx, key, sizeof(key));
+ seed_encrypt (&ctx, scratch, plaintext);
+ if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
+ return "SEED test encryption failed.";
+ seed_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext, sizeof (plaintext)))
+ return "SEED test decryption failed.";
+
+ return NULL;
+}
+
+\f
+
+static gcry_cipher_oid_spec_t seed_oids[] =
+ {
+ { "1.2.410.200004.1.3", GCRY_CIPHER_MODE_ECB },
+ { "1.2.410.200004.1.4", GCRY_CIPHER_MODE_CBC },
+ { "1.2.410.200004.1.5", GCRY_CIPHER_MODE_CFB },
+ { "1.2.410.200004.1.6", GCRY_CIPHER_MODE_OFB },
+ { NULL }
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_seed =
+ {
+ "SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
+ seed_setkey, seed_encrypt, seed_decrypt,
+ };
--- /dev/null
+/* serpent.c - Implementation of the Serpent encryption algorithm.
+ * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdio.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bithelp.h"
+
+/* Number of rounds per Serpent encrypt/decrypt operation. */
+#define ROUNDS 32
+
+/* Magic number, used during generating of the subkeys. */
+#define PHI 0x9E3779B9
+
+/* Serpent works on 128 bit blocks. */
+typedef u32 serpent_block_t[4];
+
+/* Serpent key, provided by the user. If the original key is shorter
+ than 256 bits, it is padded. */
+typedef u32 serpent_key_t[8];
+
+/* The key schedule consists of 33 128 bit subkeys. */
+typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
+
+/* A Serpent context. */
+typedef struct serpent_context
+{
+ serpent_subkeys_t keys; /* Generated subkeys. */
+} serpent_context_t;
+
+
+/* A prototype. */
+static const char *serpent_test (void);
+
+
+#define byte_swap_32(x) \
+ (0 \
+ | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) \
+ | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+/* These are the S-Boxes of Serpent. They are copied from Serpents
+ reference implementation (the optimized one, contained in
+ `floppy2') and are therefore:
+
+ Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
+
+ To quote the Serpent homepage
+ (http://www.cl.cam.ac.uk/~rja14/serpent.html):
+
+ "Serpent is now completely in the public domain, and we impose no
+ restrictions on its use. This was announced on the 21st August at
+ the First AES Candidate Conference. The optimised implementations
+ in the submission package are now under the GNU PUBLIC LICENSE
+ (GPL), although some comments in the code still say otherwise. You
+ are welcome to use Serpent for any application." */
+
+#define SBOX0(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t05, t06, t07, t08, t09; \
+ u32 t11, t12, t13, t14, t15, t17, t01; \
+ t01 = b ^ c ; \
+ t02 = a | d ; \
+ t03 = a ^ b ; \
+ z = t02 ^ t01; \
+ t05 = c | z ; \
+ t06 = a ^ d ; \
+ t07 = b | c ; \
+ t08 = d & t05; \
+ t09 = t03 & t07; \
+ y = t09 ^ t08; \
+ t11 = t09 & y ; \
+ t12 = c ^ d ; \
+ t13 = t07 ^ t11; \
+ t14 = b & t06; \
+ t15 = t06 ^ t13; \
+ w = ~ t15; \
+ t17 = w ^ t14; \
+ x = t12 ^ t17; \
+ }
+
+#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t08, t09, t10; \
+ u32 t12, t13, t14, t15, t17, t18, t01; \
+ t01 = c ^ d ; \
+ t02 = a | b ; \
+ t03 = b | c ; \
+ t04 = c & t01; \
+ t05 = t02 ^ t01; \
+ t06 = a | t04; \
+ y = ~ t05; \
+ t08 = b ^ d ; \
+ t09 = t03 & t08; \
+ t10 = d | y ; \
+ x = t09 ^ t06; \
+ t12 = a | t05; \
+ t13 = x ^ t12; \
+ t14 = t03 ^ t10; \
+ t15 = a ^ c ; \
+ z = t14 ^ t13; \
+ t17 = t05 & t13; \
+ t18 = t14 | t17; \
+ w = t15 ^ t18; \
+ }
+
+#define SBOX1(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t08; \
+ u32 t10, t11, t12, t13, t16, t17, t01; \
+ t01 = a | d ; \
+ t02 = c ^ d ; \
+ t03 = ~ b ; \
+ t04 = a ^ c ; \
+ t05 = a | t03; \
+ t06 = d & t04; \
+ t07 = t01 & t02; \
+ t08 = b | t06; \
+ y = t02 ^ t05; \
+ t10 = t07 ^ t08; \
+ t11 = t01 ^ t10; \
+ t12 = y ^ t11; \
+ t13 = b & d ; \
+ z = ~ t10; \
+ x = t13 ^ t12; \
+ t16 = t10 | x ; \
+ t17 = t05 & t16; \
+ w = c ^ t17; \
+ }
+
+#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t08; \
+ u32 t09, t10, t11, t14, t15, t17, t01; \
+ t01 = a ^ b ; \
+ t02 = b | d ; \
+ t03 = a & c ; \
+ t04 = c ^ t02; \
+ t05 = a | t04; \
+ t06 = t01 & t05; \
+ t07 = d | t03; \
+ t08 = b ^ t06; \
+ t09 = t07 ^ t06; \
+ t10 = t04 | t03; \
+ t11 = d & t08; \
+ y = ~ t09; \
+ x = t10 ^ t11; \
+ t14 = a | y ; \
+ t15 = t06 ^ x ; \
+ z = t01 ^ t04; \
+ t17 = c ^ t15; \
+ w = t14 ^ t17; \
+ }
+
+#define SBOX2(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t05, t06, t07, t08; \
+ u32 t09, t10, t12, t13, t14, t01; \
+ t01 = a | c ; \
+ t02 = a ^ b ; \
+ t03 = d ^ t01; \
+ w = t02 ^ t03; \
+ t05 = c ^ w ; \
+ t06 = b ^ t05; \
+ t07 = b | t05; \
+ t08 = t01 & t06; \
+ t09 = t03 ^ t07; \
+ t10 = t02 | t09; \
+ x = t10 ^ t08; \
+ t12 = a | d ; \
+ t13 = t09 ^ x ; \
+ t14 = b ^ t13; \
+ z = ~ t09; \
+ y = t12 ^ t14; \
+ }
+
+#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t06, t07, t08, t09; \
+ u32 t10, t11, t12, t15, t16, t17, t01; \
+ t01 = a ^ d ; \
+ t02 = c ^ d ; \
+ t03 = a & c ; \
+ t04 = b | t02; \
+ w = t01 ^ t04; \
+ t06 = a | c ; \
+ t07 = d | w ; \
+ t08 = ~ d ; \
+ t09 = b & t06; \
+ t10 = t08 | t03; \
+ t11 = b & t07; \
+ t12 = t06 & t02; \
+ z = t09 ^ t10; \
+ x = t12 ^ t11; \
+ t15 = c & z ; \
+ t16 = w ^ x ; \
+ t17 = t10 ^ t15; \
+ y = t16 ^ t17; \
+ }
+
+#define SBOX3(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t08; \
+ u32 t09, t10, t11, t13, t14, t15, t01; \
+ t01 = a ^ c ; \
+ t02 = a | d ; \
+ t03 = a & d ; \
+ t04 = t01 & t02; \
+ t05 = b | t03; \
+ t06 = a & b ; \
+ t07 = d ^ t04; \
+ t08 = c | t06; \
+ t09 = b ^ t07; \
+ t10 = d & t05; \
+ t11 = t02 ^ t10; \
+ z = t08 ^ t09; \
+ t13 = d | z ; \
+ t14 = a | t07; \
+ t15 = b & t13; \
+ y = t08 ^ t11; \
+ w = t14 ^ t15; \
+ x = t05 ^ t04; \
+ }
+
+#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t09; \
+ u32 t11, t12, t13, t14, t16, t01; \
+ t01 = c | d ; \
+ t02 = a | d ; \
+ t03 = c ^ t02; \
+ t04 = b ^ t02; \
+ t05 = a ^ d ; \
+ t06 = t04 & t03; \
+ t07 = b & t01; \
+ y = t05 ^ t06; \
+ t09 = a ^ t03; \
+ w = t07 ^ t03; \
+ t11 = w | t05; \
+ t12 = t09 & t11; \
+ t13 = a & y ; \
+ t14 = t01 ^ t05; \
+ x = b ^ t12; \
+ t16 = b | t13; \
+ z = t14 ^ t16; \
+ }
+
+#define SBOX4(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t08, t09; \
+ u32 t10, t11, t12, t13, t14, t15, t16, t01; \
+ t01 = a | b ; \
+ t02 = b | c ; \
+ t03 = a ^ t02; \
+ t04 = b ^ d ; \
+ t05 = d | t03; \
+ t06 = d & t01; \
+ z = t03 ^ t06; \
+ t08 = z & t04; \
+ t09 = t04 & t05; \
+ t10 = c ^ t06; \
+ t11 = b & c ; \
+ t12 = t04 ^ t08; \
+ t13 = t11 | t03; \
+ t14 = t10 ^ t09; \
+ t15 = a & t05; \
+ t16 = t11 | t12; \
+ y = t13 ^ t08; \
+ x = t15 ^ t16; \
+ w = ~ t14; \
+ }
+
+#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t09; \
+ u32 t10, t11, t12, t13, t15, t01; \
+ t01 = b | d ; \
+ t02 = c | d ; \
+ t03 = a & t01; \
+ t04 = b ^ t02; \
+ t05 = c ^ d ; \
+ t06 = ~ t03; \
+ t07 = a & t04; \
+ x = t05 ^ t07; \
+ t09 = x | t06; \
+ t10 = a ^ t07; \
+ t11 = t01 ^ t09; \
+ t12 = d ^ t04; \
+ t13 = c | t10; \
+ z = t03 ^ t12; \
+ t15 = a ^ t04; \
+ y = t11 ^ t13; \
+ w = t15 ^ t09; \
+ }
+
+#define SBOX5(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t07, t08, t09; \
+ u32 t10, t11, t12, t13, t14, t01; \
+ t01 = b ^ d ; \
+ t02 = b | d ; \
+ t03 = a & t01; \
+ t04 = c ^ t02; \
+ t05 = t03 ^ t04; \
+ w = ~ t05; \
+ t07 = a ^ t01; \
+ t08 = d | w ; \
+ t09 = b | t05; \
+ t10 = d ^ t08; \
+ t11 = b | t07; \
+ t12 = t03 | w ; \
+ t13 = t07 | t10; \
+ t14 = t01 ^ t11; \
+ y = t09 ^ t13; \
+ x = t07 ^ t08; \
+ z = t12 ^ t14; \
+ }
+
+#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t07, t08, t09; \
+ u32 t10, t12, t13, t15, t16, t01; \
+ t01 = a & d ; \
+ t02 = c ^ t01; \
+ t03 = a ^ d ; \
+ t04 = b & t02; \
+ t05 = a & c ; \
+ w = t03 ^ t04; \
+ t07 = a & w ; \
+ t08 = t01 ^ w ; \
+ t09 = b | t05; \
+ t10 = ~ b ; \
+ x = t08 ^ t09; \
+ t12 = t10 | t07; \
+ t13 = w | x ; \
+ z = t02 ^ t12; \
+ t15 = t02 ^ t13; \
+ t16 = b ^ d ; \
+ y = t16 ^ t15; \
+ }
+
+#define SBOX6(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t07, t08, t09, t10; \
+ u32 t11, t12, t13, t15, t17, t18, t01; \
+ t01 = a & d ; \
+ t02 = b ^ c ; \
+ t03 = a ^ d ; \
+ t04 = t01 ^ t02; \
+ t05 = b | c ; \
+ x = ~ t04; \
+ t07 = t03 & t05; \
+ t08 = b & x ; \
+ t09 = a | c ; \
+ t10 = t07 ^ t08; \
+ t11 = b | d ; \
+ t12 = c ^ t11; \
+ t13 = t09 ^ t10; \
+ y = ~ t13; \
+ t15 = x & t03; \
+ z = t12 ^ t07; \
+ t17 = a ^ b ; \
+ t18 = y ^ t15; \
+ w = t17 ^ t18; \
+ }
+
+#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t07, t08, t09; \
+ u32 t12, t13, t14, t15, t16, t17, t01; \
+ t01 = a ^ c ; \
+ t02 = ~ c ; \
+ t03 = b & t01; \
+ t04 = b | t02; \
+ t05 = d | t03; \
+ t06 = b ^ d ; \
+ t07 = a & t04; \
+ t08 = a | t02; \
+ t09 = t07 ^ t05; \
+ x = t06 ^ t08; \
+ w = ~ t09; \
+ t12 = b & w ; \
+ t13 = t01 & t05; \
+ t14 = t01 ^ t12; \
+ t15 = t07 ^ t13; \
+ t16 = d | t02; \
+ t17 = a ^ x ; \
+ z = t17 ^ t15; \
+ y = t16 ^ t14; \
+ }
+
+#define SBOX7(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t05, t06, t08, t09, t10; \
+ u32 t11, t13, t14, t15, t16, t17, t01; \
+ t01 = a & c ; \
+ t02 = ~ d ; \
+ t03 = a & t02; \
+ t04 = b | t01; \
+ t05 = a & b ; \
+ t06 = c ^ t04; \
+ z = t03 ^ t06; \
+ t08 = c | z ; \
+ t09 = d | t05; \
+ t10 = a ^ t08; \
+ t11 = t04 & z ; \
+ x = t09 ^ t10; \
+ t13 = b ^ x ; \
+ t14 = t01 ^ x ; \
+ t15 = c ^ t05; \
+ t16 = t11 | t13; \
+ t17 = t02 | t14; \
+ w = t15 ^ t17; \
+ y = a ^ t16; \
+ }
+
+#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
+ { \
+ u32 t02, t03, t04, t06, t07, t08, t09; \
+ u32 t10, t11, t13, t14, t15, t16, t01; \
+ t01 = a & b ; \
+ t02 = a | b ; \
+ t03 = c | t01; \
+ t04 = d & t02; \
+ z = t03 ^ t04; \
+ t06 = b ^ t04; \
+ t07 = d ^ z ; \
+ t08 = ~ t07; \
+ t09 = t06 | t08; \
+ t10 = b ^ d ; \
+ t11 = a | d ; \
+ x = a ^ t09; \
+ t13 = c ^ t06; \
+ t14 = c & t11; \
+ t15 = d | x ; \
+ t16 = t01 | t10; \
+ w = t13 ^ t15; \
+ y = t14 ^ t16; \
+ }
+
+/* XOR BLOCK1 into BLOCK0. */
+#define BLOCK_XOR(block0, block1) \
+ { \
+ block0[0] ^= block1[0]; \
+ block0[1] ^= block1[1]; \
+ block0[2] ^= block1[2]; \
+ block0[3] ^= block1[3]; \
+ }
+
+/* Copy BLOCK_SRC to BLOCK_DST. */
+#define BLOCK_COPY(block_dst, block_src) \
+ { \
+ block_dst[0] = block_src[0]; \
+ block_dst[1] = block_src[1]; \
+ block_dst[2] = block_src[2]; \
+ block_dst[3] = block_src[3]; \
+ }
+
+/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
+ INDEX, writing the output to the block found in ARRAY1 at index
+ INDEX. */
+#define SBOX(which, array0, array1, index) \
+ SBOX##which (array0[index + 0], array0[index + 1], \
+ array0[index + 2], array0[index + 3], \
+ array1[index + 0], array1[index + 1], \
+ array1[index + 2], array1[index + 3]);
+
+/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
+ index INDEX, writing the output to the block found in ARRAY1 at
+ index INDEX. */
+#define SBOX_INVERSE(which, array0, array1, index) \
+ SBOX##which##_INVERSE (array0[index + 0], array0[index + 1], \
+ array0[index + 2], array0[index + 3], \
+ array1[index + 0], array1[index + 1], \
+ array1[index + 2], array1[index + 3]);
+
+/* Apply the linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION(block) \
+ { \
+ block[0] = rol (block[0], 13); \
+ block[2] = rol (block[2], 3); \
+ block[1] = block[1] ^ block[0] ^ block[2]; \
+ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+ block[1] = rol (block[1], 1); \
+ block[3] = rol (block[3], 7); \
+ block[0] = block[0] ^ block[1] ^ block[3]; \
+ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+ block[0] = rol (block[0], 5); \
+ block[2] = rol (block[2], 22); \
+ }
+
+/* Apply the inverse linear transformation to BLOCK. */
+#define LINEAR_TRANSFORMATION_INVERSE(block) \
+ { \
+ block[2] = ror (block[2], 22); \
+ block[0] = ror (block[0] , 5); \
+ block[2] = block[2] ^ block[3] ^ (block[1] << 7); \
+ block[0] = block[0] ^ block[1] ^ block[3]; \
+ block[3] = ror (block[3], 7); \
+ block[1] = ror (block[1], 1); \
+ block[3] = block[3] ^ block[2] ^ (block[0] << 3); \
+ block[1] = block[1] ^ block[0] ^ block[2]; \
+ block[2] = ror (block[2], 3); \
+ block[0] = ror (block[0], 13); \
+ }
+
+/* Apply a Serpent round to BLOCK, using the SBOX number WHICH and the
+ subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary storage.
+ This macro increments `round'. */
+#define ROUND(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round++; \
+ SBOX (which, block, block_tmp, 0); \
+ LINEAR_TRANSFORMATION (block_tmp); \
+ BLOCK_COPY (block, block_tmp); \
+ }
+
+/* Apply the last Serpent round to BLOCK, using the SBOX number WHICH
+ and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
+ storage. The result will be stored in BLOCK_TMP. This macro
+ increments `round'. */
+#define ROUND_LAST(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round++; \
+ SBOX (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkeys[round]); \
+ round++; \
+ }
+
+/* Apply an inverse Serpent round to BLOCK, using the SBOX number
+ WHICH and the subkeys contained in SUBKEYS. Use BLOCK_TMP as
+ temporary storage. This macro increments `round'. */
+#define ROUND_INVERSE(which, subkey, block, block_tmp) \
+ { \
+ LINEAR_TRANSFORMATION_INVERSE (block); \
+ SBOX_INVERSE (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkey[round]); \
+ round--; \
+ BLOCK_COPY (block, block_tmp); \
+ }
+
+/* Apply the first Serpent round to BLOCK, using the SBOX number WHICH
+ and the subkeys contained in SUBKEYS. Use BLOCK_TMP as temporary
+ storage. The result will be stored in BLOCK_TMP. This macro
+ increments `round'. */
+#define ROUND_FIRST_INVERSE(which, subkeys, block, block_tmp) \
+ { \
+ BLOCK_XOR (block, subkeys[round]); \
+ round--; \
+ SBOX_INVERSE (which, block, block_tmp, 0); \
+ BLOCK_XOR (block_tmp, subkeys[round]); \
+ round--; \
+ }
+
+/* Convert the user provided key KEY of KEY_LENGTH bytes into the
+ internally used format. */
+static void
+serpent_key_prepare (const byte *key, unsigned int key_length,
+ serpent_key_t key_prepared)
+{
+ int i;
+
+ /* Copy key. */
+ for (i = 0; i < key_length / 4; i++)
+ {
+#ifdef WORDS_BIGENDIAN
+ key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
+#else
+ key_prepared[i] = ((u32 *) key)[i];
+#endif
+ }
+
+ if (i < 8)
+ {
+ /* Key must be padded according to the Serpent
+ specification. */
+ key_prepared[i] = 0x00000001;
+
+ for (i++; i < 8; i++)
+ key_prepared[i] = 0;
+ }
+}
+
+/* Derive the 33 subkeys from KEY and store them in SUBKEYS. */
+static void
+serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
+{
+ u32 w_real[140]; /* The `prekey'. */
+ u32 k[132];
+ u32 *w = &w_real[8];
+ int i, j;
+
+ /* Initialize with key values. */
+ for (i = 0; i < 8; i++)
+ w[i - 8] = key[i];
+
+ /* Expand to intermediate key using the affine recurrence. */
+ for (i = 0; i < 132; i++)
+ w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
+
+ /* Calculate subkeys via S-Boxes, in bitslice mode. */
+ SBOX (3, w, k, 0);
+ SBOX (2, w, k, 4);
+ SBOX (1, w, k, 8);
+ SBOX (0, w, k, 12);
+ SBOX (7, w, k, 16);
+ SBOX (6, w, k, 20);
+ SBOX (5, w, k, 24);
+ SBOX (4, w, k, 28);
+ SBOX (3, w, k, 32);
+ SBOX (2, w, k, 36);
+ SBOX (1, w, k, 40);
+ SBOX (0, w, k, 44);
+ SBOX (7, w, k, 48);
+ SBOX (6, w, k, 52);
+ SBOX (5, w, k, 56);
+ SBOX (4, w, k, 60);
+ SBOX (3, w, k, 64);
+ SBOX (2, w, k, 68);
+ SBOX (1, w, k, 72);
+ SBOX (0, w, k, 76);
+ SBOX (7, w, k, 80);
+ SBOX (6, w, k, 84);
+ SBOX (5, w, k, 88);
+ SBOX (4, w, k, 92);
+ SBOX (3, w, k, 96);
+ SBOX (2, w, k, 100);
+ SBOX (1, w, k, 104);
+ SBOX (0, w, k, 108);
+ SBOX (7, w, k, 112);
+ SBOX (6, w, k, 116);
+ SBOX (5, w, k, 120);
+ SBOX (4, w, k, 124);
+ SBOX (3, w, k, 128);
+
+ /* Renumber subkeys. */
+ for (i = 0; i < ROUNDS + 1; i++)
+ for (j = 0; j < 4; j++)
+ subkeys[i][j] = k[4 * i + j];
+}
+
+/* Initialize CONTEXT with the key KEY of KEY_LENGTH bits. */
+static void
+serpent_setkey_internal (serpent_context_t *context,
+ const byte *key, unsigned int key_length)
+{
+ serpent_key_t key_prepared;
+
+ serpent_key_prepare (key, key_length, key_prepared);
+ serpent_subkeys_generate (key_prepared, context->keys);
+ _gcry_burn_stack (272 * sizeof (u32));
+}
+
+/* Initialize CTX with the key KEY of KEY_LENGTH bytes. */
+static gcry_err_code_t
+serpent_setkey (void *ctx,
+ const byte *key, unsigned int key_length)
+{
+ serpent_context_t *context = ctx;
+ static const char *serpent_test_ret;
+ static int serpent_init_done;
+ gcry_err_code_t ret = GPG_ERR_NO_ERROR;
+
+ if (! serpent_init_done)
+ {
+ /* Execute a self-test the first time, Serpent is used. */
+ serpent_test_ret = serpent_test ();
+ if (serpent_test_ret)
+ log_error ("Serpent test failure: %s\n", serpent_test_ret);
+ serpent_init_done = 1;
+ }
+
+ if (serpent_test_ret)
+ ret = GPG_ERR_SELFTEST_FAILED;
+ else
+ {
+ serpent_setkey_internal (context, key, key_length);
+ _gcry_burn_stack (sizeof (serpent_key_t));
+ }
+
+ return ret;
+}
+
+static void
+serpent_encrypt_internal (serpent_context_t *context,
+ const serpent_block_t input, serpent_block_t output)
+{
+ serpent_block_t b, b_next;
+ int round = 0;
+
+#ifdef WORDS_BIGENDIAN
+ b[0] = byte_swap_32 (input[0]);
+ b[1] = byte_swap_32 (input[1]);
+ b[2] = byte_swap_32 (input[2]);
+ b[3] = byte_swap_32 (input[3]);
+#else
+ b[0] = input[0];
+ b[1] = input[1];
+ b[2] = input[2];
+ b[3] = input[3];
+#endif
+
+ ROUND (0, context->keys, b, b_next);
+ ROUND (1, context->keys, b, b_next);
+ ROUND (2, context->keys, b, b_next);
+ ROUND (3, context->keys, b, b_next);
+ ROUND (4, context->keys, b, b_next);
+ ROUND (5, context->keys, b, b_next);
+ ROUND (6, context->keys, b, b_next);
+ ROUND (7, context->keys, b, b_next);
+ ROUND (0, context->keys, b, b_next);
+ ROUND (1, context->keys, b, b_next);
+ ROUND (2, context->keys, b, b_next);
+ ROUND (3, context->keys, b, b_next);
+ ROUND (4, context->keys, b, b_next);
+ ROUND (5, context->keys, b, b_next);
+ ROUND (6, context->keys, b, b_next);
+ ROUND (7, context->keys, b, b_next);
+ ROUND (0, context->keys, b, b_next);
+ ROUND (1, context->keys, b, b_next);
+ ROUND (2, context->keys, b, b_next);
+ ROUND (3, context->keys, b, b_next);
+ ROUND (4, context->keys, b, b_next);
+ ROUND (5, context->keys, b, b_next);
+ ROUND (6, context->keys, b, b_next);
+ ROUND (7, context->keys, b, b_next);
+ ROUND (0, context->keys, b, b_next);
+ ROUND (1, context->keys, b, b_next);
+ ROUND (2, context->keys, b, b_next);
+ ROUND (3, context->keys, b, b_next);
+ ROUND (4, context->keys, b, b_next);
+ ROUND (5, context->keys, b, b_next);
+ ROUND (6, context->keys, b, b_next);
+
+ ROUND_LAST (7, context->keys, b, b_next);
+
+#ifdef WORDS_BIGENDIAN
+ output[0] = byte_swap_32 (b_next[0]);
+ output[1] = byte_swap_32 (b_next[1]);
+ output[2] = byte_swap_32 (b_next[2]);
+ output[3] = byte_swap_32 (b_next[3]);
+#else
+ output[0] = b_next[0];
+ output[1] = b_next[1];
+ output[2] = b_next[2];
+ output[3] = b_next[3];
+#endif
+}
+
+static void
+serpent_decrypt_internal (serpent_context_t *context,
+ const serpent_block_t input, serpent_block_t output)
+{
+ serpent_block_t b, b_next;
+ int round = ROUNDS;
+
+#ifdef WORDS_BIGENDIAN
+ b_next[0] = byte_swap_32 (input[0]);
+ b_next[1] = byte_swap_32 (input[1]);
+ b_next[2] = byte_swap_32 (input[2]);
+ b_next[3] = byte_swap_32 (input[3]);
+#else
+ b_next[0] = input[0];
+ b_next[1] = input[1];
+ b_next[2] = input[2];
+ b_next[3] = input[3];
+#endif
+
+ ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
+
+ ROUND_INVERSE (6, context->keys, b, b_next);
+ ROUND_INVERSE (5, context->keys, b, b_next);
+ ROUND_INVERSE (4, context->keys, b, b_next);
+ ROUND_INVERSE (3, context->keys, b, b_next);
+ ROUND_INVERSE (2, context->keys, b, b_next);
+ ROUND_INVERSE (1, context->keys, b, b_next);
+ ROUND_INVERSE (0, context->keys, b, b_next);
+ ROUND_INVERSE (7, context->keys, b, b_next);
+ ROUND_INVERSE (6, context->keys, b, b_next);
+ ROUND_INVERSE (5, context->keys, b, b_next);
+ ROUND_INVERSE (4, context->keys, b, b_next);
+ ROUND_INVERSE (3, context->keys, b, b_next);
+ ROUND_INVERSE (2, context->keys, b, b_next);
+ ROUND_INVERSE (1, context->keys, b, b_next);
+ ROUND_INVERSE (0, context->keys, b, b_next);
+ ROUND_INVERSE (7, context->keys, b, b_next);
+ ROUND_INVERSE (6, context->keys, b, b_next);
+ ROUND_INVERSE (5, context->keys, b, b_next);
+ ROUND_INVERSE (4, context->keys, b, b_next);
+ ROUND_INVERSE (3, context->keys, b, b_next);
+ ROUND_INVERSE (2, context->keys, b, b_next);
+ ROUND_INVERSE (1, context->keys, b, b_next);
+ ROUND_INVERSE (0, context->keys, b, b_next);
+ ROUND_INVERSE (7, context->keys, b, b_next);
+ ROUND_INVERSE (6, context->keys, b, b_next);
+ ROUND_INVERSE (5, context->keys, b, b_next);
+ ROUND_INVERSE (4, context->keys, b, b_next);
+ ROUND_INVERSE (3, context->keys, b, b_next);
+ ROUND_INVERSE (2, context->keys, b, b_next);
+ ROUND_INVERSE (1, context->keys, b, b_next);
+ ROUND_INVERSE (0, context->keys, b, b_next);
+
+
+#ifdef WORDS_BIGENDIAN
+ output[0] = byte_swap_32 (b_next[0]);
+ output[1] = byte_swap_32 (b_next[1]);
+ output[2] = byte_swap_32 (b_next[2]);
+ output[3] = byte_swap_32 (b_next[3]);
+#else
+ output[0] = b_next[0];
+ output[1] = b_next[1];
+ output[2] = b_next[2];
+ output[3] = b_next[3];
+#endif
+}
+
+static void
+serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
+{
+ serpent_context_t *context = ctx;
+
+ serpent_encrypt_internal (context,
+ (const u32 *) buffer_in, (u32 *) buffer_out);
+ _gcry_burn_stack (2 * sizeof (serpent_block_t));
+}
+
+static void
+serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
+{
+ serpent_context_t *context = ctx;
+
+ serpent_decrypt_internal (context,
+ (const u32 *) buffer_in,
+ (u32 *) buffer_out);
+ _gcry_burn_stack (2 * sizeof (serpent_block_t));
+}
+
+\f
+
+/* Serpent test. */
+
+static const char *
+serpent_test (void)
+{
+ serpent_context_t context;
+ unsigned char scratch[16];
+ unsigned int i;
+
+ static struct test
+ {
+ int key_length;
+ unsigned char key[32];
+ unsigned char text_plain[16];
+ unsigned char text_cipher[16];
+ } test_data[] =
+ {
+ {
+ 16,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xD2\x9D\x57\x6F\xCE\xA3\xA3\xA7\xED\x90\x99\xF2\x92\x73\xD7\x8E",
+ "\xB2\x28\x8B\x96\x8A\xE8\xB0\x86\x48\xD1\xCE\x96\x06\xFD\x99\x2D"
+ },
+ {
+ 24,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xD2\x9D\x57\x6F\xCE\xAB\xA3\xA7\xED\x98\x99\xF2\x92\x7B\xD7\x8E",
+ "\x13\x0E\x35\x3E\x10\x37\xC2\x24\x05\xE8\xFA\xEF\xB2\xC3\xC3\xE9"
+ },
+ {
+ 32,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\xD0\x95\x57\x6F\xCE\xA3\xE3\xA7\xED\x98\xD9\xF2\x90\x73\xD7\x8E",
+ "\xB9\x0E\xE5\x86\x2D\xE6\x91\x68\xF2\xBD\xD5\x12\x5B\x45\x47\x2B"
+ },
+ {
+ 32,
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+ "\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00",
+ "\x20\x61\xA4\x27\x82\xBD\x52\xEC\x69\x1E\xC3\x83\xB0\x3B\xA7\x7C"
+ },
+ {
+ 0
+ },
+ };
+
+ for (i = 0; test_data[i].key_length; i++)
+ {
+ serpent_setkey_internal (&context, test_data[i].key,
+ test_data[i].key_length);
+ serpent_encrypt_internal (&context,
+ (const u32 *) test_data[i].text_plain,
+ (u32 *) scratch);
+
+ if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
+ switch (test_data[i].key_length)
+ {
+ case 16:
+ return "Serpent-128 test encryption failed.";
+ case 24:
+ return "Serpent-192 test encryption failed.";
+ case 32:
+ return "Serpent-256 test encryption failed.";
+ }
+
+ serpent_decrypt_internal (&context,
+ (const u32 *) test_data[i].text_cipher,
+ (u32 *) scratch);
+ if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
+ switch (test_data[i].key_length)
+ {
+ case 16:
+ return "Serpent-128 test decryption failed.";
+ case 24:
+ return "Serpent-192 test decryption failed.";
+ case 32:
+ return "Serpent-256 test decryption failed.";
+ }
+ }
+
+ return NULL;
+}
+
+\f
+
+/* "SERPENT" is an alias for "SERPENT128". */
+static const char *cipher_spec_serpent128_aliases[] =
+ {
+ "SERPENT",
+ NULL
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
+ {
+ "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
+ sizeof (serpent_context_t),
+ serpent_setkey, serpent_encrypt, serpent_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent192 =
+ {
+ "SERPENT192", NULL, NULL, 16, 192,
+ sizeof (serpent_context_t),
+ serpent_setkey, serpent_encrypt, serpent_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_serpent256 =
+ {
+ "SERPENT256", NULL, NULL, 16, 256,
+ sizeof (serpent_context_t),
+ serpent_setkey, serpent_encrypt, serpent_decrypt
+ };
--- /dev/null
+/* sha1.c - SHA1 hash function
+ * Copyright (C) 1998, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors:
+ *
+ * "abc"
+ * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D
+ *
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+/* A macro to test whether P is properly aligned for an u32 type.
+ Note that config.h provides a suitable replacement for uintptr_t if
+ it does not exist in stdint.h. */
+/* #if __GNUC__ >= 2 */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % __alignof__ (u32))) */
+/* #else */
+/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
+/* #endif */
+
+#define TRANSFORM(x,d,n) transform ((x), (d), (n))
+
+
+typedef struct
+{
+ u32 h0,h1,h2,h3,h4;
+ u32 nblocks;
+ unsigned char buf[64];
+ int count;
+} SHA1_CONTEXT;
+
+
+
+static void
+sha1_init (void *context)
+{
+ SHA1_CONTEXT *hd = context;
+
+ hd->h0 = 0x67452301;
+ hd->h1 = 0xefcdab89;
+ hd->h2 = 0x98badcfe;
+ hd->h3 = 0x10325476;
+ hd->h4 = 0xc3d2e1f0;
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+
+/* Round function macros. */
+#define K1 0x5A827999L
+#define K2 0x6ED9EBA1L
+#define K3 0x8F1BBCDCL
+#define K4 0xCA62C1D6L
+#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) )
+#define F2(x,y,z) ( x ^ y ^ z )
+#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) )
+#define F4(x,y,z) ( x ^ y ^ z )
+#define M(i) ( tm = x[ i &0x0f] \
+ ^ x[(i-14)&0x0f] \
+ ^ x[(i-8) &0x0f] \
+ ^ x[(i-3) &0x0f], \
+ (x[i&0x0f] = rol(tm, 1)))
+#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \
+ + f( b, c, d ) \
+ + k \
+ + m; \
+ b = rol( b, 30 ); \
+ } while(0)
+
+
+/*
+ * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
+ */
+static void
+transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
+{
+ register u32 a, b, c, d, e; /* Local copies of the chaining variables. */
+ register u32 tm; /* Helper. */
+ u32 x[16]; /* The array we work on. */
+
+ /* Loop over all blocks. */
+ for ( ;nblocks; nblocks--)
+ {
+#ifdef WORDS_BIGENDIAN
+ memcpy (x, data, 64);
+ data += 64;
+#else
+ {
+ int i;
+ unsigned char *p;
+
+ for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
+ {
+ p[3] = *data++;
+ p[2] = *data++;
+ p[1] = *data++;
+ p[0] = *data++;
+ }
+ }
+#endif
+ /* Get the values of the chaining variables. */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+
+ /* Transform. */
+ R( a, b, c, d, e, F1, K1, x[ 0] );
+ R( e, a, b, c, d, F1, K1, x[ 1] );
+ R( d, e, a, b, c, F1, K1, x[ 2] );
+ R( c, d, e, a, b, F1, K1, x[ 3] );
+ R( b, c, d, e, a, F1, K1, x[ 4] );
+ R( a, b, c, d, e, F1, K1, x[ 5] );
+ R( e, a, b, c, d, F1, K1, x[ 6] );
+ R( d, e, a, b, c, F1, K1, x[ 7] );
+ R( c, d, e, a, b, F1, K1, x[ 8] );
+ R( b, c, d, e, a, F1, K1, x[ 9] );
+ R( a, b, c, d, e, F1, K1, x[10] );
+ R( e, a, b, c, d, F1, K1, x[11] );
+ R( d, e, a, b, c, F1, K1, x[12] );
+ R( c, d, e, a, b, F1, K1, x[13] );
+ R( b, c, d, e, a, F1, K1, x[14] );
+ R( a, b, c, d, e, F1, K1, x[15] );
+ R( e, a, b, c, d, F1, K1, M(16) );
+ R( d, e, a, b, c, F1, K1, M(17) );
+ R( c, d, e, a, b, F1, K1, M(18) );
+ R( b, c, d, e, a, F1, K1, M(19) );
+ R( a, b, c, d, e, F2, K2, M(20) );
+ R( e, a, b, c, d, F2, K2, M(21) );
+ R( d, e, a, b, c, F2, K2, M(22) );
+ R( c, d, e, a, b, F2, K2, M(23) );
+ R( b, c, d, e, a, F2, K2, M(24) );
+ R( a, b, c, d, e, F2, K2, M(25) );
+ R( e, a, b, c, d, F2, K2, M(26) );
+ R( d, e, a, b, c, F2, K2, M(27) );
+ R( c, d, e, a, b, F2, K2, M(28) );
+ R( b, c, d, e, a, F2, K2, M(29) );
+ R( a, b, c, d, e, F2, K2, M(30) );
+ R( e, a, b, c, d, F2, K2, M(31) );
+ R( d, e, a, b, c, F2, K2, M(32) );
+ R( c, d, e, a, b, F2, K2, M(33) );
+ R( b, c, d, e, a, F2, K2, M(34) );
+ R( a, b, c, d, e, F2, K2, M(35) );
+ R( e, a, b, c, d, F2, K2, M(36) );
+ R( d, e, a, b, c, F2, K2, M(37) );
+ R( c, d, e, a, b, F2, K2, M(38) );
+ R( b, c, d, e, a, F2, K2, M(39) );
+ R( a, b, c, d, e, F3, K3, M(40) );
+ R( e, a, b, c, d, F3, K3, M(41) );
+ R( d, e, a, b, c, F3, K3, M(42) );
+ R( c, d, e, a, b, F3, K3, M(43) );
+ R( b, c, d, e, a, F3, K3, M(44) );
+ R( a, b, c, d, e, F3, K3, M(45) );
+ R( e, a, b, c, d, F3, K3, M(46) );
+ R( d, e, a, b, c, F3, K3, M(47) );
+ R( c, d, e, a, b, F3, K3, M(48) );
+ R( b, c, d, e, a, F3, K3, M(49) );
+ R( a, b, c, d, e, F3, K3, M(50) );
+ R( e, a, b, c, d, F3, K3, M(51) );
+ R( d, e, a, b, c, F3, K3, M(52) );
+ R( c, d, e, a, b, F3, K3, M(53) );
+ R( b, c, d, e, a, F3, K3, M(54) );
+ R( a, b, c, d, e, F3, K3, M(55) );
+ R( e, a, b, c, d, F3, K3, M(56) );
+ R( d, e, a, b, c, F3, K3, M(57) );
+ R( c, d, e, a, b, F3, K3, M(58) );
+ R( b, c, d, e, a, F3, K3, M(59) );
+ R( a, b, c, d, e, F4, K4, M(60) );
+ R( e, a, b, c, d, F4, K4, M(61) );
+ R( d, e, a, b, c, F4, K4, M(62) );
+ R( c, d, e, a, b, F4, K4, M(63) );
+ R( b, c, d, e, a, F4, K4, M(64) );
+ R( a, b, c, d, e, F4, K4, M(65) );
+ R( e, a, b, c, d, F4, K4, M(66) );
+ R( d, e, a, b, c, F4, K4, M(67) );
+ R( c, d, e, a, b, F4, K4, M(68) );
+ R( b, c, d, e, a, F4, K4, M(69) );
+ R( a, b, c, d, e, F4, K4, M(70) );
+ R( e, a, b, c, d, F4, K4, M(71) );
+ R( d, e, a, b, c, F4, K4, M(72) );
+ R( c, d, e, a, b, F4, K4, M(73) );
+ R( b, c, d, e, a, F4, K4, M(74) );
+ R( a, b, c, d, e, F4, K4, M(75) );
+ R( e, a, b, c, d, F4, K4, M(76) );
+ R( d, e, a, b, c, F4, K4, M(77) );
+ R( c, d, e, a, b, F4, K4, M(78) );
+ R( b, c, d, e, a, F4, K4, M(79) );
+
+ /* Update the chaining variables. */
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ }
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+sha1_write( void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ SHA1_CONTEXT *hd = context;
+ size_t nblocks;
+
+ if (hd->count == 64) /* Flush the buffer. */
+ {
+ TRANSFORM( hd, hd->buf, 1 );
+ _gcry_burn_stack (88+4*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return;
+
+ if (hd->count)
+ {
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ sha1_write (hd, NULL, 0);
+ if (!inlen)
+ return;
+ }
+
+ nblocks = inlen / 64;
+ if (nblocks)
+ {
+ TRANSFORM (hd, inbuf, nblocks);
+ hd->count = 0;
+ hd->nblocks += nblocks;
+ inlen -= nblocks * 64;
+ inbuf += nblocks * 64;
+ }
+ _gcry_burn_stack (88+4*sizeof(void*));
+
+ /* Save remaining bytes. */
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 20 bytes representing the digest.
+ */
+
+static void
+sha1_final(void *context)
+{
+ SHA1_CONTEXT *hd = context;
+
+ u32 t, msb, lsb;
+ unsigned char *p;
+
+ sha1_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) /* enough room */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else /* need one extra block */
+ {
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ sha1_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = msb >> 24;
+ hd->buf[57] = msb >> 16;
+ hd->buf[58] = msb >> 8;
+ hd->buf[59] = msb ;
+ hd->buf[60] = lsb >> 24;
+ hd->buf[61] = lsb >> 16;
+ hd->buf[62] = lsb >> 8;
+ hd->buf[63] = lsb ;
+ TRANSFORM( hd, hd->buf, 1 );
+ _gcry_burn_stack (88+4*sizeof(void*));
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+#endif
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+#undef X
+
+}
+
+static unsigned char *
+sha1_read( void *context )
+{
+ SHA1_CONTEXT *hd = context;
+
+ return hd->buf;
+}
+
+/****************
+ * Shortcut functions which puts the hash value of the supplied buffer
+ * into outbuf which must have a size of 20 bytes.
+ */
+void
+_gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
+{
+ SHA1_CONTEXT hd;
+
+ sha1_init (&hd);
+ sha1_write (&hd, buffer, length);
+ sha1_final (&hd);
+ memcpy (outbuf, hd.buf, 20);
+}
+
+
+\f
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha1 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 0,
+ "abc", 3,
+ "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
+ "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
+ "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA1, 1,
+ NULL, 0,
+ "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
+ "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA1, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA1:
+ ec = selftests_sha1 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static unsigned char asn[15] = /* Object ID is 1.3.14.3.2.26 */
+ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
+ 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 };
+
+static gcry_md_oid_spec_t oid_spec_sha1[] =
+ {
+ /* iso.member-body.us.rsadsi.pkcs.pkcs-1.5 (sha1WithRSAEncryption) */
+ { "1.2.840.113549.1.1.5" },
+ /* iso.member-body.us.x9-57.x9cm.3 (dsaWithSha1)*/
+ { "1.2.840.10040.4.3" },
+ /* from NIST's OIW (sha1) */
+ { "1.3.14.3.2.26" },
+ /* from NIST OIW (sha-1WithRSAEncryption) */
+ { "1.3.14.3.2.29" },
+ /* iso.member-body.us.ansi-x9-62.signatures.ecdsa-with-sha1 */
+ { "1.2.840.10045.4.1" },
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha1 =
+ {
+ "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
+ sha1_init, sha1_write, sha1_final, sha1_read,
+ sizeof (SHA1_CONTEXT)
+ };
+md_extra_spec_t _gcry_digest_extraspec_sha1 =
+ {
+ run_selftests
+ };
--- /dev/null
+/* sha256.c - SHA256 hash function
+ * Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors:
+
+ "abc"
+ SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
+ SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
+
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
+ SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
+
+ "a" one million times
+ SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
+ SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
+
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+typedef struct {
+ u32 h0,h1,h2,h3,h4,h5,h6,h7;
+ u32 nblocks;
+ byte buf[64];
+ int count;
+} SHA256_CONTEXT;
+
+
+static void
+sha256_init (void *context)
+{
+ SHA256_CONTEXT *hd = context;
+
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+
+static void
+sha224_init (void *context)
+{
+ SHA256_CONTEXT *hd = context;
+
+ hd->h0 = 0xc1059ed8;
+ hd->h1 = 0x367cd507;
+ hd->h2 = 0x3070dd17;
+ hd->h3 = 0xf70e5939;
+ hd->h4 = 0xffc00b31;
+ hd->h5 = 0x68581511;
+ hd->h6 = 0x64f98fa7;
+ hd->h7 = 0xbefa4fa4;
+
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+
+/*
+ Transform the message X which consists of 16 32-bit-words. See FIPS
+ 180-2 for details. */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ h = g; \
+ g = f; \
+ f = e; \
+ e = d + t1; \
+ d = c; \
+ c = b; \
+ b = a; \
+ a = t1 + t2; \
+ } while (0)
+
+/* (4.2) same as SHA-1's F1. */
+static inline u32
+Cho (u32 x, u32 y, u32 z)
+{
+ return (z ^ (x & (y ^ z)));
+}
+
+/* (4.3) same as SHA-1's F3 */
+static inline u32
+Maj (u32 x, u32 y, u32 z)
+{
+ return ((x & y) | (z & (x|y)));
+}
+
+/* (4.4) */
+static inline u32
+Sum0 (u32 x)
+{
+ return (ror (x, 2) ^ ror (x, 13) ^ ror (x, 22));
+}
+
+/* (4.5) */
+static inline u32
+Sum1 (u32 x)
+{
+ return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25));
+}
+
+
+static void
+transform (SHA256_CONTEXT *hd, const unsigned char *data)
+{
+ static const u32 K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ u32 a,b,c,d,e,f,g,h,t1,t2;
+ u32 x[16];
+ u32 w[64];
+ int i;
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy (x, data, 64);
+#else
+ {
+ byte *p2;
+
+ for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif
+
+ for (i=0; i < 16; i++)
+ w[i] = x[i];
+ for (; i < 64; i++)
+ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+ for (i=0; i < 64;)
+ {
+#if 0
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+ i++;
+#else
+ t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Cho (d, e, f) + K[i+1] + w[i+1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Cho (c, d, e) + K[i+2] + w[i+2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Cho (b, c, d) + K[i+3] + w[i+3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Cho (a, b, c) + K[i+4] + w[i+4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Cho (h, a, b) + K[i+5] + w[i+5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Cho (g, h, a) + K[i+6] + w[i+6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Cho (f, g, h) + K[i+7] + w[i+7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ i += 8;
+#endif
+ }
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+}
+#undef S0
+#undef S1
+#undef R
+
+
+/* Update the message digest with the contents of INBUF with length
+ INLEN. */
+static void
+sha256_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ SHA256_CONTEXT *hd = context;
+
+ if (hd->count == 64)
+ { /* flush the buffer */
+ transform (hd, hd->buf);
+ _gcry_burn_stack (74*4+32);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return;
+ if (hd->count)
+ {
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ sha256_write (hd, NULL, 0);
+ if (!inlen)
+ return;
+ }
+
+ while (inlen >= 64)
+ {
+ transform (hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ _gcry_burn_stack (74*4+32);
+ for (; inlen && hd->count < 64; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/*
+ The routine finally terminates the computation and returns the
+ digest. The handle is prepared for a new cycle, but adding bytes
+ to the handle will the destroy the returned buffer. Returns: 32
+ bytes with the message the digest. */
+static void
+sha256_final(void *context)
+{
+ SHA256_CONTEXT *hd = context;
+ u32 t, msb, lsb;
+ byte *p;
+
+ sha256_write (hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56)
+ { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ sha256_write (hd, NULL, 0); /* flush */;
+ memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = msb >> 24;
+ hd->buf[57] = msb >> 16;
+ hd->buf[58] = msb >> 8;
+ hd->buf[59] = msb;
+ hd->buf[60] = lsb >> 24;
+ hd->buf[61] = lsb >> 16;
+ hd->buf[62] = lsb >> 8;
+ hd->buf[63] = lsb;
+ transform (hd, hd->buf);
+ _gcry_burn_stack (74*4+32);
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+#endif
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+}
+
+static byte *
+sha256_read (void *context)
+{
+ SHA256_CONTEXT *hd = context;
+
+ return hd->buf;
+}
+
+
+\f
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha224 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 0,
+ "abc", 3,
+ "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
+ "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
+ "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA224, 1,
+ NULL, 0,
+ "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
+ "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA224, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha256 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 0,
+ "abc", 3,
+ "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
+ "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad", 32);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 0,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
+ "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+ "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1",
+ 32);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA256, 1,
+ NULL, 0,
+ "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
+ "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0",
+ 32);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA256, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA224:
+ ec = selftests_sha224 (extended, report);
+ break;
+ case GCRY_MD_SHA256:
+ ec = selftests_sha256 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static byte asn224[19] = /* Object ID is 2.16.840.1.101.3.4.2.4 */
+ { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+ 0x1C
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha224[] =
+ {
+ /* From RFC3874, Section 4 */
+ { "2.16.840.1.101.3.4.2.4" },
+ { NULL },
+ };
+
+static byte asn256[19] = /* Object ID is 2.16.840.1.101.3.4.2.1 */
+ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
+ 0x00, 0x04, 0x20 };
+
+static gcry_md_oid_spec_t oid_spec_sha256[] =
+ {
+ /* According to the OpenPGP draft rfc2440-bis06 */
+ { "2.16.840.1.101.3.4.2.1" },
+ /* PKCS#1 sha256WithRSAEncryption */
+ { "1.2.840.113549.1.1.11" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha224 =
+ {
+ "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
+ sha224_init, sha256_write, sha256_final, sha256_read,
+ sizeof (SHA256_CONTEXT)
+ };
+md_extra_spec_t _gcry_digest_extraspec_sha224 =
+ {
+ run_selftests
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha256 =
+ {
+ "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
+ sha256_init, sha256_write, sha256_final, sha256_read,
+ sizeof (SHA256_CONTEXT)
+ };
+md_extra_spec_t _gcry_digest_extraspec_sha256 =
+ {
+ run_selftests
+ };
--- /dev/null
+/* sha512.c - SHA384 and SHA512 hash functions
+ * Copyright (C) 2003, 2008, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* Test vectors from FIPS-180-2:
+ *
+ * "abc"
+ * 384:
+ * CB00753F 45A35E8B B5A03D69 9AC65007 272C32AB 0EDED163
+ * 1A8B605A 43FF5BED 8086072B A1E7CC23 58BAECA1 34C825A7
+ * 512:
+ * DDAF35A1 93617ABA CC417349 AE204131 12E6FA4E 89A97EA2 0A9EEEE6 4B55D39A
+ * 2192992A 274FC1A8 36BA3C23 A3FEEBBD 454D4423 643CE80E 2A9AC94F A54CA49F
+ *
+ * "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
+ * 384:
+ * 09330C33 F71147E8 3D192FC7 82CD1B47 53111B17 3B3B05D2
+ * 2FA08086 E3B0F712 FCC7C71A 557E2DB9 66C3E9FA 91746039
+ * 512:
+ * 8E959B75 DAE313DA 8CF4F728 14FC143F 8F7779C6 EB9F7FA1 7299AEAD B6889018
+ * 501D289E 4900F7E4 331B99DE C4B5433A C7D329EE B6DD2654 5E96E55B 874BE909
+ *
+ * "a" x 1000000
+ * 384:
+ * 9D0E1809 716474CB 086E834E 310A4A1C ED149E9C 00F24852
+ * 7972CEC5 704C2A5B 07B8B3DC 38ECC4EB AE97DDD8 7F3D8985
+ * 512:
+ * E718483D 0CE76964 4E2E42C7 BC15B463 8E1F98B1 3B204428 5632A803 AFA973EB
+ * DE0FF244 877EA60A 4CB0432C E577C31B EB009C5C 2C49AA2E 4EADB217 AD8CC09B
+ */
+
+
+#include <config.h>
+#include <string.h>
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+typedef struct
+{
+ u64 h0, h1, h2, h3, h4, h5, h6, h7;
+ u64 nblocks;
+ byte buf[128];
+ int count;
+} SHA512_CONTEXT;
+
+static void
+sha512_init (void *context)
+{
+ SHA512_CONTEXT *hd = context;
+
+ hd->h0 = U64_C(0x6a09e667f3bcc908);
+ hd->h1 = U64_C(0xbb67ae8584caa73b);
+ hd->h2 = U64_C(0x3c6ef372fe94f82b);
+ hd->h3 = U64_C(0xa54ff53a5f1d36f1);
+ hd->h4 = U64_C(0x510e527fade682d1);
+ hd->h5 = U64_C(0x9b05688c2b3e6c1f);
+ hd->h6 = U64_C(0x1f83d9abfb41bd6b);
+ hd->h7 = U64_C(0x5be0cd19137e2179);
+
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+static void
+sha384_init (void *context)
+{
+ SHA512_CONTEXT *hd = context;
+
+ hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
+ hd->h1 = U64_C(0x629a292a367cd507);
+ hd->h2 = U64_C(0x9159015a3070dd17);
+ hd->h3 = U64_C(0x152fecd8f70e5939);
+ hd->h4 = U64_C(0x67332667ffc00b31);
+ hd->h5 = U64_C(0x8eb44a8768581511);
+ hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
+ hd->h7 = U64_C(0x47b5481dbefa4fa4);
+
+ hd->nblocks = 0;
+ hd->count = 0;
+}
+
+
+static inline u64
+ROTR (u64 x, u64 n)
+{
+ return ((x >> n) | (x << (64 - n)));
+}
+
+static inline u64
+Ch (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ ( ~x & z));
+}
+
+static inline u64
+Maj (u64 x, u64 y, u64 z)
+{
+ return ((x & y) ^ (x & z) ^ (y & z));
+}
+
+static inline u64
+Sum0 (u64 x)
+{
+ return (ROTR (x, 28) ^ ROTR (x, 34) ^ ROTR (x, 39));
+}
+
+static inline u64
+Sum1 (u64 x)
+{
+ return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
+}
+
+/****************
+ * Transform the message W which consists of 16 64-bit-words
+ */
+static void
+transform (SHA512_CONTEXT *hd, const unsigned char *data)
+{
+ u64 a, b, c, d, e, f, g, h;
+ u64 w[80];
+ int t;
+ static const u64 k[] =
+ {
+ U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+ U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+ U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+ U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+ U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+ U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+ U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+ U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+ U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+ U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+ U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+ U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+ U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+ U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+ U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+ U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+ U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+ U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+ U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+ U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+ U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+ U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+ U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+ U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+ U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+ U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+ U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+ U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+ U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+ U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+ U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+ U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+ U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+ U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+ U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+ U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+ U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+ U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+ U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+ U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+ };
+
+ /* get values from the chaining vars */
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy (w, data, 128);
+#else
+ {
+ int i;
+ byte *p2;
+
+ for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
+ {
+ p2[7] = *data++;
+ p2[6] = *data++;
+ p2[5] = *data++;
+ p2[4] = *data++;
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif
+
+#define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
+#define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
+
+ for (t = 16; t < 80; t++)
+ w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
+
+
+ for (t = 0; t < 80; )
+ {
+ u64 t1, t2;
+
+ /* Performance on a AMD Athlon(tm) Dual Core Processor 4050e
+ with gcc 4.3.3 using gcry_md_hash_buffer of each 10000 bytes
+ initialized to 0,1,2,3...255,0,... and 1000 iterations:
+
+ Not unrolled with macros: 440ms
+ Unrolled with macros: 350ms
+ Unrolled with inline: 330ms
+ */
+#if 0 /* Not unrolled. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ t++;
+#else /* Unrolled to interweave the chain variables. */
+ t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+ t2 = Sum0 (a) + Maj (a, b, c);
+ d += t1;
+ h = t1 + t2;
+
+ t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1];
+ t2 = Sum0 (h) + Maj (h, a, b);
+ c += t1;
+ g = t1 + t2;
+
+ t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2];
+ t2 = Sum0 (g) + Maj (g, h, a);
+ b += t1;
+ f = t1 + t2;
+
+ t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3];
+ t2 = Sum0 (f) + Maj (f, g, h);
+ a += t1;
+ e = t1 + t2;
+
+ t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4];
+ t2 = Sum0 (e) + Maj (e, f, g);
+ h += t1;
+ d = t1 + t2;
+
+ t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5];
+ t2 = Sum0 (d) + Maj (d, e, f);
+ g += t1;
+ c = t1 + t2;
+
+ t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6];
+ t2 = Sum0 (c) + Maj (c, d, e);
+ f += t1;
+ b = t1 + t2;
+
+ t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7];
+ t2 = Sum0 (b) + Maj (b, c, d);
+ e += t1;
+ a = t1 + t2;
+
+ t += 8;
+#endif
+ }
+
+ /* Update chaining vars. */
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+}
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+sha512_write (void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ SHA512_CONTEXT *hd = context;
+
+ if (hd->count == 128)
+ { /* flush the buffer */
+ transform (hd, hd->buf);
+ _gcry_burn_stack (768);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return;
+ if (hd->count)
+ {
+ for (; inlen && hd->count < 128; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+ sha512_write (context, NULL, 0);
+ if (!inlen)
+ return;
+ }
+
+ while (inlen >= 128)
+ {
+ transform (hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 128;
+ inbuf += 128;
+ }
+ _gcry_burn_stack (768);
+ for (; inlen && hd->count < 128; inlen--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* The routine final terminates the computation and
+ * returns the digest.
+ * The handle is prepared for a new cycle, but adding bytes to the
+ * handle will the destroy the returned buffer.
+ * Returns: 64 bytes representing the digest. When used for sha384,
+ * we take the leftmost 48 of those bytes.
+ */
+
+static void
+sha512_final (void *context)
+{
+ SHA512_CONTEXT *hd = context;
+ u64 t, msb, lsb;
+ byte *p;
+
+ sha512_write (context, NULL, 0); /* flush */ ;
+
+ t = hd->nblocks;
+ /* multiply by 128 to make a byte count */
+ lsb = t << 7;
+ msb = t >> 57;
+ /* add the count */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 61;
+
+ if (hd->count < 112)
+ { /* enough room */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 112)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* need one extra block */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 128)
+ hd->buf[hd->count++] = 0;
+ sha512_write (context, NULL, 0); /* flush */ ;
+ memset (hd->buf, 0, 112); /* fill next block with zeroes */
+ }
+ /* append the 128 bit count */
+ hd->buf[112] = msb >> 56;
+ hd->buf[113] = msb >> 48;
+ hd->buf[114] = msb >> 40;
+ hd->buf[115] = msb >> 32;
+ hd->buf[116] = msb >> 24;
+ hd->buf[117] = msb >> 16;
+ hd->buf[118] = msb >> 8;
+ hd->buf[119] = msb;
+
+ hd->buf[120] = lsb >> 56;
+ hd->buf[121] = lsb >> 48;
+ hd->buf[122] = lsb >> 40;
+ hd->buf[123] = lsb >> 32;
+ hd->buf[124] = lsb >> 24;
+ hd->buf[125] = lsb >> 16;
+ hd->buf[126] = lsb >> 8;
+ hd->buf[127] = lsb;
+ transform (hd, hd->buf);
+ _gcry_burn_stack (768);
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \
+ *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \
+ *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0)
+#endif
+ X (0);
+ X (1);
+ X (2);
+ X (3);
+ X (4);
+ X (5);
+ /* Note that these last two chunks are included even for SHA384.
+ We just ignore them. */
+ X (6);
+ X (7);
+#undef X
+}
+
+static byte *
+sha512_read (void *context)
+{
+ SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
+ return hd->buf;
+}
+
+
+\f
+/*
+ Self-test section.
+ */
+
+
+static gpg_err_code_t
+selftests_sha384 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 0,
+ "abc", 3,
+ "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+ "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+ "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7", 48);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
+ "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
+ "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
+ 48);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA384, 1,
+ NULL, 0,
+ "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C"
+ "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B"
+ "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85",
+ 48);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA384, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+static gpg_err_code_t
+selftests_sha512 (int extended, selftest_report_func_t report)
+{
+ const char *what;
+ const char *errtxt;
+
+ what = "short string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 0,
+ "abc", 3,
+ "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
+ "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
+ "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
+ "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F", 64);
+ if (errtxt)
+ goto failed;
+
+ if (extended)
+ {
+ what = "long string";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 0,
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
+ "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
+ "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
+ "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09",
+ 64);
+ if (errtxt)
+ goto failed;
+
+ what = "one million \"a\"";
+ errtxt = _gcry_hash_selftest_check_one
+ (GCRY_MD_SHA512, 1,
+ NULL, 0,
+ "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63"
+ "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB"
+ "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B"
+ "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B",
+ 64);
+ if (errtxt)
+ goto failed;
+ }
+
+ return 0; /* Succeeded. */
+
+ failed:
+ if (report)
+ report ("digest", GCRY_MD_SHA512, what, errtxt);
+ return GPG_ERR_SELFTEST_FAILED;
+}
+
+
+/* Run a full self-test for ALGO and return 0 on success. */
+static gpg_err_code_t
+run_selftests (int algo, int extended, selftest_report_func_t report)
+{
+ gpg_err_code_t ec;
+
+ switch (algo)
+ {
+ case GCRY_MD_SHA384:
+ ec = selftests_sha384 (extended, report);
+ break;
+ case GCRY_MD_SHA512:
+ ec = selftests_sha512 (extended, report);
+ break;
+ default:
+ ec = GPG_ERR_DIGEST_ALGO;
+ break;
+
+ }
+ return ec;
+}
+
+
+
+\f
+static byte sha512_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.3 */
+ {
+ 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
+ 0x00, 0x04, 0x40
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha512[] =
+ {
+ { "2.16.840.1.101.3.4.2.3" },
+
+ /* PKCS#1 sha512WithRSAEncryption */
+ { "1.2.840.113549.1.1.13" },
+
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha512 =
+ {
+ "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
+ sha512_init, sha512_write, sha512_final, sha512_read,
+ sizeof (SHA512_CONTEXT),
+ };
+md_extra_spec_t _gcry_digest_extraspec_sha512 =
+ {
+ run_selftests
+ };
+
+static byte sha384_asn[] = /* Object ID is 2.16.840.1.101.3.4.2.2 */
+ {
+ 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
+ 0x00, 0x04, 0x30
+ };
+
+static gcry_md_oid_spec_t oid_spec_sha384[] =
+ {
+ { "2.16.840.1.101.3.4.2.2" },
+
+ /* PKCS#1 sha384WithRSAEncryption */
+ { "1.2.840.113549.1.1.12" },
+
+ { NULL },
+ };
+
+gcry_md_spec_t _gcry_digest_spec_sha384 =
+ {
+ "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
+ sha384_init, sha512_write, sha512_final, sha512_read,
+ sizeof (SHA512_CONTEXT),
+ };
+md_extra_spec_t _gcry_digest_extraspec_sha384 =
+ {
+ run_selftests
+ };
--- /dev/null
+/* tiger.c - The TIGER hash function
+ * Copyright (C) 1998, 2001, 2002, 2003, 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/* See http://www.cs.technion.ac.il/~biham/Reports/Tiger/ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+
+/* We really need a 64 bit type for this code. */
+#ifdef HAVE_U64_TYPEDEF
+
+typedef struct
+{
+ u64 a, b, c;
+ byte buf[64];
+ int count;
+ u32 nblocks;
+ int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */
+} TIGER_CONTEXT;
+
+
+/*********************************
+ * Okay, okay, this is not the fastest code - improvements are welcome.
+ *
+ */
+
+/* Some test vectors:
+ * "" 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
+ * "abc" F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
+ * "Tiger" 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ * 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789"
+ * 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham"
+ * 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge."
+ * EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
+ * "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proc"
+ * "eedings of Fast Software Encryption 3, Cambridge, 1996."
+ * 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
+ * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEF"
+ * "GHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"
+ * 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
+ */
+
+static u64 sbox1[256] = {
+ U64_C(0x02aab17cf7e90c5e) /* 0 */, U64_C(0xac424b03e243a8ec) /* 1 */,
+ U64_C(0x72cd5be30dd5fcd3) /* 2 */, U64_C(0x6d019b93f6f97f3a) /* 3 */,
+ U64_C(0xcd9978ffd21f9193) /* 4 */, U64_C(0x7573a1c9708029e2) /* 5 */,
+ U64_C(0xb164326b922a83c3) /* 6 */, U64_C(0x46883eee04915870) /* 7 */,
+ U64_C(0xeaace3057103ece6) /* 8 */, U64_C(0xc54169b808a3535c) /* 9 */,
+ U64_C(0x4ce754918ddec47c) /* 10 */, U64_C(0x0aa2f4dfdc0df40c) /* 11 */,
+ U64_C(0x10b76f18a74dbefa) /* 12 */, U64_C(0xc6ccb6235ad1ab6a) /* 13 */,
+ U64_C(0x13726121572fe2ff) /* 14 */, U64_C(0x1a488c6f199d921e) /* 15 */,
+ U64_C(0x4bc9f9f4da0007ca) /* 16 */, U64_C(0x26f5e6f6e85241c7) /* 17 */,
+ U64_C(0x859079dbea5947b6) /* 18 */, U64_C(0x4f1885c5c99e8c92) /* 19 */,
+ U64_C(0xd78e761ea96f864b) /* 20 */, U64_C(0x8e36428c52b5c17d) /* 21 */,
+ U64_C(0x69cf6827373063c1) /* 22 */, U64_C(0xb607c93d9bb4c56e) /* 23 */,
+ U64_C(0x7d820e760e76b5ea) /* 24 */, U64_C(0x645c9cc6f07fdc42) /* 25 */,
+ U64_C(0xbf38a078243342e0) /* 26 */, U64_C(0x5f6b343c9d2e7d04) /* 27 */,
+ U64_C(0xf2c28aeb600b0ec6) /* 28 */, U64_C(0x6c0ed85f7254bcac) /* 29 */,
+ U64_C(0x71592281a4db4fe5) /* 30 */, U64_C(0x1967fa69ce0fed9f) /* 31 */,
+ U64_C(0xfd5293f8b96545db) /* 32 */, U64_C(0xc879e9d7f2a7600b) /* 33 */,
+ U64_C(0x860248920193194e) /* 34 */, U64_C(0xa4f9533b2d9cc0b3) /* 35 */,
+ U64_C(0x9053836c15957613) /* 36 */, U64_C(0xdb6dcf8afc357bf1) /* 37 */,
+ U64_C(0x18beea7a7a370f57) /* 38 */, U64_C(0x037117ca50b99066) /* 39 */,
+ U64_C(0x6ab30a9774424a35) /* 40 */, U64_C(0xf4e92f02e325249b) /* 41 */,
+ U64_C(0x7739db07061ccae1) /* 42 */, U64_C(0xd8f3b49ceca42a05) /* 43 */,
+ U64_C(0xbd56be3f51382f73) /* 44 */, U64_C(0x45faed5843b0bb28) /* 45 */,
+ U64_C(0x1c813d5c11bf1f83) /* 46 */, U64_C(0x8af0e4b6d75fa169) /* 47 */,
+ U64_C(0x33ee18a487ad9999) /* 48 */, U64_C(0x3c26e8eab1c94410) /* 49 */,
+ U64_C(0xb510102bc0a822f9) /* 50 */, U64_C(0x141eef310ce6123b) /* 51 */,
+ U64_C(0xfc65b90059ddb154) /* 52 */, U64_C(0xe0158640c5e0e607) /* 53 */,
+ U64_C(0x884e079826c3a3cf) /* 54 */, U64_C(0x930d0d9523c535fd) /* 55 */,
+ U64_C(0x35638d754e9a2b00) /* 56 */, U64_C(0x4085fccf40469dd5) /* 57 */,
+ U64_C(0xc4b17ad28be23a4c) /* 58 */, U64_C(0xcab2f0fc6a3e6a2e) /* 59 */,
+ U64_C(0x2860971a6b943fcd) /* 60 */, U64_C(0x3dde6ee212e30446) /* 61 */,
+ U64_C(0x6222f32ae01765ae) /* 62 */, U64_C(0x5d550bb5478308fe) /* 63 */,
+ U64_C(0xa9efa98da0eda22a) /* 64 */, U64_C(0xc351a71686c40da7) /* 65 */,
+ U64_C(0x1105586d9c867c84) /* 66 */, U64_C(0xdcffee85fda22853) /* 67 */,
+ U64_C(0xccfbd0262c5eef76) /* 68 */, U64_C(0xbaf294cb8990d201) /* 69 */,
+ U64_C(0xe69464f52afad975) /* 70 */, U64_C(0x94b013afdf133e14) /* 71 */,
+ U64_C(0x06a7d1a32823c958) /* 72 */, U64_C(0x6f95fe5130f61119) /* 73 */,
+ U64_C(0xd92ab34e462c06c0) /* 74 */, U64_C(0xed7bde33887c71d2) /* 75 */,
+ U64_C(0x79746d6e6518393e) /* 76 */, U64_C(0x5ba419385d713329) /* 77 */,
+ U64_C(0x7c1ba6b948a97564) /* 78 */, U64_C(0x31987c197bfdac67) /* 79 */,
+ U64_C(0xde6c23c44b053d02) /* 80 */, U64_C(0x581c49fed002d64d) /* 81 */,
+ U64_C(0xdd474d6338261571) /* 82 */, U64_C(0xaa4546c3e473d062) /* 83 */,
+ U64_C(0x928fce349455f860) /* 84 */, U64_C(0x48161bbacaab94d9) /* 85 */,
+ U64_C(0x63912430770e6f68) /* 86 */, U64_C(0x6ec8a5e602c6641c) /* 87 */,
+ U64_C(0x87282515337ddd2b) /* 88 */, U64_C(0x2cda6b42034b701b) /* 89 */,
+ U64_C(0xb03d37c181cb096d) /* 90 */, U64_C(0xe108438266c71c6f) /* 91 */,
+ U64_C(0x2b3180c7eb51b255) /* 92 */, U64_C(0xdf92b82f96c08bbc) /* 93 */,
+ U64_C(0x5c68c8c0a632f3ba) /* 94 */, U64_C(0x5504cc861c3d0556) /* 95 */,
+ U64_C(0xabbfa4e55fb26b8f) /* 96 */, U64_C(0x41848b0ab3baceb4) /* 97 */,
+ U64_C(0xb334a273aa445d32) /* 98 */, U64_C(0xbca696f0a85ad881) /* 99 */,
+ U64_C(0x24f6ec65b528d56c) /* 100 */, U64_C(0x0ce1512e90f4524a) /* 101 */,
+ U64_C(0x4e9dd79d5506d35a) /* 102 */, U64_C(0x258905fac6ce9779) /* 103 */,
+ U64_C(0x2019295b3e109b33) /* 104 */, U64_C(0xf8a9478b73a054cc) /* 105 */,
+ U64_C(0x2924f2f934417eb0) /* 106 */, U64_C(0x3993357d536d1bc4) /* 107 */,
+ U64_C(0x38a81ac21db6ff8b) /* 108 */, U64_C(0x47c4fbf17d6016bf) /* 109 */,
+ U64_C(0x1e0faadd7667e3f5) /* 110 */, U64_C(0x7abcff62938beb96) /* 111 */,
+ U64_C(0xa78dad948fc179c9) /* 112 */, U64_C(0x8f1f98b72911e50d) /* 113 */,
+ U64_C(0x61e48eae27121a91) /* 114 */, U64_C(0x4d62f7ad31859808) /* 115 */,
+ U64_C(0xeceba345ef5ceaeb) /* 116 */, U64_C(0xf5ceb25ebc9684ce) /* 117 */,
+ U64_C(0xf633e20cb7f76221) /* 118 */, U64_C(0xa32cdf06ab8293e4) /* 119 */,
+ U64_C(0x985a202ca5ee2ca4) /* 120 */, U64_C(0xcf0b8447cc8a8fb1) /* 121 */,
+ U64_C(0x9f765244979859a3) /* 122 */, U64_C(0xa8d516b1a1240017) /* 123 */,
+ U64_C(0x0bd7ba3ebb5dc726) /* 124 */, U64_C(0xe54bca55b86adb39) /* 125 */,
+ U64_C(0x1d7a3afd6c478063) /* 126 */, U64_C(0x519ec608e7669edd) /* 127 */,
+ U64_C(0x0e5715a2d149aa23) /* 128 */, U64_C(0x177d4571848ff194) /* 129 */,
+ U64_C(0xeeb55f3241014c22) /* 130 */, U64_C(0x0f5e5ca13a6e2ec2) /* 131 */,
+ U64_C(0x8029927b75f5c361) /* 132 */, U64_C(0xad139fabc3d6e436) /* 133 */,
+ U64_C(0x0d5df1a94ccf402f) /* 134 */, U64_C(0x3e8bd948bea5dfc8) /* 135 */,
+ U64_C(0xa5a0d357bd3ff77e) /* 136 */, U64_C(0xa2d12e251f74f645) /* 137 */,
+ U64_C(0x66fd9e525e81a082) /* 138 */, U64_C(0x2e0c90ce7f687a49) /* 139 */,
+ U64_C(0xc2e8bcbeba973bc5) /* 140 */, U64_C(0x000001bce509745f) /* 141 */,
+ U64_C(0x423777bbe6dab3d6) /* 142 */, U64_C(0xd1661c7eaef06eb5) /* 143 */,
+ U64_C(0xa1781f354daacfd8) /* 144 */, U64_C(0x2d11284a2b16affc) /* 145 */,
+ U64_C(0xf1fc4f67fa891d1f) /* 146 */, U64_C(0x73ecc25dcb920ada) /* 147 */,
+ U64_C(0xae610c22c2a12651) /* 148 */, U64_C(0x96e0a810d356b78a) /* 149 */,
+ U64_C(0x5a9a381f2fe7870f) /* 150 */, U64_C(0xd5ad62ede94e5530) /* 151 */,
+ U64_C(0xd225e5e8368d1427) /* 152 */, U64_C(0x65977b70c7af4631) /* 153 */,
+ U64_C(0x99f889b2de39d74f) /* 154 */, U64_C(0x233f30bf54e1d143) /* 155 */,
+ U64_C(0x9a9675d3d9a63c97) /* 156 */, U64_C(0x5470554ff334f9a8) /* 157 */,
+ U64_C(0x166acb744a4f5688) /* 158 */, U64_C(0x70c74caab2e4aead) /* 159 */,
+ U64_C(0xf0d091646f294d12) /* 160 */, U64_C(0x57b82a89684031d1) /* 161 */,
+ U64_C(0xefd95a5a61be0b6b) /* 162 */, U64_C(0x2fbd12e969f2f29a) /* 163 */,
+ U64_C(0x9bd37013feff9fe8) /* 164 */, U64_C(0x3f9b0404d6085a06) /* 165 */,
+ U64_C(0x4940c1f3166cfe15) /* 166 */, U64_C(0x09542c4dcdf3defb) /* 167 */,
+ U64_C(0xb4c5218385cd5ce3) /* 168 */, U64_C(0xc935b7dc4462a641) /* 169 */,
+ U64_C(0x3417f8a68ed3b63f) /* 170 */, U64_C(0xb80959295b215b40) /* 171 */,
+ U64_C(0xf99cdaef3b8c8572) /* 172 */, U64_C(0x018c0614f8fcb95d) /* 173 */,
+ U64_C(0x1b14accd1a3acdf3) /* 174 */, U64_C(0x84d471f200bb732d) /* 175 */,
+ U64_C(0xc1a3110e95e8da16) /* 176 */, U64_C(0x430a7220bf1a82b8) /* 177 */,
+ U64_C(0xb77e090d39df210e) /* 178 */, U64_C(0x5ef4bd9f3cd05e9d) /* 179 */,
+ U64_C(0x9d4ff6da7e57a444) /* 180 */, U64_C(0xda1d60e183d4a5f8) /* 181 */,
+ U64_C(0xb287c38417998e47) /* 182 */, U64_C(0xfe3edc121bb31886) /* 183 */,
+ U64_C(0xc7fe3ccc980ccbef) /* 184 */, U64_C(0xe46fb590189bfd03) /* 185 */,
+ U64_C(0x3732fd469a4c57dc) /* 186 */, U64_C(0x7ef700a07cf1ad65) /* 187 */,
+ U64_C(0x59c64468a31d8859) /* 188 */, U64_C(0x762fb0b4d45b61f6) /* 189 */,
+ U64_C(0x155baed099047718) /* 190 */, U64_C(0x68755e4c3d50baa6) /* 191 */,
+ U64_C(0xe9214e7f22d8b4df) /* 192 */, U64_C(0x2addbf532eac95f4) /* 193 */,
+ U64_C(0x32ae3909b4bd0109) /* 194 */, U64_C(0x834df537b08e3450) /* 195 */,
+ U64_C(0xfa209da84220728d) /* 196 */, U64_C(0x9e691d9b9efe23f7) /* 197 */,
+ U64_C(0x0446d288c4ae8d7f) /* 198 */, U64_C(0x7b4cc524e169785b) /* 199 */,
+ U64_C(0x21d87f0135ca1385) /* 200 */, U64_C(0xcebb400f137b8aa5) /* 201 */,
+ U64_C(0x272e2b66580796be) /* 202 */, U64_C(0x3612264125c2b0de) /* 203 */,
+ U64_C(0x057702bdad1efbb2) /* 204 */, U64_C(0xd4babb8eacf84be9) /* 205 */,
+ U64_C(0x91583139641bc67b) /* 206 */, U64_C(0x8bdc2de08036e024) /* 207 */,
+ U64_C(0x603c8156f49f68ed) /* 208 */, U64_C(0xf7d236f7dbef5111) /* 209 */,
+ U64_C(0x9727c4598ad21e80) /* 210 */, U64_C(0xa08a0896670a5fd7) /* 211 */,
+ U64_C(0xcb4a8f4309eba9cb) /* 212 */, U64_C(0x81af564b0f7036a1) /* 213 */,
+ U64_C(0xc0b99aa778199abd) /* 214 */, U64_C(0x959f1ec83fc8e952) /* 215 */,
+ U64_C(0x8c505077794a81b9) /* 216 */, U64_C(0x3acaaf8f056338f0) /* 217 */,
+ U64_C(0x07b43f50627a6778) /* 218 */, U64_C(0x4a44ab49f5eccc77) /* 219 */,
+ U64_C(0x3bc3d6e4b679ee98) /* 220 */, U64_C(0x9cc0d4d1cf14108c) /* 221 */,
+ U64_C(0x4406c00b206bc8a0) /* 222 */, U64_C(0x82a18854c8d72d89) /* 223 */,
+ U64_C(0x67e366b35c3c432c) /* 224 */, U64_C(0xb923dd61102b37f2) /* 225 */,
+ U64_C(0x56ab2779d884271d) /* 226 */, U64_C(0xbe83e1b0ff1525af) /* 227 */,
+ U64_C(0xfb7c65d4217e49a9) /* 228 */, U64_C(0x6bdbe0e76d48e7d4) /* 229 */,
+ U64_C(0x08df828745d9179e) /* 230 */, U64_C(0x22ea6a9add53bd34) /* 231 */,
+ U64_C(0xe36e141c5622200a) /* 232 */, U64_C(0x7f805d1b8cb750ee) /* 233 */,
+ U64_C(0xafe5c7a59f58e837) /* 234 */, U64_C(0xe27f996a4fb1c23c) /* 235 */,
+ U64_C(0xd3867dfb0775f0d0) /* 236 */, U64_C(0xd0e673de6e88891a) /* 237 */,
+ U64_C(0x123aeb9eafb86c25) /* 238 */, U64_C(0x30f1d5d5c145b895) /* 239 */,
+ U64_C(0xbb434a2dee7269e7) /* 240 */, U64_C(0x78cb67ecf931fa38) /* 241 */,
+ U64_C(0xf33b0372323bbf9c) /* 242 */, U64_C(0x52d66336fb279c74) /* 243 */,
+ U64_C(0x505f33ac0afb4eaa) /* 244 */, U64_C(0xe8a5cd99a2cce187) /* 245 */,
+ U64_C(0x534974801e2d30bb) /* 246 */, U64_C(0x8d2d5711d5876d90) /* 247 */,
+ U64_C(0x1f1a412891bc038e) /* 248 */, U64_C(0xd6e2e71d82e56648) /* 249 */,
+ U64_C(0x74036c3a497732b7) /* 250 */, U64_C(0x89b67ed96361f5ab) /* 251 */,
+ U64_C(0xffed95d8f1ea02a2) /* 252 */, U64_C(0xe72b3bd61464d43d) /* 253 */,
+ U64_C(0xa6300f170bdc4820) /* 254 */, U64_C(0xebc18760ed78a77a) /* 255 */
+};
+static u64 sbox2[256] = {
+ U64_C(0xe6a6be5a05a12138) /* 256 */, U64_C(0xb5a122a5b4f87c98) /* 257 */,
+ U64_C(0x563c6089140b6990) /* 258 */, U64_C(0x4c46cb2e391f5dd5) /* 259 */,
+ U64_C(0xd932addbc9b79434) /* 260 */, U64_C(0x08ea70e42015aff5) /* 261 */,
+ U64_C(0xd765a6673e478cf1) /* 262 */, U64_C(0xc4fb757eab278d99) /* 263 */,
+ U64_C(0xdf11c6862d6e0692) /* 264 */, U64_C(0xddeb84f10d7f3b16) /* 265 */,
+ U64_C(0x6f2ef604a665ea04) /* 266 */, U64_C(0x4a8e0f0ff0e0dfb3) /* 267 */,
+ U64_C(0xa5edeef83dbcba51) /* 268 */, U64_C(0xfc4f0a2a0ea4371e) /* 269 */,
+ U64_C(0xe83e1da85cb38429) /* 270 */, U64_C(0xdc8ff882ba1b1ce2) /* 271 */,
+ U64_C(0xcd45505e8353e80d) /* 272 */, U64_C(0x18d19a00d4db0717) /* 273 */,
+ U64_C(0x34a0cfeda5f38101) /* 274 */, U64_C(0x0be77e518887caf2) /* 275 */,
+ U64_C(0x1e341438b3c45136) /* 276 */, U64_C(0xe05797f49089ccf9) /* 277 */,
+ U64_C(0xffd23f9df2591d14) /* 278 */, U64_C(0x543dda228595c5cd) /* 279 */,
+ U64_C(0x661f81fd99052a33) /* 280 */, U64_C(0x8736e641db0f7b76) /* 281 */,
+ U64_C(0x15227725418e5307) /* 282 */, U64_C(0xe25f7f46162eb2fa) /* 283 */,
+ U64_C(0x48a8b2126c13d9fe) /* 284 */, U64_C(0xafdc541792e76eea) /* 285 */,
+ U64_C(0x03d912bfc6d1898f) /* 286 */, U64_C(0x31b1aafa1b83f51b) /* 287 */,
+ U64_C(0xf1ac2796e42ab7d9) /* 288 */, U64_C(0x40a3a7d7fcd2ebac) /* 289 */,
+ U64_C(0x1056136d0afbbcc5) /* 290 */, U64_C(0x7889e1dd9a6d0c85) /* 291 */,
+ U64_C(0xd33525782a7974aa) /* 292 */, U64_C(0xa7e25d09078ac09b) /* 293 */,
+ U64_C(0xbd4138b3eac6edd0) /* 294 */, U64_C(0x920abfbe71eb9e70) /* 295 */,
+ U64_C(0xa2a5d0f54fc2625c) /* 296 */, U64_C(0xc054e36b0b1290a3) /* 297 */,
+ U64_C(0xf6dd59ff62fe932b) /* 298 */, U64_C(0x3537354511a8ac7d) /* 299 */,
+ U64_C(0xca845e9172fadcd4) /* 300 */, U64_C(0x84f82b60329d20dc) /* 301 */,
+ U64_C(0x79c62ce1cd672f18) /* 302 */, U64_C(0x8b09a2add124642c) /* 303 */,
+ U64_C(0xd0c1e96a19d9e726) /* 304 */, U64_C(0x5a786a9b4ba9500c) /* 305 */,
+ U64_C(0x0e020336634c43f3) /* 306 */, U64_C(0xc17b474aeb66d822) /* 307 */,
+ U64_C(0x6a731ae3ec9baac2) /* 308 */, U64_C(0x8226667ae0840258) /* 309 */,
+ U64_C(0x67d4567691caeca5) /* 310 */, U64_C(0x1d94155c4875adb5) /* 311 */,
+ U64_C(0x6d00fd985b813fdf) /* 312 */, U64_C(0x51286efcb774cd06) /* 313 */,
+ U64_C(0x5e8834471fa744af) /* 314 */, U64_C(0xf72ca0aee761ae2e) /* 315 */,
+ U64_C(0xbe40e4cdaee8e09a) /* 316 */, U64_C(0xe9970bbb5118f665) /* 317 */,
+ U64_C(0x726e4beb33df1964) /* 318 */, U64_C(0x703b000729199762) /* 319 */,
+ U64_C(0x4631d816f5ef30a7) /* 320 */, U64_C(0xb880b5b51504a6be) /* 321 */,
+ U64_C(0x641793c37ed84b6c) /* 322 */, U64_C(0x7b21ed77f6e97d96) /* 323 */,
+ U64_C(0x776306312ef96b73) /* 324 */, U64_C(0xae528948e86ff3f4) /* 325 */,
+ U64_C(0x53dbd7f286a3f8f8) /* 326 */, U64_C(0x16cadce74cfc1063) /* 327 */,
+ U64_C(0x005c19bdfa52c6dd) /* 328 */, U64_C(0x68868f5d64d46ad3) /* 329 */,
+ U64_C(0x3a9d512ccf1e186a) /* 330 */, U64_C(0x367e62c2385660ae) /* 331 */,
+ U64_C(0xe359e7ea77dcb1d7) /* 332 */, U64_C(0x526c0773749abe6e) /* 333 */,
+ U64_C(0x735ae5f9d09f734b) /* 334 */, U64_C(0x493fc7cc8a558ba8) /* 335 */,
+ U64_C(0xb0b9c1533041ab45) /* 336 */, U64_C(0x321958ba470a59bd) /* 337 */,
+ U64_C(0x852db00b5f46c393) /* 338 */, U64_C(0x91209b2bd336b0e5) /* 339 */,
+ U64_C(0x6e604f7d659ef19f) /* 340 */, U64_C(0xb99a8ae2782ccb24) /* 341 */,
+ U64_C(0xccf52ab6c814c4c7) /* 342 */, U64_C(0x4727d9afbe11727b) /* 343 */,
+ U64_C(0x7e950d0c0121b34d) /* 344 */, U64_C(0x756f435670ad471f) /* 345 */,
+ U64_C(0xf5add442615a6849) /* 346 */, U64_C(0x4e87e09980b9957a) /* 347 */,
+ U64_C(0x2acfa1df50aee355) /* 348 */, U64_C(0xd898263afd2fd556) /* 349 */,
+ U64_C(0xc8f4924dd80c8fd6) /* 350 */, U64_C(0xcf99ca3d754a173a) /* 351 */,
+ U64_C(0xfe477bacaf91bf3c) /* 352 */, U64_C(0xed5371f6d690c12d) /* 353 */,
+ U64_C(0x831a5c285e687094) /* 354 */, U64_C(0xc5d3c90a3708a0a4) /* 355 */,
+ U64_C(0x0f7f903717d06580) /* 356 */, U64_C(0x19f9bb13b8fdf27f) /* 357 */,
+ U64_C(0xb1bd6f1b4d502843) /* 358 */, U64_C(0x1c761ba38fff4012) /* 359 */,
+ U64_C(0x0d1530c4e2e21f3b) /* 360 */, U64_C(0x8943ce69a7372c8a) /* 361 */,
+ U64_C(0xe5184e11feb5ce66) /* 362 */, U64_C(0x618bdb80bd736621) /* 363 */,
+ U64_C(0x7d29bad68b574d0b) /* 364 */, U64_C(0x81bb613e25e6fe5b) /* 365 */,
+ U64_C(0x071c9c10bc07913f) /* 366 */, U64_C(0xc7beeb7909ac2d97) /* 367 */,
+ U64_C(0xc3e58d353bc5d757) /* 368 */, U64_C(0xeb017892f38f61e8) /* 369 */,
+ U64_C(0xd4effb9c9b1cc21a) /* 370 */, U64_C(0x99727d26f494f7ab) /* 371 */,
+ U64_C(0xa3e063a2956b3e03) /* 372 */, U64_C(0x9d4a8b9a4aa09c30) /* 373 */,
+ U64_C(0x3f6ab7d500090fb4) /* 374 */, U64_C(0x9cc0f2a057268ac0) /* 375 */,
+ U64_C(0x3dee9d2dedbf42d1) /* 376 */, U64_C(0x330f49c87960a972) /* 377 */,
+ U64_C(0xc6b2720287421b41) /* 378 */, U64_C(0x0ac59ec07c00369c) /* 379 */,
+ U64_C(0xef4eac49cb353425) /* 380 */, U64_C(0xf450244eef0129d8) /* 381 */,
+ U64_C(0x8acc46e5caf4deb6) /* 382 */, U64_C(0x2ffeab63989263f7) /* 383 */,
+ U64_C(0x8f7cb9fe5d7a4578) /* 384 */, U64_C(0x5bd8f7644e634635) /* 385 */,
+ U64_C(0x427a7315bf2dc900) /* 386 */, U64_C(0x17d0c4aa2125261c) /* 387 */,
+ U64_C(0x3992486c93518e50) /* 388 */, U64_C(0xb4cbfee0a2d7d4c3) /* 389 */,
+ U64_C(0x7c75d6202c5ddd8d) /* 390 */, U64_C(0xdbc295d8e35b6c61) /* 391 */,
+ U64_C(0x60b369d302032b19) /* 392 */, U64_C(0xce42685fdce44132) /* 393 */,
+ U64_C(0x06f3ddb9ddf65610) /* 394 */, U64_C(0x8ea4d21db5e148f0) /* 395 */,
+ U64_C(0x20b0fce62fcd496f) /* 396 */, U64_C(0x2c1b912358b0ee31) /* 397 */,
+ U64_C(0xb28317b818f5a308) /* 398 */, U64_C(0xa89c1e189ca6d2cf) /* 399 */,
+ U64_C(0x0c6b18576aaadbc8) /* 400 */, U64_C(0xb65deaa91299fae3) /* 401 */,
+ U64_C(0xfb2b794b7f1027e7) /* 402 */, U64_C(0x04e4317f443b5beb) /* 403 */,
+ U64_C(0x4b852d325939d0a6) /* 404 */, U64_C(0xd5ae6beefb207ffc) /* 405 */,
+ U64_C(0x309682b281c7d374) /* 406 */, U64_C(0xbae309a194c3b475) /* 407 */,
+ U64_C(0x8cc3f97b13b49f05) /* 408 */, U64_C(0x98a9422ff8293967) /* 409 */,
+ U64_C(0x244b16b01076ff7c) /* 410 */, U64_C(0xf8bf571c663d67ee) /* 411 */,
+ U64_C(0x1f0d6758eee30da1) /* 412 */, U64_C(0xc9b611d97adeb9b7) /* 413 */,
+ U64_C(0xb7afd5887b6c57a2) /* 414 */, U64_C(0x6290ae846b984fe1) /* 415 */,
+ U64_C(0x94df4cdeacc1a5fd) /* 416 */, U64_C(0x058a5bd1c5483aff) /* 417 */,
+ U64_C(0x63166cc142ba3c37) /* 418 */, U64_C(0x8db8526eb2f76f40) /* 419 */,
+ U64_C(0xe10880036f0d6d4e) /* 420 */, U64_C(0x9e0523c9971d311d) /* 421 */,
+ U64_C(0x45ec2824cc7cd691) /* 422 */, U64_C(0x575b8359e62382c9) /* 423 */,
+ U64_C(0xfa9e400dc4889995) /* 424 */, U64_C(0xd1823ecb45721568) /* 425 */,
+ U64_C(0xdafd983b8206082f) /* 426 */, U64_C(0xaa7d29082386a8cb) /* 427 */,
+ U64_C(0x269fcd4403b87588) /* 428 */, U64_C(0x1b91f5f728bdd1e0) /* 429 */,
+ U64_C(0xe4669f39040201f6) /* 430 */, U64_C(0x7a1d7c218cf04ade) /* 431 */,
+ U64_C(0x65623c29d79ce5ce) /* 432 */, U64_C(0x2368449096c00bb1) /* 433 */,
+ U64_C(0xab9bf1879da503ba) /* 434 */, U64_C(0xbc23ecb1a458058e) /* 435 */,
+ U64_C(0x9a58df01bb401ecc) /* 436 */, U64_C(0xa070e868a85f143d) /* 437 */,
+ U64_C(0x4ff188307df2239e) /* 438 */, U64_C(0x14d565b41a641183) /* 439 */,
+ U64_C(0xee13337452701602) /* 440 */, U64_C(0x950e3dcf3f285e09) /* 441 */,
+ U64_C(0x59930254b9c80953) /* 442 */, U64_C(0x3bf299408930da6d) /* 443 */,
+ U64_C(0xa955943f53691387) /* 444 */, U64_C(0xa15edecaa9cb8784) /* 445 */,
+ U64_C(0x29142127352be9a0) /* 446 */, U64_C(0x76f0371fff4e7afb) /* 447 */,
+ U64_C(0x0239f450274f2228) /* 448 */, U64_C(0xbb073af01d5e868b) /* 449 */,
+ U64_C(0xbfc80571c10e96c1) /* 450 */, U64_C(0xd267088568222e23) /* 451 */,
+ U64_C(0x9671a3d48e80b5b0) /* 452 */, U64_C(0x55b5d38ae193bb81) /* 453 */,
+ U64_C(0x693ae2d0a18b04b8) /* 454 */, U64_C(0x5c48b4ecadd5335f) /* 455 */,
+ U64_C(0xfd743b194916a1ca) /* 456 */, U64_C(0x2577018134be98c4) /* 457 */,
+ U64_C(0xe77987e83c54a4ad) /* 458 */, U64_C(0x28e11014da33e1b9) /* 459 */,
+ U64_C(0x270cc59e226aa213) /* 460 */, U64_C(0x71495f756d1a5f60) /* 461 */,
+ U64_C(0x9be853fb60afef77) /* 462 */, U64_C(0xadc786a7f7443dbf) /* 463 */,
+ U64_C(0x0904456173b29a82) /* 464 */, U64_C(0x58bc7a66c232bd5e) /* 465 */,
+ U64_C(0xf306558c673ac8b2) /* 466 */, U64_C(0x41f639c6b6c9772a) /* 467 */,
+ U64_C(0x216defe99fda35da) /* 468 */, U64_C(0x11640cc71c7be615) /* 469 */,
+ U64_C(0x93c43694565c5527) /* 470 */, U64_C(0xea038e6246777839) /* 471 */,
+ U64_C(0xf9abf3ce5a3e2469) /* 472 */, U64_C(0x741e768d0fd312d2) /* 473 */,
+ U64_C(0x0144b883ced652c6) /* 474 */, U64_C(0xc20b5a5ba33f8552) /* 475 */,
+ U64_C(0x1ae69633c3435a9d) /* 476 */, U64_C(0x97a28ca4088cfdec) /* 477 */,
+ U64_C(0x8824a43c1e96f420) /* 478 */, U64_C(0x37612fa66eeea746) /* 479 */,
+ U64_C(0x6b4cb165f9cf0e5a) /* 480 */, U64_C(0x43aa1c06a0abfb4a) /* 481 */,
+ U64_C(0x7f4dc26ff162796b) /* 482 */, U64_C(0x6cbacc8e54ed9b0f) /* 483 */,
+ U64_C(0xa6b7ffefd2bb253e) /* 484 */, U64_C(0x2e25bc95b0a29d4f) /* 485 */,
+ U64_C(0x86d6a58bdef1388c) /* 486 */, U64_C(0xded74ac576b6f054) /* 487 */,
+ U64_C(0x8030bdbc2b45805d) /* 488 */, U64_C(0x3c81af70e94d9289) /* 489 */,
+ U64_C(0x3eff6dda9e3100db) /* 490 */, U64_C(0xb38dc39fdfcc8847) /* 491 */,
+ U64_C(0x123885528d17b87e) /* 492 */, U64_C(0xf2da0ed240b1b642) /* 493 */,
+ U64_C(0x44cefadcd54bf9a9) /* 494 */, U64_C(0x1312200e433c7ee6) /* 495 */,
+ U64_C(0x9ffcc84f3a78c748) /* 496 */, U64_C(0xf0cd1f72248576bb) /* 497 */,
+ U64_C(0xec6974053638cfe4) /* 498 */, U64_C(0x2ba7b67c0cec4e4c) /* 499 */,
+ U64_C(0xac2f4df3e5ce32ed) /* 500 */, U64_C(0xcb33d14326ea4c11) /* 501 */,
+ U64_C(0xa4e9044cc77e58bc) /* 502 */, U64_C(0x5f513293d934fcef) /* 503 */,
+ U64_C(0x5dc9645506e55444) /* 504 */, U64_C(0x50de418f317de40a) /* 505 */,
+ U64_C(0x388cb31a69dde259) /* 506 */, U64_C(0x2db4a83455820a86) /* 507 */,
+ U64_C(0x9010a91e84711ae9) /* 508 */, U64_C(0x4df7f0b7b1498371) /* 509 */,
+ U64_C(0xd62a2eabc0977179) /* 510 */, U64_C(0x22fac097aa8d5c0e) /* 511 */
+};
+static u64 sbox3[256] = {
+ U64_C(0xf49fcc2ff1daf39b) /* 512 */, U64_C(0x487fd5c66ff29281) /* 513 */,
+ U64_C(0xe8a30667fcdca83f) /* 514 */, U64_C(0x2c9b4be3d2fcce63) /* 515 */,
+ U64_C(0xda3ff74b93fbbbc2) /* 516 */, U64_C(0x2fa165d2fe70ba66) /* 517 */,
+ U64_C(0xa103e279970e93d4) /* 518 */, U64_C(0xbecdec77b0e45e71) /* 519 */,
+ U64_C(0xcfb41e723985e497) /* 520 */, U64_C(0xb70aaa025ef75017) /* 521 */,
+ U64_C(0xd42309f03840b8e0) /* 522 */, U64_C(0x8efc1ad035898579) /* 523 */,
+ U64_C(0x96c6920be2b2abc5) /* 524 */, U64_C(0x66af4163375a9172) /* 525 */,
+ U64_C(0x2174abdcca7127fb) /* 526 */, U64_C(0xb33ccea64a72ff41) /* 527 */,
+ U64_C(0xf04a4933083066a5) /* 528 */, U64_C(0x8d970acdd7289af5) /* 529 */,
+ U64_C(0x8f96e8e031c8c25e) /* 530 */, U64_C(0xf3fec02276875d47) /* 531 */,
+ U64_C(0xec7bf310056190dd) /* 532 */, U64_C(0xf5adb0aebb0f1491) /* 533 */,
+ U64_C(0x9b50f8850fd58892) /* 534 */, U64_C(0x4975488358b74de8) /* 535 */,
+ U64_C(0xa3354ff691531c61) /* 536 */, U64_C(0x0702bbe481d2c6ee) /* 537 */,
+ U64_C(0x89fb24057deded98) /* 538 */, U64_C(0xac3075138596e902) /* 539 */,
+ U64_C(0x1d2d3580172772ed) /* 540 */, U64_C(0xeb738fc28e6bc30d) /* 541 */,
+ U64_C(0x5854ef8f63044326) /* 542 */, U64_C(0x9e5c52325add3bbe) /* 543 */,
+ U64_C(0x90aa53cf325c4623) /* 544 */, U64_C(0xc1d24d51349dd067) /* 545 */,
+ U64_C(0x2051cfeea69ea624) /* 546 */, U64_C(0x13220f0a862e7e4f) /* 547 */,
+ U64_C(0xce39399404e04864) /* 548 */, U64_C(0xd9c42ca47086fcb7) /* 549 */,
+ U64_C(0x685ad2238a03e7cc) /* 550 */, U64_C(0x066484b2ab2ff1db) /* 551 */,
+ U64_C(0xfe9d5d70efbf79ec) /* 552 */, U64_C(0x5b13b9dd9c481854) /* 553 */,
+ U64_C(0x15f0d475ed1509ad) /* 554 */, U64_C(0x0bebcd060ec79851) /* 555 */,
+ U64_C(0xd58c6791183ab7f8) /* 556 */, U64_C(0xd1187c5052f3eee4) /* 557 */,
+ U64_C(0xc95d1192e54e82ff) /* 558 */, U64_C(0x86eea14cb9ac6ca2) /* 559 */,
+ U64_C(0x3485beb153677d5d) /* 560 */, U64_C(0xdd191d781f8c492a) /* 561 */,
+ U64_C(0xf60866baa784ebf9) /* 562 */, U64_C(0x518f643ba2d08c74) /* 563 */,
+ U64_C(0x8852e956e1087c22) /* 564 */, U64_C(0xa768cb8dc410ae8d) /* 565 */,
+ U64_C(0x38047726bfec8e1a) /* 566 */, U64_C(0xa67738b4cd3b45aa) /* 567 */,
+ U64_C(0xad16691cec0dde19) /* 568 */, U64_C(0xc6d4319380462e07) /* 569 */,
+ U64_C(0xc5a5876d0ba61938) /* 570 */, U64_C(0x16b9fa1fa58fd840) /* 571 */,
+ U64_C(0x188ab1173ca74f18) /* 572 */, U64_C(0xabda2f98c99c021f) /* 573 */,
+ U64_C(0x3e0580ab134ae816) /* 574 */, U64_C(0x5f3b05b773645abb) /* 575 */,
+ U64_C(0x2501a2be5575f2f6) /* 576 */, U64_C(0x1b2f74004e7e8ba9) /* 577 */,
+ U64_C(0x1cd7580371e8d953) /* 578 */, U64_C(0x7f6ed89562764e30) /* 579 */,
+ U64_C(0xb15926ff596f003d) /* 580 */, U64_C(0x9f65293da8c5d6b9) /* 581 */,
+ U64_C(0x6ecef04dd690f84c) /* 582 */, U64_C(0x4782275fff33af88) /* 583 */,
+ U64_C(0xe41433083f820801) /* 584 */, U64_C(0xfd0dfe409a1af9b5) /* 585 */,
+ U64_C(0x4325a3342cdb396b) /* 586 */, U64_C(0x8ae77e62b301b252) /* 587 */,
+ U64_C(0xc36f9e9f6655615a) /* 588 */, U64_C(0x85455a2d92d32c09) /* 589 */,
+ U64_C(0xf2c7dea949477485) /* 590 */, U64_C(0x63cfb4c133a39eba) /* 591 */,
+ U64_C(0x83b040cc6ebc5462) /* 592 */, U64_C(0x3b9454c8fdb326b0) /* 593 */,
+ U64_C(0x56f56a9e87ffd78c) /* 594 */, U64_C(0x2dc2940d99f42bc6) /* 595 */,
+ U64_C(0x98f7df096b096e2d) /* 596 */, U64_C(0x19a6e01e3ad852bf) /* 597 */,
+ U64_C(0x42a99ccbdbd4b40b) /* 598 */, U64_C(0xa59998af45e9c559) /* 599 */,
+ U64_C(0x366295e807d93186) /* 600 */, U64_C(0x6b48181bfaa1f773) /* 601 */,
+ U64_C(0x1fec57e2157a0a1d) /* 602 */, U64_C(0x4667446af6201ad5) /* 603 */,
+ U64_C(0xe615ebcacfb0f075) /* 604 */, U64_C(0xb8f31f4f68290778) /* 605 */,
+ U64_C(0x22713ed6ce22d11e) /* 606 */, U64_C(0x3057c1a72ec3c93b) /* 607 */,
+ U64_C(0xcb46acc37c3f1f2f) /* 608 */, U64_C(0xdbb893fd02aaf50e) /* 609 */,
+ U64_C(0x331fd92e600b9fcf) /* 610 */, U64_C(0xa498f96148ea3ad6) /* 611 */,
+ U64_C(0xa8d8426e8b6a83ea) /* 612 */, U64_C(0xa089b274b7735cdc) /* 613 */,
+ U64_C(0x87f6b3731e524a11) /* 614 */, U64_C(0x118808e5cbc96749) /* 615 */,
+ U64_C(0x9906e4c7b19bd394) /* 616 */, U64_C(0xafed7f7e9b24a20c) /* 617 */,
+ U64_C(0x6509eadeeb3644a7) /* 618 */, U64_C(0x6c1ef1d3e8ef0ede) /* 619 */,
+ U64_C(0xb9c97d43e9798fb4) /* 620 */, U64_C(0xa2f2d784740c28a3) /* 621 */,
+ U64_C(0x7b8496476197566f) /* 622 */, U64_C(0x7a5be3e6b65f069d) /* 623 */,
+ U64_C(0xf96330ed78be6f10) /* 624 */, U64_C(0xeee60de77a076a15) /* 625 */,
+ U64_C(0x2b4bee4aa08b9bd0) /* 626 */, U64_C(0x6a56a63ec7b8894e) /* 627 */,
+ U64_C(0x02121359ba34fef4) /* 628 */, U64_C(0x4cbf99f8283703fc) /* 629 */,
+ U64_C(0x398071350caf30c8) /* 630 */, U64_C(0xd0a77a89f017687a) /* 631 */,
+ U64_C(0xf1c1a9eb9e423569) /* 632 */, U64_C(0x8c7976282dee8199) /* 633 */,
+ U64_C(0x5d1737a5dd1f7abd) /* 634 */, U64_C(0x4f53433c09a9fa80) /* 635 */,
+ U64_C(0xfa8b0c53df7ca1d9) /* 636 */, U64_C(0x3fd9dcbc886ccb77) /* 637 */,
+ U64_C(0xc040917ca91b4720) /* 638 */, U64_C(0x7dd00142f9d1dcdf) /* 639 */,
+ U64_C(0x8476fc1d4f387b58) /* 640 */, U64_C(0x23f8e7c5f3316503) /* 641 */,
+ U64_C(0x032a2244e7e37339) /* 642 */, U64_C(0x5c87a5d750f5a74b) /* 643 */,
+ U64_C(0x082b4cc43698992e) /* 644 */, U64_C(0xdf917becb858f63c) /* 645 */,
+ U64_C(0x3270b8fc5bf86dda) /* 646 */, U64_C(0x10ae72bb29b5dd76) /* 647 */,
+ U64_C(0x576ac94e7700362b) /* 648 */, U64_C(0x1ad112dac61efb8f) /* 649 */,
+ U64_C(0x691bc30ec5faa427) /* 650 */, U64_C(0xff246311cc327143) /* 651 */,
+ U64_C(0x3142368e30e53206) /* 652 */, U64_C(0x71380e31e02ca396) /* 653 */,
+ U64_C(0x958d5c960aad76f1) /* 654 */, U64_C(0xf8d6f430c16da536) /* 655 */,
+ U64_C(0xc8ffd13f1be7e1d2) /* 656 */, U64_C(0x7578ae66004ddbe1) /* 657 */,
+ U64_C(0x05833f01067be646) /* 658 */, U64_C(0xbb34b5ad3bfe586d) /* 659 */,
+ U64_C(0x095f34c9a12b97f0) /* 660 */, U64_C(0x247ab64525d60ca8) /* 661 */,
+ U64_C(0xdcdbc6f3017477d1) /* 662 */, U64_C(0x4a2e14d4decad24d) /* 663 */,
+ U64_C(0xbdb5e6d9be0a1eeb) /* 664 */, U64_C(0x2a7e70f7794301ab) /* 665 */,
+ U64_C(0xdef42d8a270540fd) /* 666 */, U64_C(0x01078ec0a34c22c1) /* 667 */,
+ U64_C(0xe5de511af4c16387) /* 668 */, U64_C(0x7ebb3a52bd9a330a) /* 669 */,
+ U64_C(0x77697857aa7d6435) /* 670 */, U64_C(0x004e831603ae4c32) /* 671 */,
+ U64_C(0xe7a21020ad78e312) /* 672 */, U64_C(0x9d41a70c6ab420f2) /* 673 */,
+ U64_C(0x28e06c18ea1141e6) /* 674 */, U64_C(0xd2b28cbd984f6b28) /* 675 */,
+ U64_C(0x26b75f6c446e9d83) /* 676 */, U64_C(0xba47568c4d418d7f) /* 677 */,
+ U64_C(0xd80badbfe6183d8e) /* 678 */, U64_C(0x0e206d7f5f166044) /* 679 */,
+ U64_C(0xe258a43911cbca3e) /* 680 */, U64_C(0x723a1746b21dc0bc) /* 681 */,
+ U64_C(0xc7caa854f5d7cdd3) /* 682 */, U64_C(0x7cac32883d261d9c) /* 683 */,
+ U64_C(0x7690c26423ba942c) /* 684 */, U64_C(0x17e55524478042b8) /* 685 */,
+ U64_C(0xe0be477656a2389f) /* 686 */, U64_C(0x4d289b5e67ab2da0) /* 687 */,
+ U64_C(0x44862b9c8fbbfd31) /* 688 */, U64_C(0xb47cc8049d141365) /* 689 */,
+ U64_C(0x822c1b362b91c793) /* 690 */, U64_C(0x4eb14655fb13dfd8) /* 691 */,
+ U64_C(0x1ecbba0714e2a97b) /* 692 */, U64_C(0x6143459d5cde5f14) /* 693 */,
+ U64_C(0x53a8fbf1d5f0ac89) /* 694 */, U64_C(0x97ea04d81c5e5b00) /* 695 */,
+ U64_C(0x622181a8d4fdb3f3) /* 696 */, U64_C(0xe9bcd341572a1208) /* 697 */,
+ U64_C(0x1411258643cce58a) /* 698 */, U64_C(0x9144c5fea4c6e0a4) /* 699 */,
+ U64_C(0x0d33d06565cf620f) /* 700 */, U64_C(0x54a48d489f219ca1) /* 701 */,
+ U64_C(0xc43e5eac6d63c821) /* 702 */, U64_C(0xa9728b3a72770daf) /* 703 */,
+ U64_C(0xd7934e7b20df87ef) /* 704 */, U64_C(0xe35503b61a3e86e5) /* 705 */,
+ U64_C(0xcae321fbc819d504) /* 706 */, U64_C(0x129a50b3ac60bfa6) /* 707 */,
+ U64_C(0xcd5e68ea7e9fb6c3) /* 708 */, U64_C(0xb01c90199483b1c7) /* 709 */,
+ U64_C(0x3de93cd5c295376c) /* 710 */, U64_C(0xaed52edf2ab9ad13) /* 711 */,
+ U64_C(0x2e60f512c0a07884) /* 712 */, U64_C(0xbc3d86a3e36210c9) /* 713 */,
+ U64_C(0x35269d9b163951ce) /* 714 */, U64_C(0x0c7d6e2ad0cdb5fa) /* 715 */,
+ U64_C(0x59e86297d87f5733) /* 716 */, U64_C(0x298ef221898db0e7) /* 717 */,
+ U64_C(0x55000029d1a5aa7e) /* 718 */, U64_C(0x8bc08ae1b5061b45) /* 719 */,
+ U64_C(0xc2c31c2b6c92703a) /* 720 */, U64_C(0x94cc596baf25ef42) /* 721 */,
+ U64_C(0x0a1d73db22540456) /* 722 */, U64_C(0x04b6a0f9d9c4179a) /* 723 */,
+ U64_C(0xeffdafa2ae3d3c60) /* 724 */, U64_C(0xf7c8075bb49496c4) /* 725 */,
+ U64_C(0x9cc5c7141d1cd4e3) /* 726 */, U64_C(0x78bd1638218e5534) /* 727 */,
+ U64_C(0xb2f11568f850246a) /* 728 */, U64_C(0xedfabcfa9502bc29) /* 729 */,
+ U64_C(0x796ce5f2da23051b) /* 730 */, U64_C(0xaae128b0dc93537c) /* 731 */,
+ U64_C(0x3a493da0ee4b29ae) /* 732 */, U64_C(0xb5df6b2c416895d7) /* 733 */,
+ U64_C(0xfcabbd25122d7f37) /* 734 */, U64_C(0x70810b58105dc4b1) /* 735 */,
+ U64_C(0xe10fdd37f7882a90) /* 736 */, U64_C(0x524dcab5518a3f5c) /* 737 */,
+ U64_C(0x3c9e85878451255b) /* 738 */, U64_C(0x4029828119bd34e2) /* 739 */,
+ U64_C(0x74a05b6f5d3ceccb) /* 740 */, U64_C(0xb610021542e13eca) /* 741 */,
+ U64_C(0x0ff979d12f59e2ac) /* 742 */, U64_C(0x6037da27e4f9cc50) /* 743 */,
+ U64_C(0x5e92975a0df1847d) /* 744 */, U64_C(0xd66de190d3e623fe) /* 745 */,
+ U64_C(0x5032d6b87b568048) /* 746 */, U64_C(0x9a36b7ce8235216e) /* 747 */,
+ U64_C(0x80272a7a24f64b4a) /* 748 */, U64_C(0x93efed8b8c6916f7) /* 749 */,
+ U64_C(0x37ddbff44cce1555) /* 750 */, U64_C(0x4b95db5d4b99bd25) /* 751 */,
+ U64_C(0x92d3fda169812fc0) /* 752 */, U64_C(0xfb1a4a9a90660bb6) /* 753 */,
+ U64_C(0x730c196946a4b9b2) /* 754 */, U64_C(0x81e289aa7f49da68) /* 755 */,
+ U64_C(0x64669a0f83b1a05f) /* 756 */, U64_C(0x27b3ff7d9644f48b) /* 757 */,
+ U64_C(0xcc6b615c8db675b3) /* 758 */, U64_C(0x674f20b9bcebbe95) /* 759 */,
+ U64_C(0x6f31238275655982) /* 760 */, U64_C(0x5ae488713e45cf05) /* 761 */,
+ U64_C(0xbf619f9954c21157) /* 762 */, U64_C(0xeabac46040a8eae9) /* 763 */,
+ U64_C(0x454c6fe9f2c0c1cd) /* 764 */, U64_C(0x419cf6496412691c) /* 765 */,
+ U64_C(0xd3dc3bef265b0f70) /* 766 */, U64_C(0x6d0e60f5c3578a9e) /* 767 */
+};
+static u64 sbox4[256] = {
+ U64_C(0x5b0e608526323c55) /* 768 */, U64_C(0x1a46c1a9fa1b59f5) /* 769 */,
+ U64_C(0xa9e245a17c4c8ffa) /* 770 */, U64_C(0x65ca5159db2955d7) /* 771 */,
+ U64_C(0x05db0a76ce35afc2) /* 772 */, U64_C(0x81eac77ea9113d45) /* 773 */,
+ U64_C(0x528ef88ab6ac0a0d) /* 774 */, U64_C(0xa09ea253597be3ff) /* 775 */,
+ U64_C(0x430ddfb3ac48cd56) /* 776 */, U64_C(0xc4b3a67af45ce46f) /* 777 */,
+ U64_C(0x4ececfd8fbe2d05e) /* 778 */, U64_C(0x3ef56f10b39935f0) /* 779 */,
+ U64_C(0x0b22d6829cd619c6) /* 780 */, U64_C(0x17fd460a74df2069) /* 781 */,
+ U64_C(0x6cf8cc8e8510ed40) /* 782 */, U64_C(0xd6c824bf3a6ecaa7) /* 783 */,
+ U64_C(0x61243d581a817049) /* 784 */, U64_C(0x048bacb6bbc163a2) /* 785 */,
+ U64_C(0xd9a38ac27d44cc32) /* 786 */, U64_C(0x7fddff5baaf410ab) /* 787 */,
+ U64_C(0xad6d495aa804824b) /* 788 */, U64_C(0xe1a6a74f2d8c9f94) /* 789 */,
+ U64_C(0xd4f7851235dee8e3) /* 790 */, U64_C(0xfd4b7f886540d893) /* 791 */,
+ U64_C(0x247c20042aa4bfda) /* 792 */, U64_C(0x096ea1c517d1327c) /* 793 */,
+ U64_C(0xd56966b4361a6685) /* 794 */, U64_C(0x277da5c31221057d) /* 795 */,
+ U64_C(0x94d59893a43acff7) /* 796 */, U64_C(0x64f0c51ccdc02281) /* 797 */,
+ U64_C(0x3d33bcc4ff6189db) /* 798 */, U64_C(0xe005cb184ce66af1) /* 799 */,
+ U64_C(0xff5ccd1d1db99bea) /* 800 */, U64_C(0xb0b854a7fe42980f) /* 801 */,
+ U64_C(0x7bd46a6a718d4b9f) /* 802 */, U64_C(0xd10fa8cc22a5fd8c) /* 803 */,
+ U64_C(0xd31484952be4bd31) /* 804 */, U64_C(0xc7fa975fcb243847) /* 805 */,
+ U64_C(0x4886ed1e5846c407) /* 806 */, U64_C(0x28cddb791eb70b04) /* 807 */,
+ U64_C(0xc2b00be2f573417f) /* 808 */, U64_C(0x5c9590452180f877) /* 809 */,
+ U64_C(0x7a6bddfff370eb00) /* 810 */, U64_C(0xce509e38d6d9d6a4) /* 811 */,
+ U64_C(0xebeb0f00647fa702) /* 812 */, U64_C(0x1dcc06cf76606f06) /* 813 */,
+ U64_C(0xe4d9f28ba286ff0a) /* 814 */, U64_C(0xd85a305dc918c262) /* 815 */,
+ U64_C(0x475b1d8732225f54) /* 816 */, U64_C(0x2d4fb51668ccb5fe) /* 817 */,
+ U64_C(0xa679b9d9d72bba20) /* 818 */, U64_C(0x53841c0d912d43a5) /* 819 */,
+ U64_C(0x3b7eaa48bf12a4e8) /* 820 */, U64_C(0x781e0e47f22f1ddf) /* 821 */,
+ U64_C(0xeff20ce60ab50973) /* 822 */, U64_C(0x20d261d19dffb742) /* 823 */,
+ U64_C(0x16a12b03062a2e39) /* 824 */, U64_C(0x1960eb2239650495) /* 825 */,
+ U64_C(0x251c16fed50eb8b8) /* 826 */, U64_C(0x9ac0c330f826016e) /* 827 */,
+ U64_C(0xed152665953e7671) /* 828 */, U64_C(0x02d63194a6369570) /* 829 */,
+ U64_C(0x5074f08394b1c987) /* 830 */, U64_C(0x70ba598c90b25ce1) /* 831 */,
+ U64_C(0x794a15810b9742f6) /* 832 */, U64_C(0x0d5925e9fcaf8c6c) /* 833 */,
+ U64_C(0x3067716cd868744e) /* 834 */, U64_C(0x910ab077e8d7731b) /* 835 */,
+ U64_C(0x6a61bbdb5ac42f61) /* 836 */, U64_C(0x93513efbf0851567) /* 837 */,
+ U64_C(0xf494724b9e83e9d5) /* 838 */, U64_C(0xe887e1985c09648d) /* 839 */,
+ U64_C(0x34b1d3c675370cfd) /* 840 */, U64_C(0xdc35e433bc0d255d) /* 841 */,
+ U64_C(0xd0aab84234131be0) /* 842 */, U64_C(0x08042a50b48b7eaf) /* 843 */,
+ U64_C(0x9997c4ee44a3ab35) /* 844 */, U64_C(0x829a7b49201799d0) /* 845 */,
+ U64_C(0x263b8307b7c54441) /* 846 */, U64_C(0x752f95f4fd6a6ca6) /* 847 */,
+ U64_C(0x927217402c08c6e5) /* 848 */, U64_C(0x2a8ab754a795d9ee) /* 849 */,
+ U64_C(0xa442f7552f72943d) /* 850 */, U64_C(0x2c31334e19781208) /* 851 */,
+ U64_C(0x4fa98d7ceaee6291) /* 852 */, U64_C(0x55c3862f665db309) /* 853 */,
+ U64_C(0xbd0610175d53b1f3) /* 854 */, U64_C(0x46fe6cb840413f27) /* 855 */,
+ U64_C(0x3fe03792df0cfa59) /* 856 */, U64_C(0xcfe700372eb85e8f) /* 857 */,
+ U64_C(0xa7be29e7adbce118) /* 858 */, U64_C(0xe544ee5cde8431dd) /* 859 */,
+ U64_C(0x8a781b1b41f1873e) /* 860 */, U64_C(0xa5c94c78a0d2f0e7) /* 861 */,
+ U64_C(0x39412e2877b60728) /* 862 */, U64_C(0xa1265ef3afc9a62c) /* 863 */,
+ U64_C(0xbcc2770c6a2506c5) /* 864 */, U64_C(0x3ab66dd5dce1ce12) /* 865 */,
+ U64_C(0xe65499d04a675b37) /* 866 */, U64_C(0x7d8f523481bfd216) /* 867 */,
+ U64_C(0x0f6f64fcec15f389) /* 868 */, U64_C(0x74efbe618b5b13c8) /* 869 */,
+ U64_C(0xacdc82b714273e1d) /* 870 */, U64_C(0xdd40bfe003199d17) /* 871 */,
+ U64_C(0x37e99257e7e061f8) /* 872 */, U64_C(0xfa52626904775aaa) /* 873 */,
+ U64_C(0x8bbbf63a463d56f9) /* 874 */, U64_C(0xf0013f1543a26e64) /* 875 */,
+ U64_C(0xa8307e9f879ec898) /* 876 */, U64_C(0xcc4c27a4150177cc) /* 877 */,
+ U64_C(0x1b432f2cca1d3348) /* 878 */, U64_C(0xde1d1f8f9f6fa013) /* 879 */,
+ U64_C(0x606602a047a7ddd6) /* 880 */, U64_C(0xd237ab64cc1cb2c7) /* 881 */,
+ U64_C(0x9b938e7225fcd1d3) /* 882 */, U64_C(0xec4e03708e0ff476) /* 883 */,
+ U64_C(0xfeb2fbda3d03c12d) /* 884 */, U64_C(0xae0bced2ee43889a) /* 885 */,
+ U64_C(0x22cb8923ebfb4f43) /* 886 */, U64_C(0x69360d013cf7396d) /* 887 */,
+ U64_C(0x855e3602d2d4e022) /* 888 */, U64_C(0x073805bad01f784c) /* 889 */,
+ U64_C(0x33e17a133852f546) /* 890 */, U64_C(0xdf4874058ac7b638) /* 891 */,
+ U64_C(0xba92b29c678aa14a) /* 892 */, U64_C(0x0ce89fc76cfaadcd) /* 893 */,
+ U64_C(0x5f9d4e0908339e34) /* 894 */, U64_C(0xf1afe9291f5923b9) /* 895 */,
+ U64_C(0x6e3480f60f4a265f) /* 896 */, U64_C(0xeebf3a2ab29b841c) /* 897 */,
+ U64_C(0xe21938a88f91b4ad) /* 898 */, U64_C(0x57dfeff845c6d3c3) /* 899 */,
+ U64_C(0x2f006b0bf62caaf2) /* 900 */, U64_C(0x62f479ef6f75ee78) /* 901 */,
+ U64_C(0x11a55ad41c8916a9) /* 902 */, U64_C(0xf229d29084fed453) /* 903 */,
+ U64_C(0x42f1c27b16b000e6) /* 904 */, U64_C(0x2b1f76749823c074) /* 905 */,
+ U64_C(0x4b76eca3c2745360) /* 906 */, U64_C(0x8c98f463b91691bd) /* 907 */,
+ U64_C(0x14bcc93cf1ade66a) /* 908 */, U64_C(0x8885213e6d458397) /* 909 */,
+ U64_C(0x8e177df0274d4711) /* 910 */, U64_C(0xb49b73b5503f2951) /* 911 */,
+ U64_C(0x10168168c3f96b6b) /* 912 */, U64_C(0x0e3d963b63cab0ae) /* 913 */,
+ U64_C(0x8dfc4b5655a1db14) /* 914 */, U64_C(0xf789f1356e14de5c) /* 915 */,
+ U64_C(0x683e68af4e51dac1) /* 916 */, U64_C(0xc9a84f9d8d4b0fd9) /* 917 */,
+ U64_C(0x3691e03f52a0f9d1) /* 918 */, U64_C(0x5ed86e46e1878e80) /* 919 */,
+ U64_C(0x3c711a0e99d07150) /* 920 */, U64_C(0x5a0865b20c4e9310) /* 921 */,
+ U64_C(0x56fbfc1fe4f0682e) /* 922 */, U64_C(0xea8d5de3105edf9b) /* 923 */,
+ U64_C(0x71abfdb12379187a) /* 924 */, U64_C(0x2eb99de1bee77b9c) /* 925 */,
+ U64_C(0x21ecc0ea33cf4523) /* 926 */, U64_C(0x59a4d7521805c7a1) /* 927 */,
+ U64_C(0x3896f5eb56ae7c72) /* 928 */, U64_C(0xaa638f3db18f75dc) /* 929 */,
+ U64_C(0x9f39358dabe9808e) /* 930 */, U64_C(0xb7defa91c00b72ac) /* 931 */,
+ U64_C(0x6b5541fd62492d92) /* 932 */, U64_C(0x6dc6dee8f92e4d5b) /* 933 */,
+ U64_C(0x353f57abc4beea7e) /* 934 */, U64_C(0x735769d6da5690ce) /* 935 */,
+ U64_C(0x0a234aa642391484) /* 936 */, U64_C(0xf6f9508028f80d9d) /* 937 */,
+ U64_C(0xb8e319a27ab3f215) /* 938 */, U64_C(0x31ad9c1151341a4d) /* 939 */,
+ U64_C(0x773c22a57bef5805) /* 940 */, U64_C(0x45c7561a07968633) /* 941 */,
+ U64_C(0xf913da9e249dbe36) /* 942 */, U64_C(0xda652d9b78a64c68) /* 943 */,
+ U64_C(0x4c27a97f3bc334ef) /* 944 */, U64_C(0x76621220e66b17f4) /* 945 */,
+ U64_C(0x967743899acd7d0b) /* 946 */, U64_C(0xf3ee5bcae0ed6782) /* 947 */,
+ U64_C(0x409f753600c879fc) /* 948 */, U64_C(0x06d09a39b5926db6) /* 949 */,
+ U64_C(0x6f83aeb0317ac588) /* 950 */, U64_C(0x01e6ca4a86381f21) /* 951 */,
+ U64_C(0x66ff3462d19f3025) /* 952 */, U64_C(0x72207c24ddfd3bfb) /* 953 */,
+ U64_C(0x4af6b6d3e2ece2eb) /* 954 */, U64_C(0x9c994dbec7ea08de) /* 955 */,
+ U64_C(0x49ace597b09a8bc4) /* 956 */, U64_C(0xb38c4766cf0797ba) /* 957 */,
+ U64_C(0x131b9373c57c2a75) /* 958 */, U64_C(0xb1822cce61931e58) /* 959 */,
+ U64_C(0x9d7555b909ba1c0c) /* 960 */, U64_C(0x127fafdd937d11d2) /* 961 */,
+ U64_C(0x29da3badc66d92e4) /* 962 */, U64_C(0xa2c1d57154c2ecbc) /* 963 */,
+ U64_C(0x58c5134d82f6fe24) /* 964 */, U64_C(0x1c3ae3515b62274f) /* 965 */,
+ U64_C(0xe907c82e01cb8126) /* 966 */, U64_C(0xf8ed091913e37fcb) /* 967 */,
+ U64_C(0x3249d8f9c80046c9) /* 968 */, U64_C(0x80cf9bede388fb63) /* 969 */,
+ U64_C(0x1881539a116cf19e) /* 970 */, U64_C(0x5103f3f76bd52457) /* 971 */,
+ U64_C(0x15b7e6f5ae47f7a8) /* 972 */, U64_C(0xdbd7c6ded47e9ccf) /* 973 */,
+ U64_C(0x44e55c410228bb1a) /* 974 */, U64_C(0xb647d4255edb4e99) /* 975 */,
+ U64_C(0x5d11882bb8aafc30) /* 976 */, U64_C(0xf5098bbb29d3212a) /* 977 */,
+ U64_C(0x8fb5ea14e90296b3) /* 978 */, U64_C(0x677b942157dd025a) /* 979 */,
+ U64_C(0xfb58e7c0a390acb5) /* 980 */, U64_C(0x89d3674c83bd4a01) /* 981 */,
+ U64_C(0x9e2da4df4bf3b93b) /* 982 */, U64_C(0xfcc41e328cab4829) /* 983 */,
+ U64_C(0x03f38c96ba582c52) /* 984 */, U64_C(0xcad1bdbd7fd85db2) /* 985 */,
+ U64_C(0xbbb442c16082ae83) /* 986 */, U64_C(0xb95fe86ba5da9ab0) /* 987 */,
+ U64_C(0xb22e04673771a93f) /* 988 */, U64_C(0x845358c9493152d8) /* 989 */,
+ U64_C(0xbe2a488697b4541e) /* 990 */, U64_C(0x95a2dc2dd38e6966) /* 991 */,
+ U64_C(0xc02c11ac923c852b) /* 992 */, U64_C(0x2388b1990df2a87b) /* 993 */,
+ U64_C(0x7c8008fa1b4f37be) /* 994 */, U64_C(0x1f70d0c84d54e503) /* 995 */,
+ U64_C(0x5490adec7ece57d4) /* 996 */, U64_C(0x002b3c27d9063a3a) /* 997 */,
+ U64_C(0x7eaea3848030a2bf) /* 998 */, U64_C(0xc602326ded2003c0) /* 999 */,
+ U64_C(0x83a7287d69a94086) /* 1000 */, U64_C(0xc57a5fcb30f57a8a) /* 1001 */,
+ U64_C(0xb56844e479ebe779) /* 1002 */, U64_C(0xa373b40f05dcbce9) /* 1003 */,
+ U64_C(0xd71a786e88570ee2) /* 1004 */, U64_C(0x879cbacdbde8f6a0) /* 1005 */,
+ U64_C(0x976ad1bcc164a32f) /* 1006 */, U64_C(0xab21e25e9666d78b) /* 1007 */,
+ U64_C(0x901063aae5e5c33c) /* 1008 */, U64_C(0x9818b34448698d90) /* 1009 */,
+ U64_C(0xe36487ae3e1e8abb) /* 1010 */, U64_C(0xafbdf931893bdcb4) /* 1011 */,
+ U64_C(0x6345a0dc5fbbd519) /* 1012 */, U64_C(0x8628fe269b9465ca) /* 1013 */,
+ U64_C(0x1e5d01603f9c51ec) /* 1014 */, U64_C(0x4de44006a15049b7) /* 1015 */,
+ U64_C(0xbf6c70e5f776cbb1) /* 1016 */, U64_C(0x411218f2ef552bed) /* 1017 */,
+ U64_C(0xcb0c0708705a36a3) /* 1018 */, U64_C(0xe74d14754f986044) /* 1019 */,
+ U64_C(0xcd56d9430ea8280e) /* 1020 */, U64_C(0xc12591d7535f5065) /* 1021 */,
+ U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
+};
+
+static void
+do_init (void *context, int variant)
+{
+ TIGER_CONTEXT *hd = context;
+
+ hd->a = 0x0123456789abcdefLL;
+ hd->b = 0xfedcba9876543210LL;
+ hd->c = 0xf096a5b4c3b2e187LL;
+ hd->nblocks = 0;
+ hd->count = 0;
+ hd->variant = variant;
+}
+
+static void
+tiger_init (void *context)
+{
+ do_init (context, 0);
+}
+
+static void
+tiger1_init (void *context)
+{
+ do_init (context, 1);
+}
+
+static void
+tiger2_init (void *context)
+{
+ do_init (context, 2);
+}
+
+static void
+tiger_round( u64 *ra, u64 *rb, u64 *rc, u64 x, int mul )
+{
+ u64 a = *ra;
+ u64 b = *rb;
+ u64 c = *rc;
+
+ c ^= x;
+ a -= ( sbox1[ c & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
+ ^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
+ b += ( sbox4[ (c >> 8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
+ ^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
+ b *= mul;
+
+ *ra = a;
+ *rb = b;
+ *rc = c;
+}
+
+
+static void
+pass( u64 *ra, u64 *rb, u64 *rc, u64 *x, int mul )
+{
+ u64 a = *ra;
+ u64 b = *rb;
+ u64 c = *rc;
+
+ tiger_round( &a, &b, &c, x[0], mul );
+ tiger_round( &b, &c, &a, x[1], mul );
+ tiger_round( &c, &a, &b, x[2], mul );
+ tiger_round( &a, &b, &c, x[3], mul );
+ tiger_round( &b, &c, &a, x[4], mul );
+ tiger_round( &c, &a, &b, x[5], mul );
+ tiger_round( &a, &b, &c, x[6], mul );
+ tiger_round( &b, &c, &a, x[7], mul );
+
+ *ra = a;
+ *rb = b;
+ *rc = c;
+}
+
+
+static void
+key_schedule( u64 *x )
+{
+ x[0] -= x[7] ^ 0xa5a5a5a5a5a5a5a5LL;
+ x[1] ^= x[0];
+ x[2] += x[1];
+ x[3] -= x[2] ^ ((~x[1]) << 19 );
+ x[4] ^= x[3];
+ x[5] += x[4];
+ x[6] -= x[5] ^ ((~x[4]) >> 23 );
+ x[7] ^= x[6];
+ x[0] += x[7];
+ x[1] -= x[0] ^ ((~x[7]) << 19 );
+ x[2] ^= x[1];
+ x[3] += x[2];
+ x[4] -= x[3] ^ ((~x[2]) >> 23 );
+ x[5] ^= x[4];
+ x[6] += x[5];
+ x[7] -= x[6] ^ 0x0123456789abcdefLL;
+}
+
+
+/****************
+ * Transform the message DATA which consists of 512 bytes (8 words)
+ */
+static void
+transform ( TIGER_CONTEXT *hd, const unsigned char *data )
+{
+ u64 a,b,c,aa,bb,cc;
+ u64 x[8];
+#ifdef WORDS_BIGENDIAN
+#define MKWORD(d,n) \
+ ( ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48 \
+ | ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32 \
+ | ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16 \
+ | ((u64)(d)[8*(n)+1]) << 8 | ((u64)(d)[8*(n) ]) )
+ x[0] = MKWORD(data, 0);
+ x[1] = MKWORD(data, 1);
+ x[2] = MKWORD(data, 2);
+ x[3] = MKWORD(data, 3);
+ x[4] = MKWORD(data, 4);
+ x[5] = MKWORD(data, 5);
+ x[6] = MKWORD(data, 6);
+ x[7] = MKWORD(data, 7);
+#undef MKWORD
+#else
+ memcpy( &x[0], data, 64 );
+#endif
+
+ /* save */
+ a = aa = hd->a;
+ b = bb = hd->b;
+ c = cc = hd->c;
+
+ pass( &a, &b, &c, x, 5);
+ key_schedule( x );
+ pass( &c, &a, &b, x, 7);
+ key_schedule( x );
+ pass( &b, &c, &a, x, 9);
+
+ /* feedforward */
+ a ^= aa;
+ b -= bb;
+ c += cc;
+ /* store */
+ hd->a = a;
+ hd->b = b;
+ hd->c = c;
+}
+
+
+
+/* Update the message digest with the contents
+ * of INBUF with length INLEN.
+ */
+static void
+tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
+{
+ const unsigned char *inbuf = inbuf_arg;
+ TIGER_CONTEXT *hd = context;
+
+ if( hd->count == 64 ) /* flush the buffer */
+ {
+ transform( hd, hd->buf );
+ _gcry_burn_stack (21*8+11*sizeof(void*));
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+ if( hd->count )
+ {
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ tiger_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+
+ while( inlen >= 64 )
+ {
+ transform( hd, inbuf );
+ hd->count = 0;
+ hd->nblocks++;
+ inlen -= 64;
+ inbuf += 64;
+ }
+ _gcry_burn_stack (21*8+11*sizeof(void*));
+ for( ; inlen && hd->count < 64; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+
+/* The routine terminates the computation
+ */
+static void
+tiger_final( void *context )
+{
+ TIGER_CONTEXT *hd = context;
+ u32 t, msb, lsb;
+ byte *p;
+ byte pad = hd->variant == 2? 0x80 : 0x01;
+
+ tiger_write(hd, NULL, 0); /* flush */;
+
+ t = hd->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* add the count */
+ t = lsb;
+ if( (lsb += hd->count) < t )
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if( hd->count < 56 ) /* enough room */
+ {
+ hd->buf[hd->count++] = pad;
+ while( hd->count < 56 )
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else /* need one extra block */
+ {
+ hd->buf[hd->count++] = pad; /* pad character */
+ while( hd->count < 64 )
+ hd->buf[hd->count++] = 0;
+ tiger_write(hd, NULL, 0); /* flush */;
+ memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ }
+ /* append the 64 bit count */
+ hd->buf[56] = lsb ;
+ hd->buf[57] = lsb >> 8;
+ hd->buf[58] = lsb >> 16;
+ hd->buf[59] = lsb >> 24;
+ hd->buf[60] = msb ;
+ hd->buf[61] = msb >> 8;
+ hd->buf[62] = msb >> 16;
+ hd->buf[63] = msb >> 24;
+ transform( hd, hd->buf );
+ _gcry_burn_stack (21*8+11*sizeof(void*));
+
+ p = hd->buf;
+#ifdef WORDS_BIGENDIAN
+#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
+#else /* little endian */
+#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \
+ *p++ = hd->a >> 40; *p++ = hd->a >> 32; \
+ *p++ = hd->a >> 24; *p++ = hd->a >> 16; \
+ *p++ = hd->a >> 8; *p++ = hd->a; } while(0)
+#endif
+#define Y(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
+ *p++ = hd->a >> 16; *p++ = hd->a >> 24; \
+ *p++ = hd->a >> 32; *p++ = hd->a >> 40; \
+ *p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0)
+ if (hd->variant == 0)
+ {
+ X(a);
+ X(b);
+ X(c);
+ }
+ else
+ {
+ Y(a);
+ Y(b);
+ Y(c);
+ }
+#undef X
+#undef Y
+}
+
+static byte *
+tiger_read( void *context )
+{
+ TIGER_CONTEXT *hd = context;
+
+ return hd->buf;
+}
+
+
+\f
+/* This is the old TIGER variant based on the unfixed reference
+ implementation. IT was used in GnupG up to 1.3.2. We don't provide
+ an OID anymore because that would not be correct. */
+gcry_md_spec_t _gcry_digest_spec_tiger =
+ {
+ "TIGER192", NULL, 0, NULL, 24,
+ tiger_init, tiger_write, tiger_final, tiger_read,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+\f
+/* This is the fixed TIGER implementation. */
+static byte asn1[19] = /* Object ID is 1.3.6.1.4.1.11591.12.2 */
+ { 0x30, 0x29, 0x30, 0x0d, 0x06, 0x09, 0x2b, 0x06,
+ 0x01, 0x04, 0x01, 0xda, 0x47, 0x0c, 0x02,
+ 0x05, 0x00, 0x04, 0x18 };
+
+static gcry_md_oid_spec_t oid_spec_tiger1[] =
+ {
+ /* GNU.digestAlgorithm TIGER */
+ { "1.3.6.1.4.1.11591.12.2" },
+ { NULL }
+ };
+
+gcry_md_spec_t _gcry_digest_spec_tiger1 =
+ {
+ "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
+ tiger1_init, tiger_write, tiger_final, tiger_read,
+ sizeof (TIGER_CONTEXT)
+ };
+
+
+\f
+/* This is TIGER2 which usues a changed padding algorithm. */
+gcry_md_spec_t _gcry_digest_spec_tiger2 =
+ {
+ "TIGER2", NULL, 0, NULL, 24,
+ tiger2_init, tiger_write, tiger_final, tiger_read,
+ sizeof (TIGER_CONTEXT)
+ };
+
+#endif /* HAVE_U64_TYPEDEF */
--- /dev/null
+/* Twofish for GPG
+ * Copyright (C) 1998, 2002, 2003 Free Software Foundation, Inc.
+ * Written by Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
+ * 256-bit key length added March 20, 1999
+ * Some modifications to reduce the text size by Werner Koch, April, 1998
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ ********************************************************************
+ *
+ * This code is a "clean room" implementation, written from the paper
+ * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
+ * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
+ * through http://www.counterpane.com/twofish.html
+ *
+ * For background information on multiplication in finite fields, used for
+ * the matrix operations in the key schedule, see the book _Contemporary
+ * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
+ * Third Edition.
+ *
+ * Only the 128- and 256-bit key sizes are supported. This code is intended
+ * for GNU C on a 32-bit system, but it should work almost anywhere. Loops
+ * are unrolled, precomputation tables are used, etc., for maximum speed at
+ * some cost in memory consumption. */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* for memcmp() */
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+/* Prototype for the self-test function. */
+static const char *selftest(void);
+
+/* Structure for an expanded Twofish key. s contains the key-dependent
+ * S-boxes composed with the MDS matrix; w contains the eight "whitening"
+ * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note
+ * that k[i] corresponds to what the Twofish paper calls K[i+8]. */
+typedef struct {
+ u32 s[4][256], w[8], k[32];
+} TWOFISH_context;
+\f
+/* These two tables are the q0 and q1 permutations, exactly as described in
+ * the Twofish paper. */
+
+static const byte q0[256] = {
+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
+ 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
+ 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
+ 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
+ 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
+ 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
+ 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
+ 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
+ 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
+ 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
+ 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
+ 0x4A, 0x5E, 0xC1, 0xE0
+};
+
+static const byte q1[256] = {
+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
+ 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
+ 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
+ 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
+ 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
+ 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
+ 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
+ 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
+ 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
+ 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
+ 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
+ 0x55, 0x09, 0xBE, 0x91
+};
+\f
+/* These MDS tables are actually tables of MDS composed with q0 and q1,
+ * because it is only ever used that way and we can save some time by
+ * precomputing. Of course the main saving comes from precomputing the
+ * GF(2^8) multiplication involved in the MDS matrix multiply; by looking
+ * things up in these tables we reduce the matrix multiply to four lookups
+ * and three XORs. Semi-formally, the definition of these tables is:
+ * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T
+ * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T
+ * where ^T means "transpose", the matrix multiply is performed in GF(2^8)
+ * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described
+ * by Schneier et al, and I'm casually glossing over the byte/word
+ * conversion issues. */
+
+static const u32 mds[4][256] = {
+ {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B,
+ 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B,
+ 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32,
+ 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+ 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA,
+ 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B,
+ 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1,
+ 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+ 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490,
+ 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154,
+ 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0,
+ 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+ 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228,
+ 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7,
+ 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3,
+ 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+ 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477,
+ 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF,
+ 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C,
+ 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+ 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA,
+ 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D,
+ 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72,
+ 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+ 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76,
+ 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321,
+ 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39,
+ 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+ 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D,
+ 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E,
+ 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5,
+ 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+ 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7,
+ 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544,
+ 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E,
+ 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+ 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A,
+ 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B,
+ 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2,
+ 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+ 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504,
+ 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756,
+ 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91},
+
+ {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252,
+ 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A,
+ 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020,
+ 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+ 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444,
+ 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424,
+ 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A,
+ 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+ 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383,
+ 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A,
+ 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9,
+ 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+ 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1,
+ 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898,
+ 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414,
+ 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+ 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1,
+ 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989,
+ 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5,
+ 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+ 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E,
+ 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E,
+ 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202,
+ 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+ 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565,
+ 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A,
+ 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808,
+ 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+ 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A,
+ 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969,
+ 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505,
+ 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+ 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D,
+ 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343,
+ 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF,
+ 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+ 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F,
+ 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646,
+ 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6,
+ 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+ 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A,
+ 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7,
+ 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8},
+
+ {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B,
+ 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F,
+ 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A,
+ 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+ 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70,
+ 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3,
+ 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB,
+ 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+ 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4,
+ 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41,
+ 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C,
+ 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+ 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622,
+ 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18,
+ 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035,
+ 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+ 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84,
+ 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E,
+ 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F,
+ 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+ 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558,
+ 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40,
+ 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA,
+ 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+ 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF,
+ 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773,
+ 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D,
+ 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+ 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C,
+ 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19,
+ 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086,
+ 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+ 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74,
+ 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755,
+ 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691,
+ 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+ 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4,
+ 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53,
+ 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E,
+ 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+ 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705,
+ 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7,
+ 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF},
+
+ {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98,
+ 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866,
+ 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643,
+ 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+ 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9,
+ 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C,
+ 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3,
+ 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+ 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F,
+ 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25,
+ 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF,
+ 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+ 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4,
+ 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E,
+ 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA,
+ 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+ 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12,
+ 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A,
+ 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D,
+ 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+ 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A,
+ 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C,
+ 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B,
+ 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+ 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B,
+ 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3,
+ 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE,
+ 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+ 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85,
+ 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA,
+ 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E,
+ 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+ 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33,
+ 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC,
+ 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718,
+ 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+ 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8,
+ 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872,
+ 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882,
+ 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+ 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10,
+ 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6,
+ 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8}
+};
+\f
+/* The exp_to_poly and poly_to_exp tables are used to perform efficient
+ * operations in GF(2^8) represented as GF(2)[x]/w(x) where
+ * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the
+ * definition of the RS matrix in the key schedule. Elements of that field
+ * are polynomials of degree not greater than 7 and all coefficients 0 or 1,
+ * which can be represented naturally by bytes (just substitute x=2). In that
+ * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8)
+ * multiplication is inefficient without hardware support. To multiply
+ * faster, I make use of the fact x is a generator for the nonzero elements,
+ * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for
+ * some n in 0..254. Note that that caret is exponentiation in GF(2^8),
+ * *not* polynomial notation. So if I want to compute pq where p and q are
+ * in GF(2^8), I can just say:
+ * 1. if p=0 or q=0 then pq=0
+ * 2. otherwise, find m and n such that p=x^m and q=x^n
+ * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq
+ * The translations in steps 2 and 3 are looked up in the tables
+ * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this
+ * in action, look at the CALC_S macro. As additional wrinkles, note that
+ * one of my operands is always a constant, so the poly_to_exp lookup on it
+ * is done in advance; I included the original values in the comments so
+ * readers can have some chance of recognizing that this *is* the RS matrix
+ * from the Twofish paper. I've only included the table entries I actually
+ * need; I never do a lookup on a variable input of zero and the biggest
+ * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll
+ * never sum to more than 491. I'm repeating part of the exp_to_poly table
+ * so that I don't have to do mod-255 reduction in the exponent arithmetic.
+ * Since I know my constant operands are never zero, I only have to worry
+ * about zero values in the variable operand, and I do it with a simple
+ * conditional branch. I know conditionals are expensive, but I couldn't
+ * see a non-horrible way of avoiding them, and I did manage to group the
+ * statements so that each if covers four group multiplications. */
+
+static const byte poly_to_exp[255] = {
+ 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19,
+ 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A,
+ 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C,
+ 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B,
+ 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47,
+ 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D,
+ 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8,
+ 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C,
+ 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83,
+ 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48,
+ 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26,
+ 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E,
+ 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3,
+ 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9,
+ 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A,
+ 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D,
+ 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75,
+ 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84,
+ 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64,
+ 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49,
+ 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF,
+ 0x85, 0xC8, 0xA1
+};
+
+static const byte exp_to_poly[492] = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2,
+ 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03,
+ 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6,
+ 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A,
+ 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63,
+ 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C,
+ 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07,
+ 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88,
+ 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12,
+ 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7,
+ 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C,
+ 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8,
+ 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25,
+ 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A,
+ 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE,
+ 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC,
+ 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E,
+ 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92,
+ 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89,
+ 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB,
+ 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1,
+ 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D,
+ 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC,
+ 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3,
+ 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52,
+ 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0,
+ 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1,
+ 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A,
+ 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11,
+ 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51,
+ 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66,
+ 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB,
+ 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19,
+ 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D,
+ 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56,
+ 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE,
+ 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9,
+ 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE,
+ 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41,
+ 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E,
+ 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB
+};
+\f
+
+/* The table constants are indices of
+ * S-box entries, preprocessed through q0 and q1. */
+static byte calc_sb_tbl[512] = {
+ 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4,
+ 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8,
+ 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B,
+ 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B,
+ 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD,
+ 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1,
+ 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B,
+ 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F,
+ 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B,
+ 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D,
+ 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E,
+ 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5,
+ 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14,
+ 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3,
+ 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54,
+ 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51,
+ 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A,
+ 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96,
+ 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10,
+ 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C,
+ 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7,
+ 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70,
+ 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB,
+ 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8,
+ 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF,
+ 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC,
+ 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF,
+ 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2,
+ 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82,
+ 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9,
+ 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97,
+ 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17,
+ 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D,
+ 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3,
+ 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C,
+ 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E,
+ 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F,
+ 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49,
+ 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21,
+ 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9,
+ 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD,
+ 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01,
+ 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F,
+ 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48,
+ 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E,
+ 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19,
+ 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57,
+ 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64,
+ 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE,
+ 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5,
+ 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44,
+ 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69,
+ 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15,
+ 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E,
+ 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34,
+ 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC,
+ 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B,
+ 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB,
+ 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52,
+ 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9,
+ 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4,
+ 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2,
+ 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56,
+ 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91
+};
+/* Macro to perform one column of the RS matrix multiplication. The
+ * parameters a, b, c, and d are the four bytes of output; i is the index
+ * of the key bytes, and w, x, y, and z, are the column of constants from
+ * the RS matrix, preprocessed through the poly_to_exp table. */
+
+#define CALC_S(a, b, c, d, i, w, x, y, z) \
+ if (key[i]) { \
+ tmp = poly_to_exp[key[i] - 1]; \
+ (a) ^= exp_to_poly[tmp + (w)]; \
+ (b) ^= exp_to_poly[tmp + (x)]; \
+ (c) ^= exp_to_poly[tmp + (y)]; \
+ (d) ^= exp_to_poly[tmp + (z)]; \
+ }
+
+/* Macros to calculate the key-dependent S-boxes for a 128-bit key using
+ * the S vector from CALC_S. CALC_SB_2 computes a single entry in all
+ * four S-boxes, where i is the index of the entry to compute, and a and b
+ * are the index numbers preprocessed through the q0 and q1 tables
+ * respectively. CALC_SB is simply a convenience to make the code shorter;
+ * it calls CALC_SB_2 four times with consecutive indices from i to i+3,
+ * using the remaining parameters two by two. */
+
+#define CALC_SB_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \
+ ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \
+ ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \
+ ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh]
+
+#define CALC_SB(i, a, b, c, d, e, f, g, h) \
+ CALC_SB_2 (i, a, b); CALC_SB_2 ((i)+1, c, d); \
+ CALC_SB_2 ((i)+2, e, f); CALC_SB_2 ((i)+3, g, h)
+
+/* Macros exactly like CALC_SB and CALC_SB_2, but for 256-bit keys. */
+
+#define CALC_SB256_2(i, a, b) \
+ ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \
+ ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \
+ ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \
+ ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp];
+
+#define CALC_SB256(i, a, b, c, d, e, f, g, h) \
+ CALC_SB256_2 (i, a, b); CALC_SB256_2 ((i)+1, c, d); \
+ CALC_SB256_2 ((i)+2, e, f); CALC_SB256_2 ((i)+3, g, h)
+
+/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the
+ * last two stages of the h() function for a given index (either 2i or 2i+1).
+ * a, b, c, and d are the four bytes going into the last two stages. For
+ * 128-bit keys, this is the entire h() function and a and c are the index
+ * preprocessed through q0 and q1 respectively; for longer keys they are the
+ * output of previous stages. j is the index of the first key byte to use.
+ * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2
+ * twice, doing the Pseudo-Hadamard Transform, and doing the necessary
+ * rotations. Its parameters are: a, the array to write the results into,
+ * j, the index of the first output entry, k and l, the preprocessed indices
+ * for index 2i, and m and n, the preprocessed indices for index 2i+1.
+ * CALC_K256_2 expands CALC_K_2 to handle 256-bit keys, by doing two
+ * additional lookup-and-XOR stages. The parameters a and b are the index
+ * preprocessed through q0 and q1 respectively; j is the index of the first
+ * key byte to use. CALC_K256 is identical to CALC_K but for using the
+ * CALC_K256_2 macro instead of CALC_K_2. */
+
+#define CALC_K_2(a, b, c, d, j) \
+ mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \
+ ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \
+ ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \
+ ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]]
+
+#define CALC_K(a, j, k, l, m, n) \
+ x = CALC_K_2 (k, l, k, l, 0); \
+ y = CALC_K_2 (m, n, m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+
+#define CALC_K256_2(a, b, j) \
+ CALC_K_2 (q0[q1[b ^ key[(j) + 24]] ^ key[(j) + 16]], \
+ q1[q1[a ^ key[(j) + 25]] ^ key[(j) + 17]], \
+ q0[q0[a ^ key[(j) + 26]] ^ key[(j) + 18]], \
+ q1[q0[b ^ key[(j) + 27]] ^ key[(j) + 19]], j)
+
+#define CALC_K256(a, j, k, l, m, n) \
+ x = CALC_K256_2 (k, l, 0); \
+ y = CALC_K256_2 (m, n, 4); \
+ y = (y << 8) + (y >> 24); \
+ x += y; y += x; ctx->a[j] = x; \
+ ctx->a[(j) + 1] = (y << 9) + (y >> 23)
+\f
+
+
+/* Perform the key setup. Note that this works only with 128- and 256-bit
+ * keys, despite the API that looks like it might support other sizes. */
+
+static gcry_err_code_t
+do_twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen)
+{
+ int i, j, k;
+
+ /* Temporaries for CALC_K. */
+ u32 x, y;
+
+ /* The S vector used to key the S-boxes, split up into individual bytes.
+ * 128-bit keys use only sa through sh; 256-bit use all of them. */
+ byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
+ byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
+
+ /* Temporary for CALC_S. */
+ byte tmp;
+
+ /* Flags for self-test. */
+ static int initialized = 0;
+ static const char *selftest_failed=0;
+
+ /* Check key length. */
+ if( ( ( keylen - 16 ) | 16 ) != 16 )
+ return GPG_ERR_INV_KEYLEN;
+
+ /* Do self-test if necessary. */
+ if (!initialized)
+ {
+ initialized = 1;
+ selftest_failed = selftest ();
+ if( selftest_failed )
+ log_error("%s\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ /* Compute the first two words of the S vector. The magic numbers are
+ * the entries of the RS matrix, preprocessed through poly_to_exp. The
+ * numbers in the comments are the original (polynomial form) matrix
+ * entries. */
+ CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ if (keylen == 32) /* 256-bit key */
+ {
+ /* Calculate the remaining two words of the S vector */
+ CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+ CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */
+ CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */
+ CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */
+ CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */
+ CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */
+ CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */
+ CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */
+ CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */
+
+ /* Compute the S-boxes. */
+ for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
+ {
+ CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ }
+ else
+ {
+ /* Compute the S-boxes. */
+ for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
+ {
+ CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] );
+ }
+
+ /* Calculate whitening and round subkeys. The constants are
+ * indices of subkeys, preprocessed through q0 and q1. */
+ CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3);
+ CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4);
+ CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B);
+ CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8);
+ CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3);
+ CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B);
+ CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D);
+ CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B);
+ CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32);
+ CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD);
+ CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71);
+ CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1);
+ CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F);
+ CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B);
+ CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA);
+ CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F);
+ CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA);
+ CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B);
+ CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00);
+ CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
+ }
+
+ return 0;
+}
+
+static gcry_err_code_t
+twofish_setkey (void *context, const byte *key, unsigned int keylen)
+{
+ TWOFISH_context *ctx = context;
+ int rc = do_twofish_setkey (ctx, key, keylen);
+ _gcry_burn_stack (23+6*sizeof(void*));
+ return rc;
+}
+
+
+\f
+/* Macros to compute the g() function in the encryption and decryption
+ * rounds. G1 is the straight g() function; G2 includes the 8-bit
+ * rotation for the high 32-bit word. */
+
+#define G1(a) \
+ (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \
+ ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24])
+
+#define G2(b) \
+ (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \
+ ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24])
+
+/* Encryption and decryption Feistel rounds. Each one calls the two g()
+ * macros, does the PHT, and performs the XOR and the appropriate bit
+ * rotations. The parameters are the round number (used to select subkeys),
+ * and the four 32-bit chunks of the text. */
+
+#define ENCROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x + ctx->k[2 * (n) + 1]; \
+ (c) ^= x + ctx->k[2 * (n)]; \
+ (c) = ((c) >> 1) + ((c) << 31); \
+ (d) = (((d) << 1)+((d) >> 31)) ^ y
+
+#define DECROUND(n, a, b, c, d) \
+ x = G1 (a); y = G2 (b); \
+ x += y; y += x; \
+ (d) ^= y + ctx->k[2 * (n) + 1]; \
+ (d) = ((d) >> 1) + ((d) << 31); \
+ (c) = (((c) << 1)+((c) >> 31)); \
+ (c) ^= (x + ctx->k[2 * (n)])
+
+/* Encryption and decryption cycles; each one is simply two Feistel rounds
+ * with the 32-bit chunks re-ordered to simulate the "swap" */
+
+#define ENCCYCLE(n) \
+ ENCROUND (2 * (n), a, b, c, d); \
+ ENCROUND (2 * (n) + 1, c, d, a, b)
+
+#define DECCYCLE(n) \
+ DECROUND (2 * (n) + 1, c, d, a, b); \
+ DECROUND (2 * (n), a, b, c, d)
+
+/* Macros to convert the input and output bytes into 32-bit words,
+ * and simultaneously perform the whitening step. INPACK packs word
+ * number n into the variable named by x, using whitening subkey number m.
+ * OUTUNPACK unpacks word number n from the variable named by x, using
+ * whitening subkey number m. */
+
+#define INPACK(n, x, m) \
+ x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
+ ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+
+#define OUTUNPACK(n, x, m) \
+ x ^= ctx->w[m]; \
+ out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
+ out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+\f
+/* Encrypt one block. in and out may be the same. */
+
+static void
+do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, a, 0);
+ INPACK (1, b, 1);
+ INPACK (2, c, 2);
+ INPACK (3, d, 3);
+
+ /* Encryption Feistel cycles. */
+ ENCCYCLE (0);
+ ENCCYCLE (1);
+ ENCCYCLE (2);
+ ENCCYCLE (3);
+ ENCCYCLE (4);
+ ENCCYCLE (5);
+ ENCCYCLE (6);
+ ENCCYCLE (7);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, c, 4);
+ OUTUNPACK (1, d, 5);
+ OUTUNPACK (2, a, 6);
+ OUTUNPACK (3, b, 7);
+}
+
+static void
+twofish_encrypt (void *context, byte *out, const byte *in)
+{
+ TWOFISH_context *ctx = context;
+ do_twofish_encrypt (ctx, out, in);
+ _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+\f
+/* Decrypt one block. in and out may be the same. */
+
+static void
+do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
+{
+ /* The four 32-bit chunks of the text. */
+ u32 a, b, c, d;
+
+ /* Temporaries used by the round function. */
+ u32 x, y;
+
+ /* Input whitening and packing. */
+ INPACK (0, c, 4);
+ INPACK (1, d, 5);
+ INPACK (2, a, 6);
+ INPACK (3, b, 7);
+
+ /* Encryption Feistel cycles. */
+ DECCYCLE (7);
+ DECCYCLE (6);
+ DECCYCLE (5);
+ DECCYCLE (4);
+ DECCYCLE (3);
+ DECCYCLE (2);
+ DECCYCLE (1);
+ DECCYCLE (0);
+
+ /* Output whitening and unpacking. */
+ OUTUNPACK (0, a, 0);
+ OUTUNPACK (1, b, 1);
+ OUTUNPACK (2, c, 2);
+ OUTUNPACK (3, d, 3);
+}
+
+static void
+twofish_decrypt (void *context, byte *out, const byte *in)
+{
+ TWOFISH_context *ctx = context;
+
+ do_twofish_decrypt (ctx, out, in);
+ _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+\f
+/* Test a single encryption and decryption with each key size. */
+
+static const char*
+selftest (void)
+{
+ TWOFISH_context ctx; /* Expanded key. */
+ byte scratch[16]; /* Encryption/decryption result buffer. */
+
+ /* Test vectors for single encryption/decryption. Note that I am using
+ * the vectors from the Twofish paper's "known answer test", I=3 for
+ * 128-bit and I=4 for 256-bit, instead of the all-0 vectors from the
+ * "intermediate value test", because an all-0 key would trigger all the
+ * special cases in the RS matrix multiply, leaving the math untested. */
+ static byte plaintext[16] = {
+ 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
+ 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19
+ };
+ static byte key[16] = {
+ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
+ 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A
+ };
+ static const byte ciphertext[16] = {
+ 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
+ 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3
+ };
+ static byte plaintext_256[16] = {
+ 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
+ 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6
+ };
+ static byte key_256[32] = {
+ 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
+ 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
+ 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
+ 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F
+ };
+ static const byte ciphertext_256[16] = {
+ 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
+ 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA
+ };
+
+ twofish_setkey (&ctx, key, sizeof(key));
+ twofish_encrypt (&ctx, scratch, plaintext);
+ if (memcmp (scratch, ciphertext, sizeof (ciphertext)))
+ return "Twofish-128 test encryption failed.";
+ twofish_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext, sizeof (plaintext)))
+ return "Twofish-128 test decryption failed.";
+
+ twofish_setkey (&ctx, key_256, sizeof(key_256));
+ twofish_encrypt (&ctx, scratch, plaintext_256);
+ if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256)))
+ return "Twofish-256 test encryption failed.";
+ twofish_decrypt (&ctx, scratch, scratch);
+ if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
+ return "Twofish-256 test decryption failed.";
+
+ return NULL;
+}
+\f
+/* More complete test program. This does 1000 encryptions and decryptions
+ * with each of 250 128-bit keys and 2000 encryptions and decryptions with
+ * each of 125 256-bit keys, using a feedback scheme similar to a Feistel
+ * cipher, so as to be sure of testing all the table entries pretty
+ * thoroughly. We keep changing the keys so as to get a more meaningful
+ * performance number, since the key setup is non-trivial for Twofish. */
+
+#ifdef TEST
+
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+int
+main()
+{
+ TWOFISH_context ctx; /* Expanded key. */
+ int i, j; /* Loop counters. */
+
+ const char *encrypt_msg; /* Message to print regarding encryption test;
+ * the printf is done outside the loop to avoid
+ * stuffing up the timing. */
+ clock_t timer; /* For computing elapsed time. */
+
+ /* Test buffer. */
+ byte buffer[4][16] = {
+ {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
+ {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
+ 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+ {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+ 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
+ };
+
+ /* Expected outputs for the million-operation test */
+ static const byte test_encrypt[4][16] = {
+ {0xC8, 0x23, 0xB8, 0xB7, 0x6B, 0xFE, 0x91, 0x13,
+ 0x2F, 0xA7, 0x5E, 0xE6, 0x94, 0x77, 0x6F, 0x6B},
+ {0x90, 0x36, 0xD8, 0x29, 0xD5, 0x96, 0xC2, 0x8E,
+ 0xE4, 0xFF, 0x76, 0xBC, 0xE5, 0x77, 0x88, 0x27},
+ {0xB8, 0x78, 0x69, 0xAF, 0x42, 0x8B, 0x48, 0x64,
+ 0xF7, 0xE9, 0xF3, 0x9C, 0x42, 0x18, 0x7B, 0x73},
+ {0x7A, 0x88, 0xFB, 0xEB, 0x90, 0xA4, 0xB4, 0xA8,
+ 0x43, 0xA3, 0x1D, 0xF1, 0x26, 0xC4, 0x53, 0x57}
+ };
+ static const byte test_decrypt[4][16] = {
+ {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
+ {0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78,
+ 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2 ,0xE1, 0xF0},
+ {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
+ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54 ,0x32, 0x10},
+ {0x01, 0x23, 0x45, 0x67, 0x76, 0x54 ,0x32, 0x10,
+ 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98}
+ };
+
+ /* Start the timer ticking. */
+ timer = clock ();
+
+ /* Encryption test. */
+ for (i = 0; i < 125; i++)
+ {
+ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
+ for (j = 0; j < 1000; j++)
+ twofish_encrypt (&ctx, buffer[2], buffer[2]);
+ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
+ for (j = 0; j < 1000; j++)
+ twofish_encrypt (&ctx, buffer[3], buffer[3]);
+ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+ for (j = 0; j < 1000; j++) {
+ twofish_encrypt (&ctx, buffer[0], buffer[0]);
+ twofish_encrypt (&ctx, buffer[1], buffer[1]);
+ }
+ }
+ encrypt_msg = memcmp (buffer, test_encrypt, sizeof (test_encrypt)) ?
+ "encryption failure!\n" : "encryption OK!\n";
+
+ /* Decryption test. */
+ for (i = 0; i < 125; i++)
+ {
+ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
+ for (j = 0; j < 1000; j++) {
+ twofish_decrypt (&ctx, buffer[0], buffer[0]);
+ twofish_decrypt (&ctx, buffer[1], buffer[1]);
+ }
+ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]));
+ for (j = 0; j < 1000; j++)
+ twofish_decrypt (&ctx, buffer[3], buffer[3]);
+ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
+ for (j = 0; j < 1000; j++)
+ twofish_decrypt (&ctx, buffer[2], buffer[2]);
+ }
+
+ /* Stop the timer, and print results. */
+ timer = clock () - timer;
+ printf (encrypt_msg);
+ printf (memcmp (buffer, test_decrypt, sizeof (test_decrypt)) ?
+ "decryption failure!\n" : "decryption OK!\n");
+ printf ("elapsed time: %.1f s.\n", (float) timer / CLOCKS_PER_SEC);
+
+ return 0;
+}
+
+#endif /* TEST */
+
+\f
+
+gcry_cipher_spec_t _gcry_cipher_spec_twofish =
+ {
+ "TWOFISH", NULL, NULL, 16, 256, sizeof (TWOFISH_context),
+ twofish_setkey, twofish_encrypt, twofish_decrypt
+ };
+
+gcry_cipher_spec_t _gcry_cipher_spec_twofish128 =
+ {
+ "TWOFISH128", NULL, NULL, 16, 128, sizeof (TWOFISH_context),
+ twofish_setkey, twofish_encrypt, twofish_decrypt
+ };
--- /dev/null
+/* whirlpool.c - Whirlpool hashing algorithm
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+/* This is an implementation of the Whirlpool hashing algorithm, which
+ has been developed by Vincent Rijmen and Paulo S. L. M. Barreto;
+ it's homepage is located at:
+ http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html.
+
+ The S-Boxes and the structure of the main transformation function,
+ which implements an optimized version of the algorithm, is taken
+ from the reference implementation available from
+ http://planeta.terra.com.br/informatica/paulobarreto/whirlpool.zip. */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+#include "bithelp.h"
+
+/* Size of a whirlpool block (in bytes). */
+#define BLOCK_SIZE 64
+
+/* Number of rounds. */
+#define R 10
+
+\f
+
+/* Types. */
+typedef u64 whirlpool_block_t[BLOCK_SIZE / 8];
+
+typedef struct {
+ whirlpool_block_t hash_state;
+ unsigned char buffer[BLOCK_SIZE];
+ size_t count;
+ unsigned char length[32];
+} whirlpool_context_t;
+
+\f
+
+/* Macros. */
+
+/* Convert the the buffer BUFFER into a block BLOCK, using I as
+ counter. */
+#define buffer_to_block(buffer, block, i) \
+ for (i = 0; i < 8; i++) \
+ (block)[i] = ((u64) (0 \
+ | (((u64) (buffer)[i * 8 + 0]) << 56) \
+ | (((u64) (buffer)[i * 8 + 1]) << 48) \
+ | (((u64) (buffer)[i * 8 + 2]) << 40) \
+ | (((u64) (buffer)[i * 8 + 3]) << 32) \
+ | (((u64) (buffer)[i * 8 + 4]) << 24) \
+ | (((u64) (buffer)[i * 8 + 5]) << 16) \
+ | (((u64) (buffer)[i * 8 + 6]) << 8) \
+ | (((u64) (buffer)[i * 8 + 7]) << 0)));
+
+/* Convert the block BLOCK into a buffer BUFFER, using I as
+ counter. */
+#define block_to_buffer(buffer, block, i) \
+ for (i = 0; i < 8; i++) \
+ { \
+ (buffer)[i * 8 + 0] = (block[i] >> 56) & 0xFF; \
+ (buffer)[i * 8 + 1] = (block[i] >> 48) & 0xFF; \
+ (buffer)[i * 8 + 2] = (block[i] >> 40) & 0xFF; \
+ (buffer)[i * 8 + 3] = (block[i] >> 32) & 0xFF; \
+ (buffer)[i * 8 + 4] = (block[i] >> 24) & 0xFF; \
+ (buffer)[i * 8 + 5] = (block[i] >> 16) & 0xFF; \
+ (buffer)[i * 8 + 6] = (block[i] >> 8) & 0xFF; \
+ (buffer)[i * 8 + 7] = (block[i] >> 0) & 0xFF; \
+ }
+
+/* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter. */
+#define block_copy(block_dst, block_src, i) \
+ for (i = 0; i < 8; i++) \
+ block_dst[i] = block_src[i];
+
+/* XOR the block BLOCK_SRC into BLOCK_DST, using I as counter. */
+#define block_xor(block_dst, block_src, i) \
+ for (i = 0; i < 8; i++) \
+ block_dst[i] ^= block_src[i];
+
+\f
+
+/* Round constants. */
+static const u64 rc[R] =
+ {
+ U64_C (0x1823c6e887b8014f),
+ U64_C (0x36a6d2f5796f9152),
+ U64_C (0x60bc9b8ea30c7b35),
+ U64_C (0x1de0d7c22e4bfe57),
+ U64_C (0x157737e59ff04ada),
+ U64_C (0x58c9290ab1a06b85),
+ U64_C (0xbd5d10f4cb3e0567),
+ U64_C (0xe427418ba77d95d8),
+ U64_C (0xfbee7c66dd17479e),
+ U64_C (0xca2dbf07ad5a8333),
+ };
+
+\f
+
+/* Main lookup boxes. */
+static const u64 C0[256] =
+ {
+ U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626),
+ U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb),
+ U64_C (0x878726874ca113cb), U64_C (0xb8b8dab8a9626d11),
+ U64_C (0x0101040108050209), U64_C (0x4f4f214f426e9e0d),
+ U64_C (0x3636d836adee6c9b), U64_C (0xa6a6a2a6590451ff),
+ U64_C (0xd2d26fd2debdb90c), U64_C (0xf5f5f3f5fb06f70e),
+ U64_C (0x7979f979ef80f296), U64_C (0x6f6fa16f5fcede30),
+ U64_C (0x91917e91fcef3f6d), U64_C (0x52525552aa07a4f8),
+ U64_C (0x60609d6027fdc047), U64_C (0xbcbccabc89766535),
+ U64_C (0x9b9b569baccd2b37), U64_C (0x8e8e028e048c018a),
+ U64_C (0xa3a3b6a371155bd2), U64_C (0x0c0c300c603c186c),
+ U64_C (0x7b7bf17bff8af684), U64_C (0x3535d435b5e16a80),
+ U64_C (0x1d1d741de8693af5), U64_C (0xe0e0a7e05347ddb3),
+ U64_C (0xd7d77bd7f6acb321), U64_C (0xc2c22fc25eed999c),
+ U64_C (0x2e2eb82e6d965c43), U64_C (0x4b4b314b627a9629),
+ U64_C (0xfefedffea321e15d), U64_C (0x575741578216aed5),
+ U64_C (0x15155415a8412abd), U64_C (0x7777c1779fb6eee8),
+ U64_C (0x3737dc37a5eb6e92), U64_C (0xe5e5b3e57b56d79e),
+ U64_C (0x9f9f469f8cd92313), U64_C (0xf0f0e7f0d317fd23),
+ U64_C (0x4a4a354a6a7f9420), U64_C (0xdada4fda9e95a944),
+ U64_C (0x58587d58fa25b0a2), U64_C (0xc9c903c906ca8fcf),
+ U64_C (0x2929a429558d527c), U64_C (0x0a0a280a5022145a),
+ U64_C (0xb1b1feb1e14f7f50), U64_C (0xa0a0baa0691a5dc9),
+ U64_C (0x6b6bb16b7fdad614), U64_C (0x85852e855cab17d9),
+ U64_C (0xbdbdcebd8173673c), U64_C (0x5d5d695dd234ba8f),
+ U64_C (0x1010401080502090), U64_C (0xf4f4f7f4f303f507),
+ U64_C (0xcbcb0bcb16c08bdd), U64_C (0x3e3ef83eedc67cd3),
+ U64_C (0x0505140528110a2d), U64_C (0x676781671fe6ce78),
+ U64_C (0xe4e4b7e47353d597), U64_C (0x27279c2725bb4e02),
+ U64_C (0x4141194132588273), U64_C (0x8b8b168b2c9d0ba7),
+ U64_C (0xa7a7a6a7510153f6), U64_C (0x7d7de97dcf94fab2),
+ U64_C (0x95956e95dcfb3749), U64_C (0xd8d847d88e9fad56),
+ U64_C (0xfbfbcbfb8b30eb70), U64_C (0xeeee9fee2371c1cd),
+ U64_C (0x7c7ced7cc791f8bb), U64_C (0x6666856617e3cc71),
+ U64_C (0xdddd53dda68ea77b), U64_C (0x17175c17b84b2eaf),
+ U64_C (0x4747014702468e45), U64_C (0x9e9e429e84dc211a),
+ U64_C (0xcaca0fca1ec589d4), U64_C (0x2d2db42d75995a58),
+ U64_C (0xbfbfc6bf9179632e), U64_C (0x07071c07381b0e3f),
+ U64_C (0xadad8ead012347ac), U64_C (0x5a5a755aea2fb4b0),
+ U64_C (0x838336836cb51bef), U64_C (0x3333cc3385ff66b6),
+ U64_C (0x636391633ff2c65c), U64_C (0x02020802100a0412),
+ U64_C (0xaaaa92aa39384993), U64_C (0x7171d971afa8e2de),
+ U64_C (0xc8c807c80ecf8dc6), U64_C (0x19196419c87d32d1),
+ U64_C (0x494939497270923b), U64_C (0xd9d943d9869aaf5f),
+ U64_C (0xf2f2eff2c31df931), U64_C (0xe3e3abe34b48dba8),
+ U64_C (0x5b5b715be22ab6b9), U64_C (0x88881a8834920dbc),
+ U64_C (0x9a9a529aa4c8293e), U64_C (0x262698262dbe4c0b),
+ U64_C (0x3232c8328dfa64bf), U64_C (0xb0b0fab0e94a7d59),
+ U64_C (0xe9e983e91b6acff2), U64_C (0x0f0f3c0f78331e77),
+ U64_C (0xd5d573d5e6a6b733), U64_C (0x80803a8074ba1df4),
+ U64_C (0xbebec2be997c6127), U64_C (0xcdcd13cd26de87eb),
+ U64_C (0x3434d034bde46889), U64_C (0x48483d487a759032),
+ U64_C (0xffffdbffab24e354), U64_C (0x7a7af57af78ff48d),
+ U64_C (0x90907a90f4ea3d64), U64_C (0x5f5f615fc23ebe9d),
+ U64_C (0x202080201da0403d), U64_C (0x6868bd6867d5d00f),
+ U64_C (0x1a1a681ad07234ca), U64_C (0xaeae82ae192c41b7),
+ U64_C (0xb4b4eab4c95e757d), U64_C (0x54544d549a19a8ce),
+ U64_C (0x93937693ece53b7f), U64_C (0x222288220daa442f),
+ U64_C (0x64648d6407e9c863), U64_C (0xf1f1e3f1db12ff2a),
+ U64_C (0x7373d173bfa2e6cc), U64_C (0x12124812905a2482),
+ U64_C (0x40401d403a5d807a), U64_C (0x0808200840281048),
+ U64_C (0xc3c32bc356e89b95), U64_C (0xecec97ec337bc5df),
+ U64_C (0xdbdb4bdb9690ab4d), U64_C (0xa1a1bea1611f5fc0),
+ U64_C (0x8d8d0e8d1c830791), U64_C (0x3d3df43df5c97ac8),
+ U64_C (0x97976697ccf1335b), U64_C (0x0000000000000000),
+ U64_C (0xcfcf1bcf36d483f9), U64_C (0x2b2bac2b4587566e),
+ U64_C (0x7676c57697b3ece1), U64_C (0x8282328264b019e6),
+ U64_C (0xd6d67fd6fea9b128), U64_C (0x1b1b6c1bd87736c3),
+ U64_C (0xb5b5eeb5c15b7774), U64_C (0xafaf86af112943be),
+ U64_C (0x6a6ab56a77dfd41d), U64_C (0x50505d50ba0da0ea),
+ U64_C (0x45450945124c8a57), U64_C (0xf3f3ebf3cb18fb38),
+ U64_C (0x3030c0309df060ad), U64_C (0xefef9bef2b74c3c4),
+ U64_C (0x3f3ffc3fe5c37eda), U64_C (0x55554955921caac7),
+ U64_C (0xa2a2b2a2791059db), U64_C (0xeaea8fea0365c9e9),
+ U64_C (0x656589650fecca6a), U64_C (0xbabad2bab9686903),
+ U64_C (0x2f2fbc2f65935e4a), U64_C (0xc0c027c04ee79d8e),
+ U64_C (0xdede5fdebe81a160), U64_C (0x1c1c701ce06c38fc),
+ U64_C (0xfdfdd3fdbb2ee746), U64_C (0x4d4d294d52649a1f),
+ U64_C (0x92927292e4e03976), U64_C (0x7575c9758fbceafa),
+ U64_C (0x06061806301e0c36), U64_C (0x8a8a128a249809ae),
+ U64_C (0xb2b2f2b2f940794b), U64_C (0xe6e6bfe66359d185),
+ U64_C (0x0e0e380e70361c7e), U64_C (0x1f1f7c1ff8633ee7),
+ U64_C (0x6262956237f7c455), U64_C (0xd4d477d4eea3b53a),
+ U64_C (0xa8a89aa829324d81), U64_C (0x96966296c4f43152),
+ U64_C (0xf9f9c3f99b3aef62), U64_C (0xc5c533c566f697a3),
+ U64_C (0x2525942535b14a10), U64_C (0x59597959f220b2ab),
+ U64_C (0x84842a8454ae15d0), U64_C (0x7272d572b7a7e4c5),
+ U64_C (0x3939e439d5dd72ec), U64_C (0x4c4c2d4c5a619816),
+ U64_C (0x5e5e655eca3bbc94), U64_C (0x7878fd78e785f09f),
+ U64_C (0x3838e038ddd870e5), U64_C (0x8c8c0a8c14860598),
+ U64_C (0xd1d163d1c6b2bf17), U64_C (0xa5a5aea5410b57e4),
+ U64_C (0xe2e2afe2434dd9a1), U64_C (0x616199612ff8c24e),
+ U64_C (0xb3b3f6b3f1457b42), U64_C (0x2121842115a54234),
+ U64_C (0x9c9c4a9c94d62508), U64_C (0x1e1e781ef0663cee),
+ U64_C (0x4343114322528661), U64_C (0xc7c73bc776fc93b1),
+ U64_C (0xfcfcd7fcb32be54f), U64_C (0x0404100420140824),
+ U64_C (0x51515951b208a2e3), U64_C (0x99995e99bcc72f25),
+ U64_C (0x6d6da96d4fc4da22), U64_C (0x0d0d340d68391a65),
+ U64_C (0xfafacffa8335e979), U64_C (0xdfdf5bdfb684a369),
+ U64_C (0x7e7ee57ed79bfca9), U64_C (0x242490243db44819),
+ U64_C (0x3b3bec3bc5d776fe), U64_C (0xabab96ab313d4b9a),
+ U64_C (0xcece1fce3ed181f0), U64_C (0x1111441188552299),
+ U64_C (0x8f8f068f0c890383), U64_C (0x4e4e254e4a6b9c04),
+ U64_C (0xb7b7e6b7d1517366), U64_C (0xebeb8beb0b60cbe0),
+ U64_C (0x3c3cf03cfdcc78c1), U64_C (0x81813e817cbf1ffd),
+ U64_C (0x94946a94d4fe3540), U64_C (0xf7f7fbf7eb0cf31c),
+ U64_C (0xb9b9deb9a1676f18), U64_C (0x13134c13985f268b),
+ U64_C (0x2c2cb02c7d9c5851), U64_C (0xd3d36bd3d6b8bb05),
+ U64_C (0xe7e7bbe76b5cd38c), U64_C (0x6e6ea56e57cbdc39),
+ U64_C (0xc4c437c46ef395aa), U64_C (0x03030c03180f061b),
+ U64_C (0x565645568a13acdc), U64_C (0x44440d441a49885e),
+ U64_C (0x7f7fe17fdf9efea0), U64_C (0xa9a99ea921374f88),
+ U64_C (0x2a2aa82a4d825467), U64_C (0xbbbbd6bbb16d6b0a),
+ U64_C (0xc1c123c146e29f87), U64_C (0x53535153a202a6f1),
+ U64_C (0xdcdc57dcae8ba572), U64_C (0x0b0b2c0b58271653),
+ U64_C (0x9d9d4e9d9cd32701), U64_C (0x6c6cad6c47c1d82b),
+ U64_C (0x3131c43195f562a4), U64_C (0x7474cd7487b9e8f3),
+ U64_C (0xf6f6fff6e309f115), U64_C (0x464605460a438c4c),
+ U64_C (0xacac8aac092645a5), U64_C (0x89891e893c970fb5),
+ U64_C (0x14145014a04428b4), U64_C (0xe1e1a3e15b42dfba),
+ U64_C (0x16165816b04e2ca6), U64_C (0x3a3ae83acdd274f7),
+ U64_C (0x6969b9696fd0d206), U64_C (0x09092409482d1241),
+ U64_C (0x7070dd70a7ade0d7), U64_C (0xb6b6e2b6d954716f),
+ U64_C (0xd0d067d0ceb7bd1e), U64_C (0xeded93ed3b7ec7d6),
+ U64_C (0xcccc17cc2edb85e2), U64_C (0x424215422a578468),
+ U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed),
+ U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886),
+ U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2),
+ };
+
+static const u64 C1[256] =
+ {
+ U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46),
+ U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd),
+ U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d),
+ U64_C (0x0901010401080502), U64_C (0x0d4f4f214f426e9e),
+ U64_C (0x9b3636d836adee6c), U64_C (0xffa6a6a2a6590451),
+ U64_C (0x0cd2d26fd2debdb9), U64_C (0x0ef5f5f3f5fb06f7),
+ U64_C (0x967979f979ef80f2), U64_C (0x306f6fa16f5fcede),
+ U64_C (0x6d91917e91fcef3f), U64_C (0xf852525552aa07a4),
+ U64_C (0x4760609d6027fdc0), U64_C (0x35bcbccabc897665),
+ U64_C (0x379b9b569baccd2b), U64_C (0x8a8e8e028e048c01),
+ U64_C (0xd2a3a3b6a371155b), U64_C (0x6c0c0c300c603c18),
+ U64_C (0x847b7bf17bff8af6), U64_C (0x803535d435b5e16a),
+ U64_C (0xf51d1d741de8693a), U64_C (0xb3e0e0a7e05347dd),
+ U64_C (0x21d7d77bd7f6acb3), U64_C (0x9cc2c22fc25eed99),
+ U64_C (0x432e2eb82e6d965c), U64_C (0x294b4b314b627a96),
+ U64_C (0x5dfefedffea321e1), U64_C (0xd5575741578216ae),
+ U64_C (0xbd15155415a8412a), U64_C (0xe87777c1779fb6ee),
+ U64_C (0x923737dc37a5eb6e), U64_C (0x9ee5e5b3e57b56d7),
+ U64_C (0x139f9f469f8cd923), U64_C (0x23f0f0e7f0d317fd),
+ U64_C (0x204a4a354a6a7f94), U64_C (0x44dada4fda9e95a9),
+ U64_C (0xa258587d58fa25b0), U64_C (0xcfc9c903c906ca8f),
+ U64_C (0x7c2929a429558d52), U64_C (0x5a0a0a280a502214),
+ U64_C (0x50b1b1feb1e14f7f), U64_C (0xc9a0a0baa0691a5d),
+ U64_C (0x146b6bb16b7fdad6), U64_C (0xd985852e855cab17),
+ U64_C (0x3cbdbdcebd817367), U64_C (0x8f5d5d695dd234ba),
+ U64_C (0x9010104010805020), U64_C (0x07f4f4f7f4f303f5),
+ U64_C (0xddcbcb0bcb16c08b), U64_C (0xd33e3ef83eedc67c),
+ U64_C (0x2d0505140528110a), U64_C (0x78676781671fe6ce),
+ U64_C (0x97e4e4b7e47353d5), U64_C (0x0227279c2725bb4e),
+ U64_C (0x7341411941325882), U64_C (0xa78b8b168b2c9d0b),
+ U64_C (0xf6a7a7a6a7510153), U64_C (0xb27d7de97dcf94fa),
+ U64_C (0x4995956e95dcfb37), U64_C (0x56d8d847d88e9fad),
+ U64_C (0x70fbfbcbfb8b30eb), U64_C (0xcdeeee9fee2371c1),
+ U64_C (0xbb7c7ced7cc791f8), U64_C (0x716666856617e3cc),
+ U64_C (0x7bdddd53dda68ea7), U64_C (0xaf17175c17b84b2e),
+ U64_C (0x454747014702468e), U64_C (0x1a9e9e429e84dc21),
+ U64_C (0xd4caca0fca1ec589), U64_C (0x582d2db42d75995a),
+ U64_C (0x2ebfbfc6bf917963), U64_C (0x3f07071c07381b0e),
+ U64_C (0xacadad8ead012347), U64_C (0xb05a5a755aea2fb4),
+ U64_C (0xef838336836cb51b), U64_C (0xb63333cc3385ff66),
+ U64_C (0x5c636391633ff2c6), U64_C (0x1202020802100a04),
+ U64_C (0x93aaaa92aa393849), U64_C (0xde7171d971afa8e2),
+ U64_C (0xc6c8c807c80ecf8d), U64_C (0xd119196419c87d32),
+ U64_C (0x3b49493949727092), U64_C (0x5fd9d943d9869aaf),
+ U64_C (0x31f2f2eff2c31df9), U64_C (0xa8e3e3abe34b48db),
+ U64_C (0xb95b5b715be22ab6), U64_C (0xbc88881a8834920d),
+ U64_C (0x3e9a9a529aa4c829), U64_C (0x0b262698262dbe4c),
+ U64_C (0xbf3232c8328dfa64), U64_C (0x59b0b0fab0e94a7d),
+ U64_C (0xf2e9e983e91b6acf), U64_C (0x770f0f3c0f78331e),
+ U64_C (0x33d5d573d5e6a6b7), U64_C (0xf480803a8074ba1d),
+ U64_C (0x27bebec2be997c61), U64_C (0xebcdcd13cd26de87),
+ U64_C (0x893434d034bde468), U64_C (0x3248483d487a7590),
+ U64_C (0x54ffffdbffab24e3), U64_C (0x8d7a7af57af78ff4),
+ U64_C (0x6490907a90f4ea3d), U64_C (0x9d5f5f615fc23ebe),
+ U64_C (0x3d202080201da040), U64_C (0x0f6868bd6867d5d0),
+ U64_C (0xca1a1a681ad07234), U64_C (0xb7aeae82ae192c41),
+ U64_C (0x7db4b4eab4c95e75), U64_C (0xce54544d549a19a8),
+ U64_C (0x7f93937693ece53b), U64_C (0x2f222288220daa44),
+ U64_C (0x6364648d6407e9c8), U64_C (0x2af1f1e3f1db12ff),
+ U64_C (0xcc7373d173bfa2e6), U64_C (0x8212124812905a24),
+ U64_C (0x7a40401d403a5d80), U64_C (0x4808082008402810),
+ U64_C (0x95c3c32bc356e89b), U64_C (0xdfecec97ec337bc5),
+ U64_C (0x4ddbdb4bdb9690ab), U64_C (0xc0a1a1bea1611f5f),
+ U64_C (0x918d8d0e8d1c8307), U64_C (0xc83d3df43df5c97a),
+ U64_C (0x5b97976697ccf133), U64_C (0x0000000000000000),
+ U64_C (0xf9cfcf1bcf36d483), U64_C (0x6e2b2bac2b458756),
+ U64_C (0xe17676c57697b3ec), U64_C (0xe68282328264b019),
+ U64_C (0x28d6d67fd6fea9b1), U64_C (0xc31b1b6c1bd87736),
+ U64_C (0x74b5b5eeb5c15b77), U64_C (0xbeafaf86af112943),
+ U64_C (0x1d6a6ab56a77dfd4), U64_C (0xea50505d50ba0da0),
+ U64_C (0x5745450945124c8a), U64_C (0x38f3f3ebf3cb18fb),
+ U64_C (0xad3030c0309df060), U64_C (0xc4efef9bef2b74c3),
+ U64_C (0xda3f3ffc3fe5c37e), U64_C (0xc755554955921caa),
+ U64_C (0xdba2a2b2a2791059), U64_C (0xe9eaea8fea0365c9),
+ U64_C (0x6a656589650fecca), U64_C (0x03babad2bab96869),
+ U64_C (0x4a2f2fbc2f65935e), U64_C (0x8ec0c027c04ee79d),
+ U64_C (0x60dede5fdebe81a1), U64_C (0xfc1c1c701ce06c38),
+ U64_C (0x46fdfdd3fdbb2ee7), U64_C (0x1f4d4d294d52649a),
+ U64_C (0x7692927292e4e039), U64_C (0xfa7575c9758fbcea),
+ U64_C (0x3606061806301e0c), U64_C (0xae8a8a128a249809),
+ U64_C (0x4bb2b2f2b2f94079), U64_C (0x85e6e6bfe66359d1),
+ U64_C (0x7e0e0e380e70361c), U64_C (0xe71f1f7c1ff8633e),
+ U64_C (0x556262956237f7c4), U64_C (0x3ad4d477d4eea3b5),
+ U64_C (0x81a8a89aa829324d), U64_C (0x5296966296c4f431),
+ U64_C (0x62f9f9c3f99b3aef), U64_C (0xa3c5c533c566f697),
+ U64_C (0x102525942535b14a), U64_C (0xab59597959f220b2),
+ U64_C (0xd084842a8454ae15), U64_C (0xc57272d572b7a7e4),
+ U64_C (0xec3939e439d5dd72), U64_C (0x164c4c2d4c5a6198),
+ U64_C (0x945e5e655eca3bbc), U64_C (0x9f7878fd78e785f0),
+ U64_C (0xe53838e038ddd870), U64_C (0x988c8c0a8c148605),
+ U64_C (0x17d1d163d1c6b2bf), U64_C (0xe4a5a5aea5410b57),
+ U64_C (0xa1e2e2afe2434dd9), U64_C (0x4e616199612ff8c2),
+ U64_C (0x42b3b3f6b3f1457b), U64_C (0x342121842115a542),
+ U64_C (0x089c9c4a9c94d625), U64_C (0xee1e1e781ef0663c),
+ U64_C (0x6143431143225286), U64_C (0xb1c7c73bc776fc93),
+ U64_C (0x4ffcfcd7fcb32be5), U64_C (0x2404041004201408),
+ U64_C (0xe351515951b208a2), U64_C (0x2599995e99bcc72f),
+ U64_C (0x226d6da96d4fc4da), U64_C (0x650d0d340d68391a),
+ U64_C (0x79fafacffa8335e9), U64_C (0x69dfdf5bdfb684a3),
+ U64_C (0xa97e7ee57ed79bfc), U64_C (0x19242490243db448),
+ U64_C (0xfe3b3bec3bc5d776), U64_C (0x9aabab96ab313d4b),
+ U64_C (0xf0cece1fce3ed181), U64_C (0x9911114411885522),
+ U64_C (0x838f8f068f0c8903), U64_C (0x044e4e254e4a6b9c),
+ U64_C (0x66b7b7e6b7d15173), U64_C (0xe0ebeb8beb0b60cb),
+ U64_C (0xc13c3cf03cfdcc78), U64_C (0xfd81813e817cbf1f),
+ U64_C (0x4094946a94d4fe35), U64_C (0x1cf7f7fbf7eb0cf3),
+ U64_C (0x18b9b9deb9a1676f), U64_C (0x8b13134c13985f26),
+ U64_C (0x512c2cb02c7d9c58), U64_C (0x05d3d36bd3d6b8bb),
+ U64_C (0x8ce7e7bbe76b5cd3), U64_C (0x396e6ea56e57cbdc),
+ U64_C (0xaac4c437c46ef395), U64_C (0x1b03030c03180f06),
+ U64_C (0xdc565645568a13ac), U64_C (0x5e44440d441a4988),
+ U64_C (0xa07f7fe17fdf9efe), U64_C (0x88a9a99ea921374f),
+ U64_C (0x672a2aa82a4d8254), U64_C (0x0abbbbd6bbb16d6b),
+ U64_C (0x87c1c123c146e29f), U64_C (0xf153535153a202a6),
+ U64_C (0x72dcdc57dcae8ba5), U64_C (0x530b0b2c0b582716),
+ U64_C (0x019d9d4e9d9cd327), U64_C (0x2b6c6cad6c47c1d8),
+ U64_C (0xa43131c43195f562), U64_C (0xf37474cd7487b9e8),
+ U64_C (0x15f6f6fff6e309f1), U64_C (0x4c464605460a438c),
+ U64_C (0xa5acac8aac092645), U64_C (0xb589891e893c970f),
+ U64_C (0xb414145014a04428), U64_C (0xbae1e1a3e15b42df),
+ U64_C (0xa616165816b04e2c), U64_C (0xf73a3ae83acdd274),
+ U64_C (0x066969b9696fd0d2), U64_C (0x4109092409482d12),
+ U64_C (0xd77070dd70a7ade0), U64_C (0x6fb6b6e2b6d95471),
+ U64_C (0x1ed0d067d0ceb7bd), U64_C (0xd6eded93ed3b7ec7),
+ U64_C (0xe2cccc17cc2edb85), U64_C (0x68424215422a5784),
+ U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55),
+ U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8),
+ U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411),
+ };
+
+static const u64 C2[256] =
+ {
+ U64_C (0x30d818186018c078), U64_C (0x462623238c2305af),
+ U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f),
+ U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962),
+ U64_C (0x0209010104010805), U64_C (0x9e0d4f4f214f426e),
+ U64_C (0x6c9b3636d836adee), U64_C (0x51ffa6a6a2a65904),
+ U64_C (0xb90cd2d26fd2debd), U64_C (0xf70ef5f5f3f5fb06),
+ U64_C (0xf2967979f979ef80), U64_C (0xde306f6fa16f5fce),
+ U64_C (0x3f6d91917e91fcef), U64_C (0xa4f852525552aa07),
+ U64_C (0xc04760609d6027fd), U64_C (0x6535bcbccabc8976),
+ U64_C (0x2b379b9b569baccd), U64_C (0x018a8e8e028e048c),
+ U64_C (0x5bd2a3a3b6a37115), U64_C (0x186c0c0c300c603c),
+ U64_C (0xf6847b7bf17bff8a), U64_C (0x6a803535d435b5e1),
+ U64_C (0x3af51d1d741de869), U64_C (0xddb3e0e0a7e05347),
+ U64_C (0xb321d7d77bd7f6ac), U64_C (0x999cc2c22fc25eed),
+ U64_C (0x5c432e2eb82e6d96), U64_C (0x96294b4b314b627a),
+ U64_C (0xe15dfefedffea321), U64_C (0xaed5575741578216),
+ U64_C (0x2abd15155415a841), U64_C (0xeee87777c1779fb6),
+ U64_C (0x6e923737dc37a5eb), U64_C (0xd79ee5e5b3e57b56),
+ U64_C (0x23139f9f469f8cd9), U64_C (0xfd23f0f0e7f0d317),
+ U64_C (0x94204a4a354a6a7f), U64_C (0xa944dada4fda9e95),
+ U64_C (0xb0a258587d58fa25), U64_C (0x8fcfc9c903c906ca),
+ U64_C (0x527c2929a429558d), U64_C (0x145a0a0a280a5022),
+ U64_C (0x7f50b1b1feb1e14f), U64_C (0x5dc9a0a0baa0691a),
+ U64_C (0xd6146b6bb16b7fda), U64_C (0x17d985852e855cab),
+ U64_C (0x673cbdbdcebd8173), U64_C (0xba8f5d5d695dd234),
+ U64_C (0x2090101040108050), U64_C (0xf507f4f4f7f4f303),
+ U64_C (0x8bddcbcb0bcb16c0), U64_C (0x7cd33e3ef83eedc6),
+ U64_C (0x0a2d050514052811), U64_C (0xce78676781671fe6),
+ U64_C (0xd597e4e4b7e47353), U64_C (0x4e0227279c2725bb),
+ U64_C (0x8273414119413258), U64_C (0x0ba78b8b168b2c9d),
+ U64_C (0x53f6a7a7a6a75101), U64_C (0xfab27d7de97dcf94),
+ U64_C (0x374995956e95dcfb), U64_C (0xad56d8d847d88e9f),
+ U64_C (0xeb70fbfbcbfb8b30), U64_C (0xc1cdeeee9fee2371),
+ U64_C (0xf8bb7c7ced7cc791), U64_C (0xcc716666856617e3),
+ U64_C (0xa77bdddd53dda68e), U64_C (0x2eaf17175c17b84b),
+ U64_C (0x8e45474701470246), U64_C (0x211a9e9e429e84dc),
+ U64_C (0x89d4caca0fca1ec5), U64_C (0x5a582d2db42d7599),
+ U64_C (0x632ebfbfc6bf9179), U64_C (0x0e3f07071c07381b),
+ U64_C (0x47acadad8ead0123), U64_C (0xb4b05a5a755aea2f),
+ U64_C (0x1bef838336836cb5), U64_C (0x66b63333cc3385ff),
+ U64_C (0xc65c636391633ff2), U64_C (0x041202020802100a),
+ U64_C (0x4993aaaa92aa3938), U64_C (0xe2de7171d971afa8),
+ U64_C (0x8dc6c8c807c80ecf), U64_C (0x32d119196419c87d),
+ U64_C (0x923b494939497270), U64_C (0xaf5fd9d943d9869a),
+ U64_C (0xf931f2f2eff2c31d), U64_C (0xdba8e3e3abe34b48),
+ U64_C (0xb6b95b5b715be22a), U64_C (0x0dbc88881a883492),
+ U64_C (0x293e9a9a529aa4c8), U64_C (0x4c0b262698262dbe),
+ U64_C (0x64bf3232c8328dfa), U64_C (0x7d59b0b0fab0e94a),
+ U64_C (0xcff2e9e983e91b6a), U64_C (0x1e770f0f3c0f7833),
+ U64_C (0xb733d5d573d5e6a6), U64_C (0x1df480803a8074ba),
+ U64_C (0x6127bebec2be997c), U64_C (0x87ebcdcd13cd26de),
+ U64_C (0x68893434d034bde4), U64_C (0x903248483d487a75),
+ U64_C (0xe354ffffdbffab24), U64_C (0xf48d7a7af57af78f),
+ U64_C (0x3d6490907a90f4ea), U64_C (0xbe9d5f5f615fc23e),
+ U64_C (0x403d202080201da0), U64_C (0xd00f6868bd6867d5),
+ U64_C (0x34ca1a1a681ad072), U64_C (0x41b7aeae82ae192c),
+ U64_C (0x757db4b4eab4c95e), U64_C (0xa8ce54544d549a19),
+ U64_C (0x3b7f93937693ece5), U64_C (0x442f222288220daa),
+ U64_C (0xc86364648d6407e9), U64_C (0xff2af1f1e3f1db12),
+ U64_C (0xe6cc7373d173bfa2), U64_C (0x248212124812905a),
+ U64_C (0x807a40401d403a5d), U64_C (0x1048080820084028),
+ U64_C (0x9b95c3c32bc356e8), U64_C (0xc5dfecec97ec337b),
+ U64_C (0xab4ddbdb4bdb9690), U64_C (0x5fc0a1a1bea1611f),
+ U64_C (0x07918d8d0e8d1c83), U64_C (0x7ac83d3df43df5c9),
+ U64_C (0x335b97976697ccf1), U64_C (0x0000000000000000),
+ U64_C (0x83f9cfcf1bcf36d4), U64_C (0x566e2b2bac2b4587),
+ U64_C (0xece17676c57697b3), U64_C (0x19e68282328264b0),
+ U64_C (0xb128d6d67fd6fea9), U64_C (0x36c31b1b6c1bd877),
+ U64_C (0x7774b5b5eeb5c15b), U64_C (0x43beafaf86af1129),
+ U64_C (0xd41d6a6ab56a77df), U64_C (0xa0ea50505d50ba0d),
+ U64_C (0x8a5745450945124c), U64_C (0xfb38f3f3ebf3cb18),
+ U64_C (0x60ad3030c0309df0), U64_C (0xc3c4efef9bef2b74),
+ U64_C (0x7eda3f3ffc3fe5c3), U64_C (0xaac755554955921c),
+ U64_C (0x59dba2a2b2a27910), U64_C (0xc9e9eaea8fea0365),
+ U64_C (0xca6a656589650fec), U64_C (0x6903babad2bab968),
+ U64_C (0x5e4a2f2fbc2f6593), U64_C (0x9d8ec0c027c04ee7),
+ U64_C (0xa160dede5fdebe81), U64_C (0x38fc1c1c701ce06c),
+ U64_C (0xe746fdfdd3fdbb2e), U64_C (0x9a1f4d4d294d5264),
+ U64_C (0x397692927292e4e0), U64_C (0xeafa7575c9758fbc),
+ U64_C (0x0c3606061806301e), U64_C (0x09ae8a8a128a2498),
+ U64_C (0x794bb2b2f2b2f940), U64_C (0xd185e6e6bfe66359),
+ U64_C (0x1c7e0e0e380e7036), U64_C (0x3ee71f1f7c1ff863),
+ U64_C (0xc4556262956237f7), U64_C (0xb53ad4d477d4eea3),
+ U64_C (0x4d81a8a89aa82932), U64_C (0x315296966296c4f4),
+ U64_C (0xef62f9f9c3f99b3a), U64_C (0x97a3c5c533c566f6),
+ U64_C (0x4a102525942535b1), U64_C (0xb2ab59597959f220),
+ U64_C (0x15d084842a8454ae), U64_C (0xe4c57272d572b7a7),
+ U64_C (0x72ec3939e439d5dd), U64_C (0x98164c4c2d4c5a61),
+ U64_C (0xbc945e5e655eca3b), U64_C (0xf09f7878fd78e785),
+ U64_C (0x70e53838e038ddd8), U64_C (0x05988c8c0a8c1486),
+ U64_C (0xbf17d1d163d1c6b2), U64_C (0x57e4a5a5aea5410b),
+ U64_C (0xd9a1e2e2afe2434d), U64_C (0xc24e616199612ff8),
+ U64_C (0x7b42b3b3f6b3f145), U64_C (0x42342121842115a5),
+ U64_C (0x25089c9c4a9c94d6), U64_C (0x3cee1e1e781ef066),
+ U64_C (0x8661434311432252), U64_C (0x93b1c7c73bc776fc),
+ U64_C (0xe54ffcfcd7fcb32b), U64_C (0x0824040410042014),
+ U64_C (0xa2e351515951b208), U64_C (0x2f2599995e99bcc7),
+ U64_C (0xda226d6da96d4fc4), U64_C (0x1a650d0d340d6839),
+ U64_C (0xe979fafacffa8335), U64_C (0xa369dfdf5bdfb684),
+ U64_C (0xfca97e7ee57ed79b), U64_C (0x4819242490243db4),
+ U64_C (0x76fe3b3bec3bc5d7), U64_C (0x4b9aabab96ab313d),
+ U64_C (0x81f0cece1fce3ed1), U64_C (0x2299111144118855),
+ U64_C (0x03838f8f068f0c89), U64_C (0x9c044e4e254e4a6b),
+ U64_C (0x7366b7b7e6b7d151), U64_C (0xcbe0ebeb8beb0b60),
+ U64_C (0x78c13c3cf03cfdcc), U64_C (0x1ffd81813e817cbf),
+ U64_C (0x354094946a94d4fe), U64_C (0xf31cf7f7fbf7eb0c),
+ U64_C (0x6f18b9b9deb9a167), U64_C (0x268b13134c13985f),
+ U64_C (0x58512c2cb02c7d9c), U64_C (0xbb05d3d36bd3d6b8),
+ U64_C (0xd38ce7e7bbe76b5c), U64_C (0xdc396e6ea56e57cb),
+ U64_C (0x95aac4c437c46ef3), U64_C (0x061b03030c03180f),
+ U64_C (0xacdc565645568a13), U64_C (0x885e44440d441a49),
+ U64_C (0xfea07f7fe17fdf9e), U64_C (0x4f88a9a99ea92137),
+ U64_C (0x54672a2aa82a4d82), U64_C (0x6b0abbbbd6bbb16d),
+ U64_C (0x9f87c1c123c146e2), U64_C (0xa6f153535153a202),
+ U64_C (0xa572dcdc57dcae8b), U64_C (0x16530b0b2c0b5827),
+ U64_C (0x27019d9d4e9d9cd3), U64_C (0xd82b6c6cad6c47c1),
+ U64_C (0x62a43131c43195f5), U64_C (0xe8f37474cd7487b9),
+ U64_C (0xf115f6f6fff6e309), U64_C (0x8c4c464605460a43),
+ U64_C (0x45a5acac8aac0926), U64_C (0x0fb589891e893c97),
+ U64_C (0x28b414145014a044), U64_C (0xdfbae1e1a3e15b42),
+ U64_C (0x2ca616165816b04e), U64_C (0x74f73a3ae83acdd2),
+ U64_C (0xd2066969b9696fd0), U64_C (0x124109092409482d),
+ U64_C (0xe0d77070dd70a7ad), U64_C (0x716fb6b6e2b6d954),
+ U64_C (0xbd1ed0d067d0ceb7), U64_C (0xc7d6eded93ed3b7e),
+ U64_C (0x85e2cccc17cc2edb), U64_C (0x8468424215422a57),
+ U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e),
+ U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31),
+ U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4),
+ };
+
+static const u64 C3[256] =
+ {
+ U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305),
+ U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813),
+ U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9),
+ U64_C (0x0502090101040108), U64_C (0x6e9e0d4f4f214f42),
+ U64_C (0xee6c9b3636d836ad), U64_C (0x0451ffa6a6a2a659),
+ U64_C (0xbdb90cd2d26fd2de), U64_C (0x06f70ef5f5f3f5fb),
+ U64_C (0x80f2967979f979ef), U64_C (0xcede306f6fa16f5f),
+ U64_C (0xef3f6d91917e91fc), U64_C (0x07a4f852525552aa),
+ U64_C (0xfdc04760609d6027), U64_C (0x766535bcbccabc89),
+ U64_C (0xcd2b379b9b569bac), U64_C (0x8c018a8e8e028e04),
+ U64_C (0x155bd2a3a3b6a371), U64_C (0x3c186c0c0c300c60),
+ U64_C (0x8af6847b7bf17bff), U64_C (0xe16a803535d435b5),
+ U64_C (0x693af51d1d741de8), U64_C (0x47ddb3e0e0a7e053),
+ U64_C (0xacb321d7d77bd7f6), U64_C (0xed999cc2c22fc25e),
+ U64_C (0x965c432e2eb82e6d), U64_C (0x7a96294b4b314b62),
+ U64_C (0x21e15dfefedffea3), U64_C (0x16aed55757415782),
+ U64_C (0x412abd15155415a8), U64_C (0xb6eee87777c1779f),
+ U64_C (0xeb6e923737dc37a5), U64_C (0x56d79ee5e5b3e57b),
+ U64_C (0xd923139f9f469f8c), U64_C (0x17fd23f0f0e7f0d3),
+ U64_C (0x7f94204a4a354a6a), U64_C (0x95a944dada4fda9e),
+ U64_C (0x25b0a258587d58fa), U64_C (0xca8fcfc9c903c906),
+ U64_C (0x8d527c2929a42955), U64_C (0x22145a0a0a280a50),
+ U64_C (0x4f7f50b1b1feb1e1), U64_C (0x1a5dc9a0a0baa069),
+ U64_C (0xdad6146b6bb16b7f), U64_C (0xab17d985852e855c),
+ U64_C (0x73673cbdbdcebd81), U64_C (0x34ba8f5d5d695dd2),
+ U64_C (0x5020901010401080), U64_C (0x03f507f4f4f7f4f3),
+ U64_C (0xc08bddcbcb0bcb16), U64_C (0xc67cd33e3ef83eed),
+ U64_C (0x110a2d0505140528), U64_C (0xe6ce78676781671f),
+ U64_C (0x53d597e4e4b7e473), U64_C (0xbb4e0227279c2725),
+ U64_C (0x5882734141194132), U64_C (0x9d0ba78b8b168b2c),
+ U64_C (0x0153f6a7a7a6a751), U64_C (0x94fab27d7de97dcf),
+ U64_C (0xfb374995956e95dc), U64_C (0x9fad56d8d847d88e),
+ U64_C (0x30eb70fbfbcbfb8b), U64_C (0x71c1cdeeee9fee23),
+ U64_C (0x91f8bb7c7ced7cc7), U64_C (0xe3cc716666856617),
+ U64_C (0x8ea77bdddd53dda6), U64_C (0x4b2eaf17175c17b8),
+ U64_C (0x468e454747014702), U64_C (0xdc211a9e9e429e84),
+ U64_C (0xc589d4caca0fca1e), U64_C (0x995a582d2db42d75),
+ U64_C (0x79632ebfbfc6bf91), U64_C (0x1b0e3f07071c0738),
+ U64_C (0x2347acadad8ead01), U64_C (0x2fb4b05a5a755aea),
+ U64_C (0xb51bef838336836c), U64_C (0xff66b63333cc3385),
+ U64_C (0xf2c65c636391633f), U64_C (0x0a04120202080210),
+ U64_C (0x384993aaaa92aa39), U64_C (0xa8e2de7171d971af),
+ U64_C (0xcf8dc6c8c807c80e), U64_C (0x7d32d119196419c8),
+ U64_C (0x70923b4949394972), U64_C (0x9aaf5fd9d943d986),
+ U64_C (0x1df931f2f2eff2c3), U64_C (0x48dba8e3e3abe34b),
+ U64_C (0x2ab6b95b5b715be2), U64_C (0x920dbc88881a8834),
+ U64_C (0xc8293e9a9a529aa4), U64_C (0xbe4c0b262698262d),
+ U64_C (0xfa64bf3232c8328d), U64_C (0x4a7d59b0b0fab0e9),
+ U64_C (0x6acff2e9e983e91b), U64_C (0x331e770f0f3c0f78),
+ U64_C (0xa6b733d5d573d5e6), U64_C (0xba1df480803a8074),
+ U64_C (0x7c6127bebec2be99), U64_C (0xde87ebcdcd13cd26),
+ U64_C (0xe468893434d034bd), U64_C (0x75903248483d487a),
+ U64_C (0x24e354ffffdbffab), U64_C (0x8ff48d7a7af57af7),
+ U64_C (0xea3d6490907a90f4), U64_C (0x3ebe9d5f5f615fc2),
+ U64_C (0xa0403d202080201d), U64_C (0xd5d00f6868bd6867),
+ U64_C (0x7234ca1a1a681ad0), U64_C (0x2c41b7aeae82ae19),
+ U64_C (0x5e757db4b4eab4c9), U64_C (0x19a8ce54544d549a),
+ U64_C (0xe53b7f93937693ec), U64_C (0xaa442f222288220d),
+ U64_C (0xe9c86364648d6407), U64_C (0x12ff2af1f1e3f1db),
+ U64_C (0xa2e6cc7373d173bf), U64_C (0x5a24821212481290),
+ U64_C (0x5d807a40401d403a), U64_C (0x2810480808200840),
+ U64_C (0xe89b95c3c32bc356), U64_C (0x7bc5dfecec97ec33),
+ U64_C (0x90ab4ddbdb4bdb96), U64_C (0x1f5fc0a1a1bea161),
+ U64_C (0x8307918d8d0e8d1c), U64_C (0xc97ac83d3df43df5),
+ U64_C (0xf1335b97976697cc), U64_C (0x0000000000000000),
+ U64_C (0xd483f9cfcf1bcf36), U64_C (0x87566e2b2bac2b45),
+ U64_C (0xb3ece17676c57697), U64_C (0xb019e68282328264),
+ U64_C (0xa9b128d6d67fd6fe), U64_C (0x7736c31b1b6c1bd8),
+ U64_C (0x5b7774b5b5eeb5c1), U64_C (0x2943beafaf86af11),
+ U64_C (0xdfd41d6a6ab56a77), U64_C (0x0da0ea50505d50ba),
+ U64_C (0x4c8a574545094512), U64_C (0x18fb38f3f3ebf3cb),
+ U64_C (0xf060ad3030c0309d), U64_C (0x74c3c4efef9bef2b),
+ U64_C (0xc37eda3f3ffc3fe5), U64_C (0x1caac75555495592),
+ U64_C (0x1059dba2a2b2a279), U64_C (0x65c9e9eaea8fea03),
+ U64_C (0xecca6a656589650f), U64_C (0x686903babad2bab9),
+ U64_C (0x935e4a2f2fbc2f65), U64_C (0xe79d8ec0c027c04e),
+ U64_C (0x81a160dede5fdebe), U64_C (0x6c38fc1c1c701ce0),
+ U64_C (0x2ee746fdfdd3fdbb), U64_C (0x649a1f4d4d294d52),
+ U64_C (0xe0397692927292e4), U64_C (0xbceafa7575c9758f),
+ U64_C (0x1e0c360606180630), U64_C (0x9809ae8a8a128a24),
+ U64_C (0x40794bb2b2f2b2f9), U64_C (0x59d185e6e6bfe663),
+ U64_C (0x361c7e0e0e380e70), U64_C (0x633ee71f1f7c1ff8),
+ U64_C (0xf7c4556262956237), U64_C (0xa3b53ad4d477d4ee),
+ U64_C (0x324d81a8a89aa829), U64_C (0xf4315296966296c4),
+ U64_C (0x3aef62f9f9c3f99b), U64_C (0xf697a3c5c533c566),
+ U64_C (0xb14a102525942535), U64_C (0x20b2ab59597959f2),
+ U64_C (0xae15d084842a8454), U64_C (0xa7e4c57272d572b7),
+ U64_C (0xdd72ec3939e439d5), U64_C (0x6198164c4c2d4c5a),
+ U64_C (0x3bbc945e5e655eca), U64_C (0x85f09f7878fd78e7),
+ U64_C (0xd870e53838e038dd), U64_C (0x8605988c8c0a8c14),
+ U64_C (0xb2bf17d1d163d1c6), U64_C (0x0b57e4a5a5aea541),
+ U64_C (0x4dd9a1e2e2afe243), U64_C (0xf8c24e616199612f),
+ U64_C (0x457b42b3b3f6b3f1), U64_C (0xa542342121842115),
+ U64_C (0xd625089c9c4a9c94), U64_C (0x663cee1e1e781ef0),
+ U64_C (0x5286614343114322), U64_C (0xfc93b1c7c73bc776),
+ U64_C (0x2be54ffcfcd7fcb3), U64_C (0x1408240404100420),
+ U64_C (0x08a2e351515951b2), U64_C (0xc72f2599995e99bc),
+ U64_C (0xc4da226d6da96d4f), U64_C (0x391a650d0d340d68),
+ U64_C (0x35e979fafacffa83), U64_C (0x84a369dfdf5bdfb6),
+ U64_C (0x9bfca97e7ee57ed7), U64_C (0xb44819242490243d),
+ U64_C (0xd776fe3b3bec3bc5), U64_C (0x3d4b9aabab96ab31),
+ U64_C (0xd181f0cece1fce3e), U64_C (0x5522991111441188),
+ U64_C (0x8903838f8f068f0c), U64_C (0x6b9c044e4e254e4a),
+ U64_C (0x517366b7b7e6b7d1), U64_C (0x60cbe0ebeb8beb0b),
+ U64_C (0xcc78c13c3cf03cfd), U64_C (0xbf1ffd81813e817c),
+ U64_C (0xfe354094946a94d4), U64_C (0x0cf31cf7f7fbf7eb),
+ U64_C (0x676f18b9b9deb9a1), U64_C (0x5f268b13134c1398),
+ U64_C (0x9c58512c2cb02c7d), U64_C (0xb8bb05d3d36bd3d6),
+ U64_C (0x5cd38ce7e7bbe76b), U64_C (0xcbdc396e6ea56e57),
+ U64_C (0xf395aac4c437c46e), U64_C (0x0f061b03030c0318),
+ U64_C (0x13acdc565645568a), U64_C (0x49885e44440d441a),
+ U64_C (0x9efea07f7fe17fdf), U64_C (0x374f88a9a99ea921),
+ U64_C (0x8254672a2aa82a4d), U64_C (0x6d6b0abbbbd6bbb1),
+ U64_C (0xe29f87c1c123c146), U64_C (0x02a6f153535153a2),
+ U64_C (0x8ba572dcdc57dcae), U64_C (0x2716530b0b2c0b58),
+ U64_C (0xd327019d9d4e9d9c), U64_C (0xc1d82b6c6cad6c47),
+ U64_C (0xf562a43131c43195), U64_C (0xb9e8f37474cd7487),
+ U64_C (0x09f115f6f6fff6e3), U64_C (0x438c4c464605460a),
+ U64_C (0x2645a5acac8aac09), U64_C (0x970fb589891e893c),
+ U64_C (0x4428b414145014a0), U64_C (0x42dfbae1e1a3e15b),
+ U64_C (0x4e2ca616165816b0), U64_C (0xd274f73a3ae83acd),
+ U64_C (0xd0d2066969b9696f), U64_C (0x2d12410909240948),
+ U64_C (0xade0d77070dd70a7), U64_C (0x54716fb6b6e2b6d9),
+ U64_C (0xb7bd1ed0d067d0ce), U64_C (0x7ec7d6eded93ed3b),
+ U64_C (0xdb85e2cccc17cc2e), U64_C (0x578468424215422a),
+ U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449),
+ U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda),
+ U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644),
+ };
+
+static const u64 C4[256] =
+ {
+ U64_C (0xc07830d818186018), U64_C (0x05af462623238c23),
+ U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8),
+ U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8),
+ U64_C (0x0805020901010401), U64_C (0x426e9e0d4f4f214f),
+ U64_C (0xadee6c9b3636d836), U64_C (0x590451ffa6a6a2a6),
+ U64_C (0xdebdb90cd2d26fd2), U64_C (0xfb06f70ef5f5f3f5),
+ U64_C (0xef80f2967979f979), U64_C (0x5fcede306f6fa16f),
+ U64_C (0xfcef3f6d91917e91), U64_C (0xaa07a4f852525552),
+ U64_C (0x27fdc04760609d60), U64_C (0x89766535bcbccabc),
+ U64_C (0xaccd2b379b9b569b), U64_C (0x048c018a8e8e028e),
+ U64_C (0x71155bd2a3a3b6a3), U64_C (0x603c186c0c0c300c),
+ U64_C (0xff8af6847b7bf17b), U64_C (0xb5e16a803535d435),
+ U64_C (0xe8693af51d1d741d), U64_C (0x5347ddb3e0e0a7e0),
+ U64_C (0xf6acb321d7d77bd7), U64_C (0x5eed999cc2c22fc2),
+ U64_C (0x6d965c432e2eb82e), U64_C (0x627a96294b4b314b),
+ U64_C (0xa321e15dfefedffe), U64_C (0x8216aed557574157),
+ U64_C (0xa8412abd15155415), U64_C (0x9fb6eee87777c177),
+ U64_C (0xa5eb6e923737dc37), U64_C (0x7b56d79ee5e5b3e5),
+ U64_C (0x8cd923139f9f469f), U64_C (0xd317fd23f0f0e7f0),
+ U64_C (0x6a7f94204a4a354a), U64_C (0x9e95a944dada4fda),
+ U64_C (0xfa25b0a258587d58), U64_C (0x06ca8fcfc9c903c9),
+ U64_C (0x558d527c2929a429), U64_C (0x5022145a0a0a280a),
+ U64_C (0xe14f7f50b1b1feb1), U64_C (0x691a5dc9a0a0baa0),
+ U64_C (0x7fdad6146b6bb16b), U64_C (0x5cab17d985852e85),
+ U64_C (0x8173673cbdbdcebd), U64_C (0xd234ba8f5d5d695d),
+ U64_C (0x8050209010104010), U64_C (0xf303f507f4f4f7f4),
+ U64_C (0x16c08bddcbcb0bcb), U64_C (0xedc67cd33e3ef83e),
+ U64_C (0x28110a2d05051405), U64_C (0x1fe6ce7867678167),
+ U64_C (0x7353d597e4e4b7e4), U64_C (0x25bb4e0227279c27),
+ U64_C (0x3258827341411941), U64_C (0x2c9d0ba78b8b168b),
+ U64_C (0x510153f6a7a7a6a7), U64_C (0xcf94fab27d7de97d),
+ U64_C (0xdcfb374995956e95), U64_C (0x8e9fad56d8d847d8),
+ U64_C (0x8b30eb70fbfbcbfb), U64_C (0x2371c1cdeeee9fee),
+ U64_C (0xc791f8bb7c7ced7c), U64_C (0x17e3cc7166668566),
+ U64_C (0xa68ea77bdddd53dd), U64_C (0xb84b2eaf17175c17),
+ U64_C (0x02468e4547470147), U64_C (0x84dc211a9e9e429e),
+ U64_C (0x1ec589d4caca0fca), U64_C (0x75995a582d2db42d),
+ U64_C (0x9179632ebfbfc6bf), U64_C (0x381b0e3f07071c07),
+ U64_C (0x012347acadad8ead), U64_C (0xea2fb4b05a5a755a),
+ U64_C (0x6cb51bef83833683), U64_C (0x85ff66b63333cc33),
+ U64_C (0x3ff2c65c63639163), U64_C (0x100a041202020802),
+ U64_C (0x39384993aaaa92aa), U64_C (0xafa8e2de7171d971),
+ U64_C (0x0ecf8dc6c8c807c8), U64_C (0xc87d32d119196419),
+ U64_C (0x7270923b49493949), U64_C (0x869aaf5fd9d943d9),
+ U64_C (0xc31df931f2f2eff2), U64_C (0x4b48dba8e3e3abe3),
+ U64_C (0xe22ab6b95b5b715b), U64_C (0x34920dbc88881a88),
+ U64_C (0xa4c8293e9a9a529a), U64_C (0x2dbe4c0b26269826),
+ U64_C (0x8dfa64bf3232c832), U64_C (0xe94a7d59b0b0fab0),
+ U64_C (0x1b6acff2e9e983e9), U64_C (0x78331e770f0f3c0f),
+ U64_C (0xe6a6b733d5d573d5), U64_C (0x74ba1df480803a80),
+ U64_C (0x997c6127bebec2be), U64_C (0x26de87ebcdcd13cd),
+ U64_C (0xbde468893434d034), U64_C (0x7a75903248483d48),
+ U64_C (0xab24e354ffffdbff), U64_C (0xf78ff48d7a7af57a),
+ U64_C (0xf4ea3d6490907a90), U64_C (0xc23ebe9d5f5f615f),
+ U64_C (0x1da0403d20208020), U64_C (0x67d5d00f6868bd68),
+ U64_C (0xd07234ca1a1a681a), U64_C (0x192c41b7aeae82ae),
+ U64_C (0xc95e757db4b4eab4), U64_C (0x9a19a8ce54544d54),
+ U64_C (0xece53b7f93937693), U64_C (0x0daa442f22228822),
+ U64_C (0x07e9c86364648d64), U64_C (0xdb12ff2af1f1e3f1),
+ U64_C (0xbfa2e6cc7373d173), U64_C (0x905a248212124812),
+ U64_C (0x3a5d807a40401d40), U64_C (0x4028104808082008),
+ U64_C (0x56e89b95c3c32bc3), U64_C (0x337bc5dfecec97ec),
+ U64_C (0x9690ab4ddbdb4bdb), U64_C (0x611f5fc0a1a1bea1),
+ U64_C (0x1c8307918d8d0e8d), U64_C (0xf5c97ac83d3df43d),
+ U64_C (0xccf1335b97976697), U64_C (0x0000000000000000),
+ U64_C (0x36d483f9cfcf1bcf), U64_C (0x4587566e2b2bac2b),
+ U64_C (0x97b3ece17676c576), U64_C (0x64b019e682823282),
+ U64_C (0xfea9b128d6d67fd6), U64_C (0xd87736c31b1b6c1b),
+ U64_C (0xc15b7774b5b5eeb5), U64_C (0x112943beafaf86af),
+ U64_C (0x77dfd41d6a6ab56a), U64_C (0xba0da0ea50505d50),
+ U64_C (0x124c8a5745450945), U64_C (0xcb18fb38f3f3ebf3),
+ U64_C (0x9df060ad3030c030), U64_C (0x2b74c3c4efef9bef),
+ U64_C (0xe5c37eda3f3ffc3f), U64_C (0x921caac755554955),
+ U64_C (0x791059dba2a2b2a2), U64_C (0x0365c9e9eaea8fea),
+ U64_C (0x0fecca6a65658965), U64_C (0xb9686903babad2ba),
+ U64_C (0x65935e4a2f2fbc2f), U64_C (0x4ee79d8ec0c027c0),
+ U64_C (0xbe81a160dede5fde), U64_C (0xe06c38fc1c1c701c),
+ U64_C (0xbb2ee746fdfdd3fd), U64_C (0x52649a1f4d4d294d),
+ U64_C (0xe4e0397692927292), U64_C (0x8fbceafa7575c975),
+ U64_C (0x301e0c3606061806), U64_C (0x249809ae8a8a128a),
+ U64_C (0xf940794bb2b2f2b2), U64_C (0x6359d185e6e6bfe6),
+ U64_C (0x70361c7e0e0e380e), U64_C (0xf8633ee71f1f7c1f),
+ U64_C (0x37f7c45562629562), U64_C (0xeea3b53ad4d477d4),
+ U64_C (0x29324d81a8a89aa8), U64_C (0xc4f4315296966296),
+ U64_C (0x9b3aef62f9f9c3f9), U64_C (0x66f697a3c5c533c5),
+ U64_C (0x35b14a1025259425), U64_C (0xf220b2ab59597959),
+ U64_C (0x54ae15d084842a84), U64_C (0xb7a7e4c57272d572),
+ U64_C (0xd5dd72ec3939e439), U64_C (0x5a6198164c4c2d4c),
+ U64_C (0xca3bbc945e5e655e), U64_C (0xe785f09f7878fd78),
+ U64_C (0xddd870e53838e038), U64_C (0x148605988c8c0a8c),
+ U64_C (0xc6b2bf17d1d163d1), U64_C (0x410b57e4a5a5aea5),
+ U64_C (0x434dd9a1e2e2afe2), U64_C (0x2ff8c24e61619961),
+ U64_C (0xf1457b42b3b3f6b3), U64_C (0x15a5423421218421),
+ U64_C (0x94d625089c9c4a9c), U64_C (0xf0663cee1e1e781e),
+ U64_C (0x2252866143431143), U64_C (0x76fc93b1c7c73bc7),
+ U64_C (0xb32be54ffcfcd7fc), U64_C (0x2014082404041004),
+ U64_C (0xb208a2e351515951), U64_C (0xbcc72f2599995e99),
+ U64_C (0x4fc4da226d6da96d), U64_C (0x68391a650d0d340d),
+ U64_C (0x8335e979fafacffa), U64_C (0xb684a369dfdf5bdf),
+ U64_C (0xd79bfca97e7ee57e), U64_C (0x3db4481924249024),
+ U64_C (0xc5d776fe3b3bec3b), U64_C (0x313d4b9aabab96ab),
+ U64_C (0x3ed181f0cece1fce), U64_C (0x8855229911114411),
+ U64_C (0x0c8903838f8f068f), U64_C (0x4a6b9c044e4e254e),
+ U64_C (0xd1517366b7b7e6b7), U64_C (0x0b60cbe0ebeb8beb),
+ U64_C (0xfdcc78c13c3cf03c), U64_C (0x7cbf1ffd81813e81),
+ U64_C (0xd4fe354094946a94), U64_C (0xeb0cf31cf7f7fbf7),
+ U64_C (0xa1676f18b9b9deb9), U64_C (0x985f268b13134c13),
+ U64_C (0x7d9c58512c2cb02c), U64_C (0xd6b8bb05d3d36bd3),
+ U64_C (0x6b5cd38ce7e7bbe7), U64_C (0x57cbdc396e6ea56e),
+ U64_C (0x6ef395aac4c437c4), U64_C (0x180f061b03030c03),
+ U64_C (0x8a13acdc56564556), U64_C (0x1a49885e44440d44),
+ U64_C (0xdf9efea07f7fe17f), U64_C (0x21374f88a9a99ea9),
+ U64_C (0x4d8254672a2aa82a), U64_C (0xb16d6b0abbbbd6bb),
+ U64_C (0x46e29f87c1c123c1), U64_C (0xa202a6f153535153),
+ U64_C (0xae8ba572dcdc57dc), U64_C (0x582716530b0b2c0b),
+ U64_C (0x9cd327019d9d4e9d), U64_C (0x47c1d82b6c6cad6c),
+ U64_C (0x95f562a43131c431), U64_C (0x87b9e8f37474cd74),
+ U64_C (0xe309f115f6f6fff6), U64_C (0x0a438c4c46460546),
+ U64_C (0x092645a5acac8aac), U64_C (0x3c970fb589891e89),
+ U64_C (0xa04428b414145014), U64_C (0x5b42dfbae1e1a3e1),
+ U64_C (0xb04e2ca616165816), U64_C (0xcdd274f73a3ae83a),
+ U64_C (0x6fd0d2066969b969), U64_C (0x482d124109092409),
+ U64_C (0xa7ade0d77070dd70), U64_C (0xd954716fb6b6e2b6),
+ U64_C (0xceb7bd1ed0d067d0), U64_C (0x3b7ec7d6eded93ed),
+ U64_C (0x2edb85e2cccc17cc), U64_C (0x2a57846842421542),
+ U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4),
+ U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c),
+ U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286),
+ };
+
+static const u64 C5[256] =
+ {
+ U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c),
+ U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887),
+ U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da),
+ U64_C (0x0108050209010104), U64_C (0x4f426e9e0d4f4f21),
+ U64_C (0x36adee6c9b3636d8), U64_C (0xa6590451ffa6a6a2),
+ U64_C (0xd2debdb90cd2d26f), U64_C (0xf5fb06f70ef5f5f3),
+ U64_C (0x79ef80f2967979f9), U64_C (0x6f5fcede306f6fa1),
+ U64_C (0x91fcef3f6d91917e), U64_C (0x52aa07a4f8525255),
+ U64_C (0x6027fdc04760609d), U64_C (0xbc89766535bcbcca),
+ U64_C (0x9baccd2b379b9b56), U64_C (0x8e048c018a8e8e02),
+ U64_C (0xa371155bd2a3a3b6), U64_C (0x0c603c186c0c0c30),
+ U64_C (0x7bff8af6847b7bf1), U64_C (0x35b5e16a803535d4),
+ U64_C (0x1de8693af51d1d74), U64_C (0xe05347ddb3e0e0a7),
+ U64_C (0xd7f6acb321d7d77b), U64_C (0xc25eed999cc2c22f),
+ U64_C (0x2e6d965c432e2eb8), U64_C (0x4b627a96294b4b31),
+ U64_C (0xfea321e15dfefedf), U64_C (0x578216aed5575741),
+ U64_C (0x15a8412abd151554), U64_C (0x779fb6eee87777c1),
+ U64_C (0x37a5eb6e923737dc), U64_C (0xe57b56d79ee5e5b3),
+ U64_C (0x9f8cd923139f9f46), U64_C (0xf0d317fd23f0f0e7),
+ U64_C (0x4a6a7f94204a4a35), U64_C (0xda9e95a944dada4f),
+ U64_C (0x58fa25b0a258587d), U64_C (0xc906ca8fcfc9c903),
+ U64_C (0x29558d527c2929a4), U64_C (0x0a5022145a0a0a28),
+ U64_C (0xb1e14f7f50b1b1fe), U64_C (0xa0691a5dc9a0a0ba),
+ U64_C (0x6b7fdad6146b6bb1), U64_C (0x855cab17d985852e),
+ U64_C (0xbd8173673cbdbdce), U64_C (0x5dd234ba8f5d5d69),
+ U64_C (0x1080502090101040), U64_C (0xf4f303f507f4f4f7),
+ U64_C (0xcb16c08bddcbcb0b), U64_C (0x3eedc67cd33e3ef8),
+ U64_C (0x0528110a2d050514), U64_C (0x671fe6ce78676781),
+ U64_C (0xe47353d597e4e4b7), U64_C (0x2725bb4e0227279c),
+ U64_C (0x4132588273414119), U64_C (0x8b2c9d0ba78b8b16),
+ U64_C (0xa7510153f6a7a7a6), U64_C (0x7dcf94fab27d7de9),
+ U64_C (0x95dcfb374995956e), U64_C (0xd88e9fad56d8d847),
+ U64_C (0xfb8b30eb70fbfbcb), U64_C (0xee2371c1cdeeee9f),
+ U64_C (0x7cc791f8bb7c7ced), U64_C (0x6617e3cc71666685),
+ U64_C (0xdda68ea77bdddd53), U64_C (0x17b84b2eaf17175c),
+ U64_C (0x4702468e45474701), U64_C (0x9e84dc211a9e9e42),
+ U64_C (0xca1ec589d4caca0f), U64_C (0x2d75995a582d2db4),
+ U64_C (0xbf9179632ebfbfc6), U64_C (0x07381b0e3f07071c),
+ U64_C (0xad012347acadad8e), U64_C (0x5aea2fb4b05a5a75),
+ U64_C (0x836cb51bef838336), U64_C (0x3385ff66b63333cc),
+ U64_C (0x633ff2c65c636391), U64_C (0x02100a0412020208),
+ U64_C (0xaa39384993aaaa92), U64_C (0x71afa8e2de7171d9),
+ U64_C (0xc80ecf8dc6c8c807), U64_C (0x19c87d32d1191964),
+ U64_C (0x497270923b494939), U64_C (0xd9869aaf5fd9d943),
+ U64_C (0xf2c31df931f2f2ef), U64_C (0xe34b48dba8e3e3ab),
+ U64_C (0x5be22ab6b95b5b71), U64_C (0x8834920dbc88881a),
+ U64_C (0x9aa4c8293e9a9a52), U64_C (0x262dbe4c0b262698),
+ U64_C (0x328dfa64bf3232c8), U64_C (0xb0e94a7d59b0b0fa),
+ U64_C (0xe91b6acff2e9e983), U64_C (0x0f78331e770f0f3c),
+ U64_C (0xd5e6a6b733d5d573), U64_C (0x8074ba1df480803a),
+ U64_C (0xbe997c6127bebec2), U64_C (0xcd26de87ebcdcd13),
+ U64_C (0x34bde468893434d0), U64_C (0x487a75903248483d),
+ U64_C (0xffab24e354ffffdb), U64_C (0x7af78ff48d7a7af5),
+ U64_C (0x90f4ea3d6490907a), U64_C (0x5fc23ebe9d5f5f61),
+ U64_C (0x201da0403d202080), U64_C (0x6867d5d00f6868bd),
+ U64_C (0x1ad07234ca1a1a68), U64_C (0xae192c41b7aeae82),
+ U64_C (0xb4c95e757db4b4ea), U64_C (0x549a19a8ce54544d),
+ U64_C (0x93ece53b7f939376), U64_C (0x220daa442f222288),
+ U64_C (0x6407e9c86364648d), U64_C (0xf1db12ff2af1f1e3),
+ U64_C (0x73bfa2e6cc7373d1), U64_C (0x12905a2482121248),
+ U64_C (0x403a5d807a40401d), U64_C (0x0840281048080820),
+ U64_C (0xc356e89b95c3c32b), U64_C (0xec337bc5dfecec97),
+ U64_C (0xdb9690ab4ddbdb4b), U64_C (0xa1611f5fc0a1a1be),
+ U64_C (0x8d1c8307918d8d0e), U64_C (0x3df5c97ac83d3df4),
+ U64_C (0x97ccf1335b979766), U64_C (0x0000000000000000),
+ U64_C (0xcf36d483f9cfcf1b), U64_C (0x2b4587566e2b2bac),
+ U64_C (0x7697b3ece17676c5), U64_C (0x8264b019e6828232),
+ U64_C (0xd6fea9b128d6d67f), U64_C (0x1bd87736c31b1b6c),
+ U64_C (0xb5c15b7774b5b5ee), U64_C (0xaf112943beafaf86),
+ U64_C (0x6a77dfd41d6a6ab5), U64_C (0x50ba0da0ea50505d),
+ U64_C (0x45124c8a57454509), U64_C (0xf3cb18fb38f3f3eb),
+ U64_C (0x309df060ad3030c0), U64_C (0xef2b74c3c4efef9b),
+ U64_C (0x3fe5c37eda3f3ffc), U64_C (0x55921caac7555549),
+ U64_C (0xa2791059dba2a2b2), U64_C (0xea0365c9e9eaea8f),
+ U64_C (0x650fecca6a656589), U64_C (0xbab9686903babad2),
+ U64_C (0x2f65935e4a2f2fbc), U64_C (0xc04ee79d8ec0c027),
+ U64_C (0xdebe81a160dede5f), U64_C (0x1ce06c38fc1c1c70),
+ U64_C (0xfdbb2ee746fdfdd3), U64_C (0x4d52649a1f4d4d29),
+ U64_C (0x92e4e03976929272), U64_C (0x758fbceafa7575c9),
+ U64_C (0x06301e0c36060618), U64_C (0x8a249809ae8a8a12),
+ U64_C (0xb2f940794bb2b2f2), U64_C (0xe66359d185e6e6bf),
+ U64_C (0x0e70361c7e0e0e38), U64_C (0x1ff8633ee71f1f7c),
+ U64_C (0x6237f7c455626295), U64_C (0xd4eea3b53ad4d477),
+ U64_C (0xa829324d81a8a89a), U64_C (0x96c4f43152969662),
+ U64_C (0xf99b3aef62f9f9c3), U64_C (0xc566f697a3c5c533),
+ U64_C (0x2535b14a10252594), U64_C (0x59f220b2ab595979),
+ U64_C (0x8454ae15d084842a), U64_C (0x72b7a7e4c57272d5),
+ U64_C (0x39d5dd72ec3939e4), U64_C (0x4c5a6198164c4c2d),
+ U64_C (0x5eca3bbc945e5e65), U64_C (0x78e785f09f7878fd),
+ U64_C (0x38ddd870e53838e0), U64_C (0x8c148605988c8c0a),
+ U64_C (0xd1c6b2bf17d1d163), U64_C (0xa5410b57e4a5a5ae),
+ U64_C (0xe2434dd9a1e2e2af), U64_C (0x612ff8c24e616199),
+ U64_C (0xb3f1457b42b3b3f6), U64_C (0x2115a54234212184),
+ U64_C (0x9c94d625089c9c4a), U64_C (0x1ef0663cee1e1e78),
+ U64_C (0x4322528661434311), U64_C (0xc776fc93b1c7c73b),
+ U64_C (0xfcb32be54ffcfcd7), U64_C (0x0420140824040410),
+ U64_C (0x51b208a2e3515159), U64_C (0x99bcc72f2599995e),
+ U64_C (0x6d4fc4da226d6da9), U64_C (0x0d68391a650d0d34),
+ U64_C (0xfa8335e979fafacf), U64_C (0xdfb684a369dfdf5b),
+ U64_C (0x7ed79bfca97e7ee5), U64_C (0x243db44819242490),
+ U64_C (0x3bc5d776fe3b3bec), U64_C (0xab313d4b9aabab96),
+ U64_C (0xce3ed181f0cece1f), U64_C (0x1188552299111144),
+ U64_C (0x8f0c8903838f8f06), U64_C (0x4e4a6b9c044e4e25),
+ U64_C (0xb7d1517366b7b7e6), U64_C (0xeb0b60cbe0ebeb8b),
+ U64_C (0x3cfdcc78c13c3cf0), U64_C (0x817cbf1ffd81813e),
+ U64_C (0x94d4fe354094946a), U64_C (0xf7eb0cf31cf7f7fb),
+ U64_C (0xb9a1676f18b9b9de), U64_C (0x13985f268b13134c),
+ U64_C (0x2c7d9c58512c2cb0), U64_C (0xd3d6b8bb05d3d36b),
+ U64_C (0xe76b5cd38ce7e7bb), U64_C (0x6e57cbdc396e6ea5),
+ U64_C (0xc46ef395aac4c437), U64_C (0x03180f061b03030c),
+ U64_C (0x568a13acdc565645), U64_C (0x441a49885e44440d),
+ U64_C (0x7fdf9efea07f7fe1), U64_C (0xa921374f88a9a99e),
+ U64_C (0x2a4d8254672a2aa8), U64_C (0xbbb16d6b0abbbbd6),
+ U64_C (0xc146e29f87c1c123), U64_C (0x53a202a6f1535351),
+ U64_C (0xdcae8ba572dcdc57), U64_C (0x0b582716530b0b2c),
+ U64_C (0x9d9cd327019d9d4e), U64_C (0x6c47c1d82b6c6cad),
+ U64_C (0x3195f562a43131c4), U64_C (0x7487b9e8f37474cd),
+ U64_C (0xf6e309f115f6f6ff), U64_C (0x460a438c4c464605),
+ U64_C (0xac092645a5acac8a), U64_C (0x893c970fb589891e),
+ U64_C (0x14a04428b4141450), U64_C (0xe15b42dfbae1e1a3),
+ U64_C (0x16b04e2ca6161658), U64_C (0x3acdd274f73a3ae8),
+ U64_C (0x696fd0d2066969b9), U64_C (0x09482d1241090924),
+ U64_C (0x70a7ade0d77070dd), U64_C (0xb6d954716fb6b6e2),
+ U64_C (0xd0ceb7bd1ed0d067), U64_C (0xed3b7ec7d6eded93),
+ U64_C (0xcc2edb85e2cccc17), U64_C (0x422a578468424215),
+ U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa),
+ U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d),
+ U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622),
+ };
+
+static const u64 C6[256] =
+ {
+ U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323),
+ U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8),
+ U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8),
+ U64_C (0x0401080502090101), U64_C (0x214f426e9e0d4f4f),
+ U64_C (0xd836adee6c9b3636), U64_C (0xa2a6590451ffa6a6),
+ U64_C (0x6fd2debdb90cd2d2), U64_C (0xf3f5fb06f70ef5f5),
+ U64_C (0xf979ef80f2967979), U64_C (0xa16f5fcede306f6f),
+ U64_C (0x7e91fcef3f6d9191), U64_C (0x5552aa07a4f85252),
+ U64_C (0x9d6027fdc0476060), U64_C (0xcabc89766535bcbc),
+ U64_C (0x569baccd2b379b9b), U64_C (0x028e048c018a8e8e),
+ U64_C (0xb6a371155bd2a3a3), U64_C (0x300c603c186c0c0c),
+ U64_C (0xf17bff8af6847b7b), U64_C (0xd435b5e16a803535),
+ U64_C (0x741de8693af51d1d), U64_C (0xa7e05347ddb3e0e0),
+ U64_C (0x7bd7f6acb321d7d7), U64_C (0x2fc25eed999cc2c2),
+ U64_C (0xb82e6d965c432e2e), U64_C (0x314b627a96294b4b),
+ U64_C (0xdffea321e15dfefe), U64_C (0x41578216aed55757),
+ U64_C (0x5415a8412abd1515), U64_C (0xc1779fb6eee87777),
+ U64_C (0xdc37a5eb6e923737), U64_C (0xb3e57b56d79ee5e5),
+ U64_C (0x469f8cd923139f9f), U64_C (0xe7f0d317fd23f0f0),
+ U64_C (0x354a6a7f94204a4a), U64_C (0x4fda9e95a944dada),
+ U64_C (0x7d58fa25b0a25858), U64_C (0x03c906ca8fcfc9c9),
+ U64_C (0xa429558d527c2929), U64_C (0x280a5022145a0a0a),
+ U64_C (0xfeb1e14f7f50b1b1), U64_C (0xbaa0691a5dc9a0a0),
+ U64_C (0xb16b7fdad6146b6b), U64_C (0x2e855cab17d98585),
+ U64_C (0xcebd8173673cbdbd), U64_C (0x695dd234ba8f5d5d),
+ U64_C (0x4010805020901010), U64_C (0xf7f4f303f507f4f4),
+ U64_C (0x0bcb16c08bddcbcb), U64_C (0xf83eedc67cd33e3e),
+ U64_C (0x140528110a2d0505), U64_C (0x81671fe6ce786767),
+ U64_C (0xb7e47353d597e4e4), U64_C (0x9c2725bb4e022727),
+ U64_C (0x1941325882734141), U64_C (0x168b2c9d0ba78b8b),
+ U64_C (0xa6a7510153f6a7a7), U64_C (0xe97dcf94fab27d7d),
+ U64_C (0x6e95dcfb37499595), U64_C (0x47d88e9fad56d8d8),
+ U64_C (0xcbfb8b30eb70fbfb), U64_C (0x9fee2371c1cdeeee),
+ U64_C (0xed7cc791f8bb7c7c), U64_C (0x856617e3cc716666),
+ U64_C (0x53dda68ea77bdddd), U64_C (0x5c17b84b2eaf1717),
+ U64_C (0x014702468e454747), U64_C (0x429e84dc211a9e9e),
+ U64_C (0x0fca1ec589d4caca), U64_C (0xb42d75995a582d2d),
+ U64_C (0xc6bf9179632ebfbf), U64_C (0x1c07381b0e3f0707),
+ U64_C (0x8ead012347acadad), U64_C (0x755aea2fb4b05a5a),
+ U64_C (0x36836cb51bef8383), U64_C (0xcc3385ff66b63333),
+ U64_C (0x91633ff2c65c6363), U64_C (0x0802100a04120202),
+ U64_C (0x92aa39384993aaaa), U64_C (0xd971afa8e2de7171),
+ U64_C (0x07c80ecf8dc6c8c8), U64_C (0x6419c87d32d11919),
+ U64_C (0x39497270923b4949), U64_C (0x43d9869aaf5fd9d9),
+ U64_C (0xeff2c31df931f2f2), U64_C (0xabe34b48dba8e3e3),
+ U64_C (0x715be22ab6b95b5b), U64_C (0x1a8834920dbc8888),
+ U64_C (0x529aa4c8293e9a9a), U64_C (0x98262dbe4c0b2626),
+ U64_C (0xc8328dfa64bf3232), U64_C (0xfab0e94a7d59b0b0),
+ U64_C (0x83e91b6acff2e9e9), U64_C (0x3c0f78331e770f0f),
+ U64_C (0x73d5e6a6b733d5d5), U64_C (0x3a8074ba1df48080),
+ U64_C (0xc2be997c6127bebe), U64_C (0x13cd26de87ebcdcd),
+ U64_C (0xd034bde468893434), U64_C (0x3d487a7590324848),
+ U64_C (0xdbffab24e354ffff), U64_C (0xf57af78ff48d7a7a),
+ U64_C (0x7a90f4ea3d649090), U64_C (0x615fc23ebe9d5f5f),
+ U64_C (0x80201da0403d2020), U64_C (0xbd6867d5d00f6868),
+ U64_C (0x681ad07234ca1a1a), U64_C (0x82ae192c41b7aeae),
+ U64_C (0xeab4c95e757db4b4), U64_C (0x4d549a19a8ce5454),
+ U64_C (0x7693ece53b7f9393), U64_C (0x88220daa442f2222),
+ U64_C (0x8d6407e9c8636464), U64_C (0xe3f1db12ff2af1f1),
+ U64_C (0xd173bfa2e6cc7373), U64_C (0x4812905a24821212),
+ U64_C (0x1d403a5d807a4040), U64_C (0x2008402810480808),
+ U64_C (0x2bc356e89b95c3c3), U64_C (0x97ec337bc5dfecec),
+ U64_C (0x4bdb9690ab4ddbdb), U64_C (0xbea1611f5fc0a1a1),
+ U64_C (0x0e8d1c8307918d8d), U64_C (0xf43df5c97ac83d3d),
+ U64_C (0x6697ccf1335b9797), U64_C (0x0000000000000000),
+ U64_C (0x1bcf36d483f9cfcf), U64_C (0xac2b4587566e2b2b),
+ U64_C (0xc57697b3ece17676), U64_C (0x328264b019e68282),
+ U64_C (0x7fd6fea9b128d6d6), U64_C (0x6c1bd87736c31b1b),
+ U64_C (0xeeb5c15b7774b5b5), U64_C (0x86af112943beafaf),
+ U64_C (0xb56a77dfd41d6a6a), U64_C (0x5d50ba0da0ea5050),
+ U64_C (0x0945124c8a574545), U64_C (0xebf3cb18fb38f3f3),
+ U64_C (0xc0309df060ad3030), U64_C (0x9bef2b74c3c4efef),
+ U64_C (0xfc3fe5c37eda3f3f), U64_C (0x4955921caac75555),
+ U64_C (0xb2a2791059dba2a2), U64_C (0x8fea0365c9e9eaea),
+ U64_C (0x89650fecca6a6565), U64_C (0xd2bab9686903baba),
+ U64_C (0xbc2f65935e4a2f2f), U64_C (0x27c04ee79d8ec0c0),
+ U64_C (0x5fdebe81a160dede), U64_C (0x701ce06c38fc1c1c),
+ U64_C (0xd3fdbb2ee746fdfd), U64_C (0x294d52649a1f4d4d),
+ U64_C (0x7292e4e039769292), U64_C (0xc9758fbceafa7575),
+ U64_C (0x1806301e0c360606), U64_C (0x128a249809ae8a8a),
+ U64_C (0xf2b2f940794bb2b2), U64_C (0xbfe66359d185e6e6),
+ U64_C (0x380e70361c7e0e0e), U64_C (0x7c1ff8633ee71f1f),
+ U64_C (0x956237f7c4556262), U64_C (0x77d4eea3b53ad4d4),
+ U64_C (0x9aa829324d81a8a8), U64_C (0x6296c4f431529696),
+ U64_C (0xc3f99b3aef62f9f9), U64_C (0x33c566f697a3c5c5),
+ U64_C (0x942535b14a102525), U64_C (0x7959f220b2ab5959),
+ U64_C (0x2a8454ae15d08484), U64_C (0xd572b7a7e4c57272),
+ U64_C (0xe439d5dd72ec3939), U64_C (0x2d4c5a6198164c4c),
+ U64_C (0x655eca3bbc945e5e), U64_C (0xfd78e785f09f7878),
+ U64_C (0xe038ddd870e53838), U64_C (0x0a8c148605988c8c),
+ U64_C (0x63d1c6b2bf17d1d1), U64_C (0xaea5410b57e4a5a5),
+ U64_C (0xafe2434dd9a1e2e2), U64_C (0x99612ff8c24e6161),
+ U64_C (0xf6b3f1457b42b3b3), U64_C (0x842115a542342121),
+ U64_C (0x4a9c94d625089c9c), U64_C (0x781ef0663cee1e1e),
+ U64_C (0x1143225286614343), U64_C (0x3bc776fc93b1c7c7),
+ U64_C (0xd7fcb32be54ffcfc), U64_C (0x1004201408240404),
+ U64_C (0x5951b208a2e35151), U64_C (0x5e99bcc72f259999),
+ U64_C (0xa96d4fc4da226d6d), U64_C (0x340d68391a650d0d),
+ U64_C (0xcffa8335e979fafa), U64_C (0x5bdfb684a369dfdf),
+ U64_C (0xe57ed79bfca97e7e), U64_C (0x90243db448192424),
+ U64_C (0xec3bc5d776fe3b3b), U64_C (0x96ab313d4b9aabab),
+ U64_C (0x1fce3ed181f0cece), U64_C (0x4411885522991111),
+ U64_C (0x068f0c8903838f8f), U64_C (0x254e4a6b9c044e4e),
+ U64_C (0xe6b7d1517366b7b7), U64_C (0x8beb0b60cbe0ebeb),
+ U64_C (0xf03cfdcc78c13c3c), U64_C (0x3e817cbf1ffd8181),
+ U64_C (0x6a94d4fe35409494), U64_C (0xfbf7eb0cf31cf7f7),
+ U64_C (0xdeb9a1676f18b9b9), U64_C (0x4c13985f268b1313),
+ U64_C (0xb02c7d9c58512c2c), U64_C (0x6bd3d6b8bb05d3d3),
+ U64_C (0xbbe76b5cd38ce7e7), U64_C (0xa56e57cbdc396e6e),
+ U64_C (0x37c46ef395aac4c4), U64_C (0x0c03180f061b0303),
+ U64_C (0x45568a13acdc5656), U64_C (0x0d441a49885e4444),
+ U64_C (0xe17fdf9efea07f7f), U64_C (0x9ea921374f88a9a9),
+ U64_C (0xa82a4d8254672a2a), U64_C (0xd6bbb16d6b0abbbb),
+ U64_C (0x23c146e29f87c1c1), U64_C (0x5153a202a6f15353),
+ U64_C (0x57dcae8ba572dcdc), U64_C (0x2c0b582716530b0b),
+ U64_C (0x4e9d9cd327019d9d), U64_C (0xad6c47c1d82b6c6c),
+ U64_C (0xc43195f562a43131), U64_C (0xcd7487b9e8f37474),
+ U64_C (0xfff6e309f115f6f6), U64_C (0x05460a438c4c4646),
+ U64_C (0x8aac092645a5acac), U64_C (0x1e893c970fb58989),
+ U64_C (0x5014a04428b41414), U64_C (0xa3e15b42dfbae1e1),
+ U64_C (0x5816b04e2ca61616), U64_C (0xe83acdd274f73a3a),
+ U64_C (0xb9696fd0d2066969), U64_C (0x2409482d12410909),
+ U64_C (0xdd70a7ade0d77070), U64_C (0xe2b6d954716fb6b6),
+ U64_C (0x67d0ceb7bd1ed0d0), U64_C (0x93ed3b7ec7d6eded),
+ U64_C (0x17cc2edb85e2cccc), U64_C (0x15422a5784684242),
+ U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4),
+ U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c),
+ U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686),
+ };
+
+static const u64 C7[256] =
+ {
+ U64_C (0x186018c07830d818), U64_C (0x238c2305af462623),
+ U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8),
+ U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8),
+ U64_C (0x0104010805020901), U64_C (0x4f214f426e9e0d4f),
+ U64_C (0x36d836adee6c9b36), U64_C (0xa6a2a6590451ffa6),
+ U64_C (0xd26fd2debdb90cd2), U64_C (0xf5f3f5fb06f70ef5),
+ U64_C (0x79f979ef80f29679), U64_C (0x6fa16f5fcede306f),
+ U64_C (0x917e91fcef3f6d91), U64_C (0x525552aa07a4f852),
+ U64_C (0x609d6027fdc04760), U64_C (0xbccabc89766535bc),
+ U64_C (0x9b569baccd2b379b), U64_C (0x8e028e048c018a8e),
+ U64_C (0xa3b6a371155bd2a3), U64_C (0x0c300c603c186c0c),
+ U64_C (0x7bf17bff8af6847b), U64_C (0x35d435b5e16a8035),
+ U64_C (0x1d741de8693af51d), U64_C (0xe0a7e05347ddb3e0),
+ U64_C (0xd77bd7f6acb321d7), U64_C (0xc22fc25eed999cc2),
+ U64_C (0x2eb82e6d965c432e), U64_C (0x4b314b627a96294b),
+ U64_C (0xfedffea321e15dfe), U64_C (0x5741578216aed557),
+ U64_C (0x155415a8412abd15), U64_C (0x77c1779fb6eee877),
+ U64_C (0x37dc37a5eb6e9237), U64_C (0xe5b3e57b56d79ee5),
+ U64_C (0x9f469f8cd923139f), U64_C (0xf0e7f0d317fd23f0),
+ U64_C (0x4a354a6a7f94204a), U64_C (0xda4fda9e95a944da),
+ U64_C (0x587d58fa25b0a258), U64_C (0xc903c906ca8fcfc9),
+ U64_C (0x29a429558d527c29), U64_C (0x0a280a5022145a0a),
+ U64_C (0xb1feb1e14f7f50b1), U64_C (0xa0baa0691a5dc9a0),
+ U64_C (0x6bb16b7fdad6146b), U64_C (0x852e855cab17d985),
+ U64_C (0xbdcebd8173673cbd), U64_C (0x5d695dd234ba8f5d),
+ U64_C (0x1040108050209010), U64_C (0xf4f7f4f303f507f4),
+ U64_C (0xcb0bcb16c08bddcb), U64_C (0x3ef83eedc67cd33e),
+ U64_C (0x05140528110a2d05), U64_C (0x6781671fe6ce7867),
+ U64_C (0xe4b7e47353d597e4), U64_C (0x279c2725bb4e0227),
+ U64_C (0x4119413258827341), U64_C (0x8b168b2c9d0ba78b),
+ U64_C (0xa7a6a7510153f6a7), U64_C (0x7de97dcf94fab27d),
+ U64_C (0x956e95dcfb374995), U64_C (0xd847d88e9fad56d8),
+ U64_C (0xfbcbfb8b30eb70fb), U64_C (0xee9fee2371c1cdee),
+ U64_C (0x7ced7cc791f8bb7c), U64_C (0x66856617e3cc7166),
+ U64_C (0xdd53dda68ea77bdd), U64_C (0x175c17b84b2eaf17),
+ U64_C (0x47014702468e4547), U64_C (0x9e429e84dc211a9e),
+ U64_C (0xca0fca1ec589d4ca), U64_C (0x2db42d75995a582d),
+ U64_C (0xbfc6bf9179632ebf), U64_C (0x071c07381b0e3f07),
+ U64_C (0xad8ead012347acad), U64_C (0x5a755aea2fb4b05a),
+ U64_C (0x8336836cb51bef83), U64_C (0x33cc3385ff66b633),
+ U64_C (0x6391633ff2c65c63), U64_C (0x020802100a041202),
+ U64_C (0xaa92aa39384993aa), U64_C (0x71d971afa8e2de71),
+ U64_C (0xc807c80ecf8dc6c8), U64_C (0x196419c87d32d119),
+ U64_C (0x4939497270923b49), U64_C (0xd943d9869aaf5fd9),
+ U64_C (0xf2eff2c31df931f2), U64_C (0xe3abe34b48dba8e3),
+ U64_C (0x5b715be22ab6b95b), U64_C (0x881a8834920dbc88),
+ U64_C (0x9a529aa4c8293e9a), U64_C (0x2698262dbe4c0b26),
+ U64_C (0x32c8328dfa64bf32), U64_C (0xb0fab0e94a7d59b0),
+ U64_C (0xe983e91b6acff2e9), U64_C (0x0f3c0f78331e770f),
+ U64_C (0xd573d5e6a6b733d5), U64_C (0x803a8074ba1df480),
+ U64_C (0xbec2be997c6127be), U64_C (0xcd13cd26de87ebcd),
+ U64_C (0x34d034bde4688934), U64_C (0x483d487a75903248),
+ U64_C (0xffdbffab24e354ff), U64_C (0x7af57af78ff48d7a),
+ U64_C (0x907a90f4ea3d6490), U64_C (0x5f615fc23ebe9d5f),
+ U64_C (0x2080201da0403d20), U64_C (0x68bd6867d5d00f68),
+ U64_C (0x1a681ad07234ca1a), U64_C (0xae82ae192c41b7ae),
+ U64_C (0xb4eab4c95e757db4), U64_C (0x544d549a19a8ce54),
+ U64_C (0x937693ece53b7f93), U64_C (0x2288220daa442f22),
+ U64_C (0x648d6407e9c86364), U64_C (0xf1e3f1db12ff2af1),
+ U64_C (0x73d173bfa2e6cc73), U64_C (0x124812905a248212),
+ U64_C (0x401d403a5d807a40), U64_C (0x0820084028104808),
+ U64_C (0xc32bc356e89b95c3), U64_C (0xec97ec337bc5dfec),
+ U64_C (0xdb4bdb9690ab4ddb), U64_C (0xa1bea1611f5fc0a1),
+ U64_C (0x8d0e8d1c8307918d), U64_C (0x3df43df5c97ac83d),
+ U64_C (0x976697ccf1335b97), U64_C (0x0000000000000000),
+ U64_C (0xcf1bcf36d483f9cf), U64_C (0x2bac2b4587566e2b),
+ U64_C (0x76c57697b3ece176), U64_C (0x82328264b019e682),
+ U64_C (0xd67fd6fea9b128d6), U64_C (0x1b6c1bd87736c31b),
+ U64_C (0xb5eeb5c15b7774b5), U64_C (0xaf86af112943beaf),
+ U64_C (0x6ab56a77dfd41d6a), U64_C (0x505d50ba0da0ea50),
+ U64_C (0x450945124c8a5745), U64_C (0xf3ebf3cb18fb38f3),
+ U64_C (0x30c0309df060ad30), U64_C (0xef9bef2b74c3c4ef),
+ U64_C (0x3ffc3fe5c37eda3f), U64_C (0x554955921caac755),
+ U64_C (0xa2b2a2791059dba2), U64_C (0xea8fea0365c9e9ea),
+ U64_C (0x6589650fecca6a65), U64_C (0xbad2bab9686903ba),
+ U64_C (0x2fbc2f65935e4a2f), U64_C (0xc027c04ee79d8ec0),
+ U64_C (0xde5fdebe81a160de), U64_C (0x1c701ce06c38fc1c),
+ U64_C (0xfdd3fdbb2ee746fd), U64_C (0x4d294d52649a1f4d),
+ U64_C (0x927292e4e0397692), U64_C (0x75c9758fbceafa75),
+ U64_C (0x061806301e0c3606), U64_C (0x8a128a249809ae8a),
+ U64_C (0xb2f2b2f940794bb2), U64_C (0xe6bfe66359d185e6),
+ U64_C (0x0e380e70361c7e0e), U64_C (0x1f7c1ff8633ee71f),
+ U64_C (0x62956237f7c45562), U64_C (0xd477d4eea3b53ad4),
+ U64_C (0xa89aa829324d81a8), U64_C (0x966296c4f4315296),
+ U64_C (0xf9c3f99b3aef62f9), U64_C (0xc533c566f697a3c5),
+ U64_C (0x25942535b14a1025), U64_C (0x597959f220b2ab59),
+ U64_C (0x842a8454ae15d084), U64_C (0x72d572b7a7e4c572),
+ U64_C (0x39e439d5dd72ec39), U64_C (0x4c2d4c5a6198164c),
+ U64_C (0x5e655eca3bbc945e), U64_C (0x78fd78e785f09f78),
+ U64_C (0x38e038ddd870e538), U64_C (0x8c0a8c148605988c),
+ U64_C (0xd163d1c6b2bf17d1), U64_C (0xa5aea5410b57e4a5),
+ U64_C (0xe2afe2434dd9a1e2), U64_C (0x6199612ff8c24e61),
+ U64_C (0xb3f6b3f1457b42b3), U64_C (0x21842115a5423421),
+ U64_C (0x9c4a9c94d625089c), U64_C (0x1e781ef0663cee1e),
+ U64_C (0x4311432252866143), U64_C (0xc73bc776fc93b1c7),
+ U64_C (0xfcd7fcb32be54ffc), U64_C (0x0410042014082404),
+ U64_C (0x515951b208a2e351), U64_C (0x995e99bcc72f2599),
+ U64_C (0x6da96d4fc4da226d), U64_C (0x0d340d68391a650d),
+ U64_C (0xfacffa8335e979fa), U64_C (0xdf5bdfb684a369df),
+ U64_C (0x7ee57ed79bfca97e), U64_C (0x2490243db4481924),
+ U64_C (0x3bec3bc5d776fe3b), U64_C (0xab96ab313d4b9aab),
+ U64_C (0xce1fce3ed181f0ce), U64_C (0x1144118855229911),
+ U64_C (0x8f068f0c8903838f), U64_C (0x4e254e4a6b9c044e),
+ U64_C (0xb7e6b7d1517366b7), U64_C (0xeb8beb0b60cbe0eb),
+ U64_C (0x3cf03cfdcc78c13c), U64_C (0x813e817cbf1ffd81),
+ U64_C (0x946a94d4fe354094), U64_C (0xf7fbf7eb0cf31cf7),
+ U64_C (0xb9deb9a1676f18b9), U64_C (0x134c13985f268b13),
+ U64_C (0x2cb02c7d9c58512c), U64_C (0xd36bd3d6b8bb05d3),
+ U64_C (0xe7bbe76b5cd38ce7), U64_C (0x6ea56e57cbdc396e),
+ U64_C (0xc437c46ef395aac4), U64_C (0x030c03180f061b03),
+ U64_C (0x5645568a13acdc56), U64_C (0x440d441a49885e44),
+ U64_C (0x7fe17fdf9efea07f), U64_C (0xa99ea921374f88a9),
+ U64_C (0x2aa82a4d8254672a), U64_C (0xbbd6bbb16d6b0abb),
+ U64_C (0xc123c146e29f87c1), U64_C (0x535153a202a6f153),
+ U64_C (0xdc57dcae8ba572dc), U64_C (0x0b2c0b582716530b),
+ U64_C (0x9d4e9d9cd327019d), U64_C (0x6cad6c47c1d82b6c),
+ U64_C (0x31c43195f562a431), U64_C (0x74cd7487b9e8f374),
+ U64_C (0xf6fff6e309f115f6), U64_C (0x4605460a438c4c46),
+ U64_C (0xac8aac092645a5ac), U64_C (0x891e893c970fb589),
+ U64_C (0x145014a04428b414), U64_C (0xe1a3e15b42dfbae1),
+ U64_C (0x165816b04e2ca616), U64_C (0x3ae83acdd274f73a),
+ U64_C (0x69b9696fd0d20669), U64_C (0x092409482d124109),
+ U64_C (0x70dd70a7ade0d770), U64_C (0xb6e2b6d954716fb6),
+ U64_C (0xd067d0ceb7bd1ed0), U64_C (0xed93ed3b7ec7d6ed),
+ U64_C (0xcc17cc2edb85e2cc), U64_C (0x4215422a57846842),
+ U64_C (0x985a98b4c22d2c98), U64_C (0xa4aaa4490e55eda4),
+ U64_C (0x28a0285d88507528), U64_C (0x5c6d5cda31b8865c),
+ U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
+ };
+
+\f
+
+static void
+whirlpool_init (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+
+ memset (context, 0, sizeof (*context));
+}
+
+
+/*
+ * Transform block.
+ */
+static void
+whirlpool_transform (whirlpool_context_t *context, const unsigned char *data)
+{
+ whirlpool_block_t data_block;
+ whirlpool_block_t key;
+ whirlpool_block_t state;
+ whirlpool_block_t block;
+ unsigned int r;
+ unsigned int i;
+
+ buffer_to_block (data, data_block, i);
+ block_copy (key, context->hash_state, i);
+ block_copy (state, context->hash_state, i);
+ block_xor (state, data_block, i);
+
+ for (r = 0; r < R; r++)
+ {
+ /* Compute round key K^r. */
+
+ block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^
+ C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^
+ C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^
+ C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]);
+ block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^
+ C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^
+ C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^
+ C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]);
+ block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^
+ C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^
+ C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^
+ C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]);
+ block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^
+ C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^
+ C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^
+ C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]);
+ block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^
+ C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^
+ C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^
+ C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]);
+ block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^
+ C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^
+ C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^
+ C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]);
+ block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^
+ C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^
+ C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^
+ C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]);
+ block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^
+ C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^
+ C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^
+ C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]);
+ block_copy (key, block, i);
+
+ /* Apply r-th round transformation. */
+
+ block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^
+ C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^
+ C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^
+ C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]);
+ block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^
+ C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^
+ C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^
+ C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]);
+ block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^
+ C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^
+ C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^
+ C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]);
+ block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^
+ C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^
+ C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^
+ C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]);
+ block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^
+ C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^
+ C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^
+ C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]);
+ block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^
+ C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^
+ C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^
+ C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]);
+ block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^
+ C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^
+ C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^
+ C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]);
+ block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^
+ C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^
+ C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^
+ C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]);
+ block_copy (state, block, i);
+ }
+
+ /* Compression. */
+
+ block_xor (context->hash_state, data_block, i);
+ block_xor (context->hash_state, state, i);
+}
+
+static void
+whirlpool_add (whirlpool_context_t *context,
+ const void *buffer_arg, size_t buffer_n)
+{
+ const unsigned char *buffer = buffer_arg;
+ u64 buffer_size;
+ unsigned int carry;
+ unsigned int i;
+
+ buffer_size = buffer_n;
+
+ if (context->count == BLOCK_SIZE)
+ {
+ /* Flush the buffer. */
+ whirlpool_transform (context, context->buffer);
+ /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
+ context->count = 0;
+ }
+ if (! buffer)
+ return; /* Nothing to add. */
+
+ if (context->count)
+ {
+ while (buffer_n && (context->count < BLOCK_SIZE))
+ {
+ context->buffer[context->count++] = *buffer++;
+ buffer_n--;
+ }
+ whirlpool_add (context, NULL, 0);
+ if (!buffer_n)
+ /* Done. */
+ return;
+ }
+ /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
+
+ while (buffer_n >= BLOCK_SIZE)
+ {
+ whirlpool_transform (context, buffer);
+ context->count = 0;
+ buffer_n -= BLOCK_SIZE;
+ buffer += BLOCK_SIZE;
+ }
+ while (buffer_n && (context->count < BLOCK_SIZE))
+ {
+ context->buffer[context->count++] = *buffer++;
+ buffer_n--;
+ }
+
+ /* Update bit counter. */
+ carry = 0;
+ buffer_size <<= 3;
+ for (i = 1; i <= 32; i++)
+ {
+ if (! (buffer_size || carry))
+ break;
+
+ carry += context->length[32 - i] + (buffer_size & 0xFF);
+ context->length[32 - i] = carry;
+ buffer_size >>= 8;
+ carry >>= 8;
+ }
+ gcry_assert (! (buffer_size || carry));
+}
+
+static void
+whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
+{
+ whirlpool_context_t *context = ctx;
+
+ whirlpool_add (context, buffer, buffer_n);
+}
+
+static void
+whirlpool_final (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+ unsigned int i;
+
+ /* Flush. */
+ whirlpool_add (context, NULL, 0);
+
+ /* Pad. */
+ context->buffer[context->count++] = 0x80;
+
+ if (context->count > 32)
+ {
+ /* An extra block is necessary. */
+ while (context->count < 64)
+ context->buffer[context->count++] = 0;
+ whirlpool_add (context, NULL, 0);
+ }
+ while (context->count < 32)
+ context->buffer[context->count++] = 0;
+
+ /* Add length of message. */
+ memcpy (context->buffer + context->count, context->length, 32);
+ context->count += 32;
+ whirlpool_add (context, NULL, 0);
+
+ block_to_buffer (context->buffer, context->hash_state, i);
+}
+
+static byte *
+whirlpool_read (void *ctx)
+{
+ whirlpool_context_t *context = ctx;
+
+ return context->buffer;
+}
+
+gcry_md_spec_t _gcry_digest_spec_whirlpool =
+ {
+ "WHIRLPOOL", NULL, 0, NULL, 64,
+ whirlpool_init, whirlpool_write, whirlpool_final, whirlpool_read,
+ sizeof (whirlpool_context_t)
+ };
--- /dev/null
+# Makefile for compat directory
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+# We use this libcompat to work around problems with LIBOBJ stuff.
+# For example, we need some of the compat files also in tests/ but the
+# suggested way to do this (using the automake option subdir-objects)
+# leads to problems with "make distclean": The distclean target in
+# tests is run before the one src and it removes the deps files of the
+# libobj files which are in src. Now when it comes to run make in src
+# the icnluded files are gone - bummer. Instead of try to fix this
+# issue it seems better not to use subdir-objects but build them all
+# into a compat library and always link against that library. This
+# also avoids the problem that a dependency on LTLIBOBJ is not setup
+# if -- disable-static was used.
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src $(GPG_ERROR_CFLAGS)
+
+noinst_LTLIBRARIES = libcompat.la
+
+# We only need one file so that the library is guaranteed to have at
+# least one member.
+libcompat_la_SOURCES = compat.c libcompat.h
+libcompat_la_DEPENDENCIES = @LTLIBOBJS@
+libcompat_la_LIBADD = @LTLIBOBJS@
+
+# AC_LIBOBJ files are:
+# getpid.c
+# clock.c
+#
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for compat directory
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+# We use this libcompat to work around problems with LIBOBJ stuff.
+# For example, we need some of the compat files also in tests/ but the
+# suggested way to do this (using the automake option subdir-objects)
+# leads to problems with "make distclean": The distclean target in
+# tests is run before the one src and it removes the deps files of the
+# libobj files which are in src. Now when it comes to run make in src
+# the icnluded files are gone - bummer. Instead of try to fix this
+# issue it seems better not to use subdir-objects but build them all
+# into a compat library and always link against that library. This
+# also avoids the problem that a dependency on LTLIBOBJ is not setup
+# if -- disable-static was used.
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = compat
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in clock.c \
+ getpid.c
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am_libcompat_la_OBJECTS = compat.lo
+libcompat_la_OBJECTS = $(am_libcompat_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libcompat_la_SOURCES)
+DIST_SOURCES = $(libcompat_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src $(GPG_ERROR_CFLAGS)
+noinst_LTLIBRARIES = libcompat.la
+
+# We only need one file so that the library is guaranteed to have at
+# least one member.
+libcompat_la_SOURCES = compat.c libcompat.h
+libcompat_la_DEPENDENCIES = @LTLIBOBJS@
+libcompat_la_LIBADD = @LTLIBOBJS@
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu compat/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu compat/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES)
+ $(LINK) $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/clock.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getpid.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf $(DEPDIR) ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf $(DEPDIR) ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# AC_LIBOBJ files are:
+# getpid.c
+# clock.c
+#
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* clock.c - Replacement for WindowsCE
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#include <windows.h>
+#include <time.h>
+#include <assert.h>
+
+clock_t
+_gcry_clock (void)
+{
+ assert (CLOCKS_PER_SEC == 1000);
+#warning Replace by a correct implementaion.
+ /* It seems that GetProcessTimes is available in the kernel but
+ without a declaration. If that fails we would need to walk over
+ all threads and tally up the GetThreadTimes. */
+
+ return GetTickCount ();
+}
+
+#else
+# error No replacement function for clock known
+#endif
--- /dev/null
+/* compat.c - Dummy file to avoid an empty library.
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "../src/g10lib.h"
+
+
+const char *
+_gcry_compat_identification (void)
+{
+ static const char blurb[] =
+ "\n\n"
+ "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n"
+ "Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,\n"
+ " 2010, 2011 Free Software Foundation, Inc.\n"
+ "\n\n";
+ return blurb;
+}
--- /dev/null
+/* getpid.c - Replacement for WindowsCE
+ Copyright (C) 2010 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ PURPOSE. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_W32CE_SYSTEM
+#include <windows.h>
+#include <sys/types.h>
+
+pid_t
+_gcry_getpid (void)
+{
+ return GetCurrentProcessId ();
+}
+
+#else
+# error No replacement function for getpid known
+#endif
--- /dev/null
+/* libcomapt.h - Prototypes for AC_REPLACE_FUNCtions.
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_LIBCOMPAT_H
+#define GCRY_LIBCOMPAT_H
+
+const char *_gcry_compat_identification (void);
+
+
+#ifndef HAVE_GETPID
+pid_t _gcry_getpid (void);
+#define getpid() _gcry_getpid ()
+#endif
+
+#ifndef HAVE_CLOCK
+clock_t _gcry_clock (void);
+#define clock() _gcry_clock ()
+#endif
+
+
+#endif /*GCRY_LIBCOMPAT_H*/
--- /dev/null
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2005-05-14.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "compile $scriptversion"
+ exit $?
+ ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+ if test -n "$eat"; then
+ eat=
+ else
+ case $1 in
+ -o)
+ # configure might choose to run compile as `compile cc -o foo foo.c'.
+ # So we strip `-o arg' only if arg is an object.
+ eat=1
+ case $2 in
+ *.o | *.obj)
+ ofile=$2
+ ;;
+ *)
+ set x "$@" -o "$2"
+ shift
+ ;;
+ esac
+ ;;
+ *.c)
+ cfile=$1
+ set x "$@" "$1"
+ shift
+ ;;
+ *)
+ set x "$@" "$1"
+ shift
+ ;;
+ esac
+ fi
+ shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+ # If no `-o' option was seen then we might have been invoked from a
+ # pattern rule where we don't need one. That is ok -- this is a
+ # normal compilation that the losing compiler can handle. If no
+ # `.c' file was seen then we are probably linking. That is also
+ # ok.
+ exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file. Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+ if mkdir "$lockdir" >/dev/null 2>&1; then
+ break
+ fi
+ sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+ mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+ mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-06-03'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm:riscos:*:*|arm:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ case ${UNAME_MACHINE} in
+ pc98)
+ echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ cris:Linux:*:*)
+ echo cris-axis-linux-gnu
+ exit ;;
+ crisv32:Linux:*:*)
+ echo crisv32-axis-linux-gnu
+ exit ;;
+ frv:Linux:*:*)
+ echo frv-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ ;;
+ or32:Linux:*:*)
+ echo or32-unknown-linux-gnu
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-gnu
+ exit ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
+ unknown) UNAME_PROCESSOR=powerpc ;;
+ esac
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-?:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ c34*)
+ echo c34-convex-bsd
+ exit ;;
+ c38*)
+ echo c38-convex-bsd
+ exit ;;
+ c4*)
+ echo c4-convex-bsd
+ exit ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+#define _GCRYPT_CONFIG_H_INCLUDED
+
+/* Enable gpg-error's strerror macro for W32CE. */
+#define GPG_ERR_ENABLE_ERRNO_MACROS 1
+
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Subversion revision used to build this package */
+#undef BUILD_REVISION
+
+/* configure did not test for endianess */
+#undef DISABLED_ENDIAN_CHECK
+
+/* Define if you don't want the default EGD socket name. For details see
+ cipher/rndegd.c */
+#undef EGD_SOCKET_NAME
+
+/* Enable support for Intel AES-NI instructions. */
+#undef ENABLE_AESNI_SUPPORT
+
+/* Define to support an HMAC based integrity check */
+#undef ENABLE_HMAC_BINARY_CHECK
+
+/* Enable support for the PadLock engine. */
+#undef ENABLE_PADLOCK_SUPPORT
+
+/* Define to use the GNU C visibility attribute. */
+#undef GCRY_USE_VISIBILITY
+
+/* The default error source for libgcrypt. */
+#undef GPG_ERR_SOURCE_DEFAULT
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Defined if the mlock() call does not work */
+#undef HAVE_BROKEN_MLOCK
+
+/* Defined if a `byte' is typedef'd */
+#undef HAVE_BYTE_TYPEDEF
+
+/* Define to 1 if you have the `clock' function. */
+#undef HAVE_CLOCK
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#undef HAVE_CLOCK_GETTIME
+
+/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
+ don't. */
+#undef HAVE_DECL_SYS_SIGLIST
+
+/* defined if the system supports a random device */
+#undef HAVE_DEV_RANDOM
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+#undef HAVE_DOPRNT
+
+/* defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2)
+ with special properties like no file modes */
+#undef HAVE_DOSISH_SYSTEM
+
+/* defined if we must run on a stupid file system */
+#undef HAVE_DRIVE_LETTERS
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `gethrtime' function. */
+#undef HAVE_GETHRTIME
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getpid' function. */
+#undef HAVE_GETPID
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+#undef HAVE_LIBRT
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Defined if the system supports an mlock() call */
+#undef HAVE_MLOCK
+
+/* Define to 1 if you have the `mmap' function. */
+#undef HAVE_MMAP
+
+/* Defined if the GNU Pth is available */
+#undef HAVE_PTH
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `rand' function. */
+#undef HAVE_RAND
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `stpcpy' function. */
+#undef HAVE_STPCPY
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `stricmp' function. */
+#undef HAVE_STRICMP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the `syslog' function. */
+#undef HAVE_SYSLOG
+
+/* Define to 1 if you have the <sys/capability.h> header file. */
+#undef HAVE_SYS_CAPABILITY_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/msg.h> header file. */
+#undef HAVE_SYS_MSG_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Defined if a `u16' is typedef'd */
+#undef HAVE_U16_TYPEDEF
+
+/* Defined if a `u32' is typedef'd */
+#undef HAVE_U32_TYPEDEF
+
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
+/* Defined if a `ulong' is typedef'd */
+#undef HAVE_ULONG_TYPEDEF
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Defined if a `ushort' is typedef'd */
+#undef HAVE_USHORT_TYPEDEF
+
+/* Define to 1 if you have the `vprintf' function. */
+#undef HAVE_VPRINTF
+
+/* Defined if we run on WindowsCE */
+#undef HAVE_W32CE_SYSTEM
+
+/* Defined if we run on a W32 API based system */
+#undef HAVE_W32_SYSTEM
+
+/* Define to 1 if you have the `wait4' function. */
+#undef HAVE_WAIT4
+
+/* Define to 1 if you have the `waitpid' function. */
+#undef HAVE_WAITPID
+
+/* Define to 1 if you have the <winsock2.h> header file. */
+#undef HAVE_WINSOCK2_H
+
+/* Define to 1 if you have the <ws2tcpip.h> header file. */
+#undef HAVE_WS2TCPIP_H
+
+/* Defined if this is not a regular release */
+#undef IS_DEVELOPMENT_VERSION
+
+/* List of available cipher algorithms */
+#undef LIBGCRYPT_CIPHERS
+
+/* List of available digest algorithms */
+#undef LIBGCRYPT_DIGESTS
+
+/* List of available public key cipher algorithms */
+#undef LIBGCRYPT_PUBKEY_CIPHERS
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LT_OBJDIR
+
+/* Define to use the (obsolete) malloc guarding feature */
+#undef M_GUARD
+
+/* defined to the name of the strong random device */
+#undef NAME_OF_DEV_RANDOM
+
+/* defined to the name of the weaker random device */
+#undef NAME_OF_DEV_URANDOM
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+#undef NO_MINUS_C_MINUS_O
+
+/* Name of this package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* A human readable text with the name of the OS */
+#undef PRINTABLE_OS_NAME
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* The size of `unsigned int', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_INT
+
+/* The size of `unsigned long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG
+
+/* The size of `unsigned long long', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_LONG_LONG
+
+/* The size of `unsigned short', as computed by sizeof. */
+#undef SIZEOF_UNSIGNED_SHORT
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Defined if this module should be included */
+#undef USE_AES
+
+/* Defined if this module should be included */
+#undef USE_ARCFOUR
+
+/* Defined if this module should be included */
+#undef USE_BLOWFISH
+
+/* Defined if this module should be included */
+#undef USE_CAMELLIA
+
+/* define if capabilities should be used */
+#undef USE_CAPABILITIES
+
+/* Defined if this module should be included */
+#undef USE_CAST5
+
+/* Defined if this module should be included */
+#undef USE_CRC
+
+/* Defined if this module should be included */
+#undef USE_DES
+
+/* Defined if this module should be included */
+#undef USE_DSA
+
+/* Defined if this module should be included */
+#undef USE_ECC
+
+/* Defined if this module should be included */
+#undef USE_ELGAMAL
+
+/* Defined if the GNU Portable Thread Library should be used */
+#undef USE_GNU_PTH
+
+/* Defined if this module should be included */
+#undef USE_MD4
+
+/* Defined if this module should be included */
+#undef USE_MD5
+
+/* set this to limit filenames to the 8.3 format */
+#undef USE_ONLY_8DOT3
+
+/* Define to support the experimental random daemon */
+#undef USE_RANDOM_DAEMON
+
+/* Defined if this module should be included */
+#undef USE_RFC2268
+
+/* Defined if this module should be included */
+#undef USE_RMD160
+
+/* Defined if the EGD based RNG should be used. */
+#undef USE_RNDEGD
+
+/* Defined if the /dev/random RNG should be used. */
+#undef USE_RNDLINUX
+
+/* Defined if the default Unix RNG should be used. */
+#undef USE_RNDUNIX
+
+/* Defined if the Windows specific RNG should be used. */
+#undef USE_RNDW32
+
+/* Defined if the WindowsCE specific RNG should be used. */
+#undef USE_RNDW32CE
+
+/* Defined if this module should be included */
+#undef USE_RSA
+
+/* Defined if this module should be included */
+#undef USE_SEED
+
+/* Defined if this module should be included */
+#undef USE_SERPENT
+
+/* Defined if this module should be included */
+#undef USE_SHA1
+
+/* Defined if this module should be included */
+#undef USE_SHA256
+
+/* Defined if this module should be included */
+#undef USE_SHA512
+
+/* Enable extensions on AIX 3, Interix. */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them. */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris. */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop. */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris. */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Defined if this module should be included */
+#undef USE_TIGER
+
+/* Defined if this module should be included */
+#undef USE_TWOFISH
+
+/* Defined if this module should be included */
+#undef USE_WHIRLPOOL
+
+/* Version of this package */
+#undef VERSION
+
+/* Defined if compiled symbols have a leading underscore */
+#undef WITH_SYMBOL_UNDERSCORE
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+# undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+ this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* To allow the use of Libgcrypt in multithreaded programs we have to use
+ special features from the library. */
+#ifndef _REENTRANT
+# define _REENTRANT 1
+#endif
+
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* type to use in place of socklen_t if not defined */
+#undef socklen_t
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+ pointer, if such a type exists, and if the system does not define it. */
+#undef uintptr_t
+
+
+#define _GCRYPT_IN_LIBGCRYPT 1
+
+/* If the configure check for endianness has been disabled, get it from
+ OS macros. This is intended for making fat binary builds on OS X. */
+#ifdef DISABLED_ENDIAN_CHECK
+# if defined(__BIG_ENDIAN__)
+# define WORDS_BIGENDIAN 1
+# elif defined(__LITTLE_ENDIAN__)
+# undef WORDS_BIGENDIAN
+# else
+# error "No endianness found"
+# endif
+#endif /*DISABLED_ENDIAN_CHECK*/
+
+/* We basically use the original Camellia source. Make sure the symbols
+ properly prefixed. */
+#define CAMELLIA_EXT_SYM_PREFIX _gcry_
+
+/* This error code is only available with gpg-error 1.7. Thus
+ we define it here with the usual gcry prefix. */
+#define GCRY_GPG_ERR_NOT_OPERATIONAL 176
+
+
+#endif /*_GCRYPT_CONFIG_H_INCLUDED*/
+
--- /dev/null
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2007 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ icc* | ecc*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix3* | aix4* | aix5*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix4* | aix5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011 Free Software Foundation, Inc.
+
+timestamp='2011-06-03'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>. Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
+Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 \
+ | ns16k | ns32k \
+ | open8 \
+ | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -kaos*)
+ os=-kaos
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null
+#! /bin/sh
+# From configure.ac Revision.
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64 for libgcrypt 1.5.0.
+#
+# Report bugs to <bug-libgcrypt@gnupg.org>.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+$0: bug-libgcrypt@gnupg.org about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+$*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='libgcrypt'
+PACKAGE_TARNAME='libgcrypt'
+PACKAGE_VERSION='1.5.0'
+PACKAGE_STRING='libgcrypt 1.5.0'
+PACKAGE_BUGREPORT='bug-libgcrypt@gnupg.org'
+PACKAGE_URL=''
+
+ac_unique_file="src/libgcrypt.vers"
+ac_config_libobj_dir=compat
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+BUILD_FILEVERSION
+BUILD_TIMESTAMP
+BUILD_REVISION
+LIBGCRYPT_DIGESTS
+LIBGCRYPT_PUBKEY_CIPHERS
+LIBGCRYPT_CIPHERS
+GCRYPT_RANDOM
+GCRYPT_DIGESTS
+GCRYPT_PUBKEY_CIPHERS
+GCRYPT_CIPHERS
+LIBGCRYPT_THREAD_MODULES
+LIBGCRYPT_CONFIG_HOST
+LIBGCRYPT_CONFIG_CFLAGS
+LIBGCRYPT_CONFIG_LIBS
+LIBGCRYPT_CONFIG_API_VERSION
+NOEXECSTACK_FLAGS
+CROSS_COMPILING_FALSE
+CROSS_COMPILING_TRUE
+MPI_MOD_C_UDIV_QRNND_FALSE
+MPI_MOD_C_UDIV_QRNND_TRUE
+MPI_MOD_C_UDIV_FALSE
+MPI_MOD_C_UDIV_TRUE
+MPI_MOD_C_MPIH_RSHIFT_FALSE
+MPI_MOD_C_MPIH_RSHIFT_TRUE
+MPI_MOD_C_MPIH_LSHIFT_FALSE
+MPI_MOD_C_MPIH_LSHIFT_TRUE
+MPI_MOD_C_MPIH_MUL3_FALSE
+MPI_MOD_C_MPIH_MUL3_TRUE
+MPI_MOD_C_MPIH_MUL2_FALSE
+MPI_MOD_C_MPIH_MUL2_TRUE
+MPI_MOD_C_MPIH_MUL1_FALSE
+MPI_MOD_C_MPIH_MUL1_TRUE
+MPI_MOD_C_MPIH_SUB1_FALSE
+MPI_MOD_C_MPIH_SUB1_TRUE
+MPI_MOD_C_MPIH_ADD1_FALSE
+MPI_MOD_C_MPIH_ADD1_TRUE
+MPI_MOD_ASM_UDIV_QRNND_FALSE
+MPI_MOD_ASM_UDIV_QRNND_TRUE
+MPI_MOD_ASM_UDIV_FALSE
+MPI_MOD_ASM_UDIV_TRUE
+MPI_MOD_ASM_MPIH_RSHIFT_FALSE
+MPI_MOD_ASM_MPIH_RSHIFT_TRUE
+MPI_MOD_ASM_MPIH_LSHIFT_FALSE
+MPI_MOD_ASM_MPIH_LSHIFT_TRUE
+MPI_MOD_ASM_MPIH_MUL3_FALSE
+MPI_MOD_ASM_MPIH_MUL3_TRUE
+MPI_MOD_ASM_MPIH_MUL2_FALSE
+MPI_MOD_ASM_MPIH_MUL2_TRUE
+MPI_MOD_ASM_MPIH_MUL1_FALSE
+MPI_MOD_ASM_MPIH_MUL1_TRUE
+MPI_MOD_ASM_MPIH_SUB1_FALSE
+MPI_MOD_ASM_MPIH_SUB1_TRUE
+MPI_MOD_ASM_MPIH_ADD1_FALSE
+MPI_MOD_ASM_MPIH_ADD1_TRUE
+MPI_SFLAGS
+DL_LIBS
+LIBOBJS
+FALLBACK_SOCKLEN_T
+SYS_SOCKET_H
+INSERT_SYS_SELECT_H
+PTH_LIBS
+PTH_CFLAGS
+PTH_CONFIG
+GPG_ERROR_LIBS
+GPG_ERROR_CFLAGS
+GPG_ERROR_CONFIG
+HAVE_LD_VERSION_SCRIPT_FALSE
+HAVE_LD_VERSION_SCRIPT_TRUE
+ENABLE_O_FLAG_MUNGING_FALSE
+ENABLE_O_FLAG_MUNGING_TRUE
+USE_RANDOM_DAEMON_FALSE
+USE_RANDOM_DAEMON_TRUE
+emacs_local_vars_end
+emacs_local_vars_read_only
+emacs_local_vars_begin
+HAVE_W32CE_SYSTEM_FALSE
+HAVE_W32CE_SYSTEM_TRUE
+HAVE_W32_SYSTEM_FALSE
+HAVE_W32_SYSTEM_TRUE
+RC
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+lt_ECHO
+RANLIB
+AR
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+OBJDUMP
+DLLTOOL
+AS
+EGREP
+GREP
+am__fastdepCCAS_FALSE
+am__fastdepCCAS_TRUE
+CCASDEPMODE
+CCASFLAGS
+CCAS
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+LIBGCRYPT_LT_REVISION
+LIBGCRYPT_LT_AGE
+LIBGCRYPT_LT_CURRENT
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_maintainer_mode
+enable_dependency_tracking
+enable_static
+enable_shared
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+enable_endian_check
+enable_ciphers
+enable_pubkey_ciphers
+enable_digests
+enable_random
+enable_dev_random
+with_egd_socket
+enable_random_daemon
+enable_asm
+enable_m_guard
+with_capabilities
+enable_hmac_binary_check
+enable_padlock_support
+enable_aesni_support
+enable_O_flag_munging
+enable_ld_version_script
+with_gpg_error_prefix
+with_pth_prefix
+enable_mpi_path
+enable_optimization
+enable_noexecstack
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CCAS
+CCASFLAGS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures libgcrypt 1.5.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/libgcrypt]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of libgcrypt 1.5.0:";;
+ esac
+ cat <<\_ACEOF
+
+Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-static[=PKGS] build static libraries [default=no]
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-endian-check disable the endian check and trust the OS provided
+ macros
+ --enable-ciphers=ciphers
+ select the symmetric ciphers to include
+ --enable-pubkey-ciphers=ciphers
+ select the public-key ciphers to include
+ --enable-digests=digests
+ select the message digests to include
+ --enable-random=name select which random number generator to use
+ --disable-dev-random disable the use of dev random
+ --enable-random-daemon Build and support the experimental gcryptrnd
+ --disable-asm Disable MPI assembler modules
+ --enable-m-guard Enable memory guard facility
+ --enable-hmac-binary-check
+ Enable library integrity check
+ --disable-padlock-support
+ Disable support for the PadLock Engine of VIA
+ processors
+ --disable-aesni-support Disable support for the Intel AES-NI instructions
+ --disable-O-flag-munging
+ Disable modification of the cc -O flag
+ --enable-ld-version-script
+ enable/disable use of linker version script.
+ (default is system dependent)
+ --enable-mpi-path=EXTRA_PATH
+ prepend EXTRA_PATH to list of CPU specific
+ optimizations
+ --disable-optimization disable compiler optimization
+ --disable-noexecstack disable non executable stack support
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+ --with-egd-socket=NAME Use NAME for the EGD socket)
+ --with-capabilities Use linux capabilities default=no
+ --with-gpg-error-prefix=PFX
+ prefix where GPG Error is installed (optional)
+ --with-pth-prefix=PFX prefix where GNU Pth is installed (optional)
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
+ CCAS assembler compiler command (defaults to CC)
+ CCASFLAGS assembler compiler flags (defaults to CFLAGS)
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <bug-libgcrypt@gnupg.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+libgcrypt configure 1.5.0
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( cat <<\_ASBOX
+## -------------------------------------- ##
+## Report this to bug-libgcrypt@gnupg.org ##
+## -------------------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if test "$cross_compiling" = yes; then
+ # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=0 ac_mid=0
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid; break
+else
+ as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+ if test $ac_lo -le $ac_mid; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=-1 ac_mid=-1
+ while :; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_lo=$ac_mid; break
+else
+ as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+ if test $ac_mid -le $ac_hi; then
+ ac_lo= ac_hi=
+ break
+ fi
+ as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+else
+ ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+ as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_hi=$ac_mid
+else
+ as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+ else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+ FILE *f = fopen ("conftest.val", "w");
+ if (! f)
+ return 1;
+ if (($2) < 0)
+ {
+ long int i = longval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%ld", i);
+ }
+ else
+ {
+ unsigned long int i = ulongval ();
+ if (i != ($2))
+ return 1;
+ fprintf (f, "%lu", i);
+ }
+ /* Do not output a trailing newline, as this causes \r\n confusion
+ on some platforms. */
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+ ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+ fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+#ifndef $2
+ (void) $2;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libgcrypt $as_me 1.5.0, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# LT Version numbers, remember to change them just *before* a release.
+# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
+# (Interfaces added: CURRENT++, AGE++, REVISION=0)
+# (No interfaces changed: REVISION++)
+LIBGCRYPT_LT_CURRENT=18
+LIBGCRYPT_LT_AGE=7
+LIBGCRYPT_LT_REVISION=0
+
+
+# If the API is changed in an incompatible way: increment the next counter.
+LIBGCRYPT_CONFIG_API_VERSION=1
+
+NEED_GPG_ERROR_VERSION=1.8
+
+is_development_version=no
+
+BUILD_REVISION=41756
+PACKAGE=$PACKAGE_NAME
+VERSION=$PACKAGE_VERSION
+
+
+am__api_version='1.11'
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libgcrypt'
+ VERSION='1.5.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+
+
+######################
+## Basic checks. ### (we need some results later on (e.g. $GCC)
+######################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+missing_dir=`cd $ac_aux_dir && pwd`
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+# AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+if test "x$CC" != xcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+then
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&5'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } &&
+ test -f conftest2.$ac_objext && { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; };
+ then
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
+# By default we simply use the C compiler to build assembly code.
+
+test "${CCAS+set}" = set || CCAS=$CC
+test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
+
+
+
+depcc="$CCAS" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CCAS_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+
+ am_cv_CCAS_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+
+
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CCAS_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CCAS_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CCAS_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CCAS_dependencies_compiler_type" >&6; }
+CCASDEPMODE=depmode=$am_cv_CCAS_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CCAS_dependencies_compiler_type" = gcc3; then
+ am__fastdepCCAS_TRUE=
+ am__fastdepCCAS_FALSE='#'
+else
+ am__fastdepCCAS_TRUE='#'
+ am__fastdepCCAS_FALSE=
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
+$as_echo_n "checking for library containing strerror... " >&6; }
+if test "${ac_cv_search_strerror+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char strerror ();
+int
+main ()
+{
+return strerror ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' cposix; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_strerror=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_strerror+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_strerror+set}" = set; then :
+
+else
+ ac_cv_search_strerror=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_strerror" >&5
+$as_echo "$ac_cv_search_strerror" >&6; }
+ac_res=$ac_cv_search_strerror
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+for ac_prog in gawk mawk nawk awk
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AWK="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6b'
+macro_revision='1.3017'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:5678: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:5681: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:5684: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AR="${ac_tool_prefix}ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AR="ar"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_STRIP="strip"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RANLIB="ranlib"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 6886 "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_NMEDIT="nmedit"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_LIPO="lipo"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL="otool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OTOOL64="otool64"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Set options
+enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AS+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_AS="${ac_tool_prefix}as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AS+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_AS="as"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DLLTOOL"; then
+ ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+ ac_ct_DLLTOOL=$DLLTOOL
+ # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DLLTOOL"; then
+ ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_DLLTOOL="dlltool"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DLLTOOL" = x; then
+ DLLTOOL="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ DLLTOOL=$ac_ct_DLLTOOL
+ fi
+else
+ DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_OBJDUMP="objdump"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+ ;;
+esac
+
+test -z "$AS" && AS=as
+
+
+
+
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+# Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=no
+fi
+
+
+
+
+
+
+
+
+
+
+ enable_dlopen=no
+
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:8445: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:8449: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:8784: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:8788: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:8889: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:8893: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:8944: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:8948: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ link_all_deplibs=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ link_all_deplibs=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ whole_archive_flag_spec=''
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ archive_cmds_need_lc=no
+ else
+ archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[123]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 11327 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 11423 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}windres", so it can be a program name with args.
+set dummy ${ac_tool_prefix}windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RC"; then
+ ac_cv_prog_RC="$RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_RC="${ac_tool_prefix}windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+RC=$ac_cv_prog_RC
+if test -n "$RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RC" >&5
+$as_echo "$RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RC"; then
+ ac_ct_RC=$RC
+ # Extract the first word of "windres", so it can be a program name with args.
+set dummy windres; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RC"; then
+ ac_cv_prog_ac_ct_RC="$ac_ct_RC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_RC="windres"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RC=$ac_cv_prog_ac_ct_RC
+if test -n "$ac_ct_RC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RC" >&5
+$as_echo "$ac_ct_RC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RC" = x; then
+ RC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RC=$ac_ct_RC
+ fi
+else
+ RC="$ac_cv_prog_RC"
+fi
+
+
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+compiler_RC=$CC
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+lt_cv_prog_compiler_c_o_RC=yes
+
+if test -n "$compiler"; then
+ :
+
+
+
+fi
+
+GCC=$lt_save_GCC
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+CC="$lt_save_CC"
+
+
+
+##########################
+## General definitions. ##
+##########################
+
+# Used by libgcrypt-config
+LIBGCRYPT_CONFIG_LIBS="-lgcrypt"
+LIBGCRYPT_CONFIG_CFLAGS=""
+LIBGCRYPT_CONFIG_HOST="$host"
+
+# Definitions for symmetric ciphers.
+available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
+available_ciphers="$available_ciphers camellia"
+enabled_ciphers=""
+
+# Definitions for public-key ciphers.
+available_pubkey_ciphers="dsa elgamal rsa ecc"
+enabled_pubkey_ciphers=""
+
+# Definitions for message digests.
+available_digests="crc md4 md5 rmd160 sha1 sha256"
+available_digests_64="sha512 tiger whirlpool"
+enabled_digests=""
+
+# Definitions for random modules.
+available_random_modules="linux egd unix"
+auto_random_modules="$available_random_modules"
+
+# Supported thread backends.
+LIBGCRYPT_THREAD_MODULES=""
+
+# Other definitions.
+print_egd_notice=no
+have_w32_system=no
+have_w32ce_system=no
+
+# Setup some stuff depending on host.
+case "${host}" in
+ *-*-mingw32*)
+ ac_cv_have_dev_random=no
+ have_w32_system=yes
+ case "${host}" in
+ *-mingw32ce*)
+ have_w32ce_system=yes
+ available_random_modules="w32ce"
+ ;;
+ *)
+ available_random_modules="w32"
+ ;;
+ esac
+
+$as_echo "#define USE_ONLY_8DOT3 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx)
+ # OS/2 with the EMX environment
+ ac_cv_have_dev_random=no
+ $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+ $as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ # DOS with the DJGPP environment
+ ac_cv_have_dev_random=no
+ $as_echo "#define HAVE_DRIVE_LETTERS 1" >>confdefs.h
+
+ $as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
+
+ ;;
+
+ *-*-freebsd*)
+ # FreeBSD
+ CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib"
+ ;;
+
+ *-*-hpux*)
+ if test -z "$GCC" ; then
+ CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+ fi
+ ;;
+ *-dec-osf4*)
+ if test -z "$GCC" ; then
+ # Suppress all warnings
+ # to get rid of the unsigned/signed char mismatch warnings.
+ CFLAGS="$CFLAGS -w"
+ fi
+ ;;
+ m68k-atari-mint)
+ ;;
+ *)
+ ;;
+esac
+
+if test "$have_w32_system" = yes; then
+
+$as_echo "#define HAVE_W32_SYSTEM 1" >>confdefs.h
+
+ if test "$have_w32ce_system" = yes; then
+
+$as_echo "#define HAVE_W32CE_SYSTEM 1" >>confdefs.h
+
+ fi
+fi
+ if test "$have_w32_system" = yes; then
+ HAVE_W32_SYSTEM_TRUE=
+ HAVE_W32_SYSTEM_FALSE='#'
+else
+ HAVE_W32_SYSTEM_TRUE='#'
+ HAVE_W32_SYSTEM_FALSE=
+fi
+
+ if test "$have_w32ce_system" = yes; then
+ HAVE_W32CE_SYSTEM_TRUE=
+ HAVE_W32CE_SYSTEM_FALSE='#'
+else
+ HAVE_W32CE_SYSTEM_TRUE='#'
+ HAVE_W32CE_SYSTEM_FALSE=
+fi
+
+
+
+
+# A printable OS Name is sometimes useful.
+case "${host}" in
+ *-*-mingw32ce*)
+ PRINTABLE_OS_NAME="W32CE"
+ ;;
+
+ *-*-mingw32*)
+ PRINTABLE_OS_NAME="W32"
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx )
+ PRINTABLE_OS_NAME="OS/2"
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ PRINTABLE_OS_NAME="MSDOS/DJGPP"
+ ;;
+
+ *-linux*)
+ PRINTABLE_OS_NAME="GNU/Linux"
+ ;;
+
+ *)
+ PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
+ ;;
+esac
+
+#
+# Figure out the name of the random device
+#
+case "${host}" in
+ *-openbsd*)
+ NAME_OF_DEV_RANDOM="/dev/srandom"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+
+ *)
+ NAME_OF_DEV_RANDOM="/dev/random"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+esac
+
+
+# Check whether --enable-endian-check was given.
+if test "${enable_endian_check+set}" = set; then :
+ enableval=$enable_endian_check; endiancheck=$enableval
+else
+ endiancheck=yes
+fi
+
+if test x"$endiancheck" = xyes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if test "${ac_cv_c_bigendian+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
+
+int
+main ()
+{
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ ac_cv_c_bigendian=no
+else
+ ac_cv_c_bigendian=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
+
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
+
+else
+
+$as_echo "#define DISABLED_ENDIAN_CHECK 1" >>confdefs.h
+
+fi
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
+$as_echo_n "checking size of unsigned short... " >&6; }
+if test "${ac_cv_sizeof_unsigned_short+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_short" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned short)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_unsigned_short=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_short" >&5
+$as_echo "$ac_cv_sizeof_unsigned_short" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_SHORT $ac_cv_sizeof_unsigned_short
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
+$as_echo_n "checking size of unsigned int... " >&6; }
+if test "${ac_cv_sizeof_unsigned_int+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_int" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned int)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_unsigned_int=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_int" >&5
+$as_echo "$ac_cv_sizeof_unsigned_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_INT $ac_cv_sizeof_unsigned_int
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
+$as_echo_n "checking size of unsigned long... " >&6; }
+if test "${ac_cv_sizeof_unsigned_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_unsigned_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
+_ACEOF
+
+
+# The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
+$as_echo_n "checking size of unsigned long long... " >&6; }
+if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long" "$ac_includes_default"; then :
+
+else
+ if test "$ac_cv_type_unsigned_long_long" = yes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+ else
+ ac_cv_sizeof_unsigned_long_long=0
+ fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long_long" >&5
+$as_echo "$ac_cv_sizeof_unsigned_long_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UNSIGNED_LONG_LONG $ac_cv_sizeof_unsigned_long_long
+_ACEOF
+
+
+
+
+ ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
+
+else
+ for ac_type in 'unsigned int' 'unsigned long int' \
+ 'unsigned long long int'; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define uintptr_t $ac_type
+_ACEOF
+
+ ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test -z "$ac_type" && break
+ done
+fi
+
+
+
+if test "$ac_cv_sizeof_unsigned_short" = "0" \
+ || test "$ac_cv_sizeof_unsigned_int" = "0" \
+ || test "$ac_cv_sizeof_unsigned_long" = "0"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&5
+$as_echo "$as_me: WARNING: Hmmm, something is wrong with the sizes - using defaults" >&2;};
+fi
+
+# Do we have any 64-bit data types?
+if test "$ac_cv_sizeof_unsigned_int" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
+ && test "$ac_cv_sizeof_uint64_t" != "8"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No 64-bit types. Disabling TIGER/192, SHA-384, and SHA-512" >&5
+$as_echo "$as_me: WARNING: No 64-bit types. Disabling TIGER/192, SHA-384, and SHA-512" >&2;}
+else
+ available_digests="$available_digests $available_digests_64"
+fi
+
+# If not specified otherwise, all available algorithms will be
+# included.
+default_ciphers="$available_ciphers"
+default_pubkey_ciphers="$available_pubkey_ciphers"
+default_digests="$available_digests"
+
+# Substitutions to set generated files in a Emacs buffer to read-only.
+emacs_local_vars_begin='Local Variables:'
+
+emacs_local_vars_read_only='buffer-read-only: t'
+
+emacs_local_vars_end='End:'
+
+
+############################
+## Command line switches. ##
+############################
+
+# Implementation of the --enable-ciphers switch.
+# Check whether --enable-ciphers was given.
+if test "${enable_ciphers+set}" = set; then :
+ enableval=$enable_ciphers; enabled_ciphers=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_ciphers=""
+fi
+
+if test "x$enabled_ciphers" = "x" \
+ -o "$enabled_ciphers" = "yes" \
+ -o "$enabled_ciphers" = "no"; then
+ enabled_ciphers=$default_ciphers
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which symmetric ciphers to include" >&5
+$as_echo_n "checking which symmetric ciphers to include... " >&6; }
+for cipher in $enabled_ciphers; do
+
+name=$cipher
+list=$available_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error "unsupported cipher \"$cipher\" specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_ciphers" >&5
+$as_echo "$enabled_ciphers" >&6; }
+
+# Implementation of the --enable-pubkey-ciphers switch.
+# Check whether --enable-pubkey-ciphers was given.
+if test "${enable_pubkey_ciphers+set}" = set; then :
+ enableval=$enable_pubkey_ciphers; enabled_pubkey_ciphers=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_pubkey_ciphers=""
+fi
+
+if test "x$enabled_pubkey_ciphers" = "x" \
+ -o "$enabled_pubkey_ciphers" = "yes" \
+ -o "$enabled_pubkey_ciphers" = "no"; then
+ enabled_pubkey_ciphers=$default_pubkey_ciphers
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which public-key ciphers to include" >&5
+$as_echo_n "checking which public-key ciphers to include... " >&6; }
+for cipher in $enabled_pubkey_ciphers; do
+
+name=$cipher
+list=$available_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error "unsupported public-key cipher specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_pubkey_ciphers" >&5
+$as_echo "$enabled_pubkey_ciphers" >&6; }
+
+# Implementation of the --enable-digests switch.
+# Check whether --enable-digests was given.
+if test "${enable_digests+set}" = set; then :
+ enableval=$enable_digests; enabled_digests=`echo $enableval | tr ',:' ' ' | tr 'A-Z' 'a-z'`
+else
+ enabled_digests=""
+fi
+
+if test "x$enabled_digests" = "x" \
+ -o "$enabled_digests" = "yes" \
+ -o "$enabled_digests" = "no"; then
+ enabled_digests=$default_digests
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which message digests to include" >&5
+$as_echo_n "checking which message digests to include... " >&6; }
+for digest in $enabled_digests; do
+
+name=$digest
+list=$available_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error "unsupported message digest specified" "$LINENO" 5
+ fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_digests" >&5
+$as_echo "$enabled_digests" >&6; }
+
+# Implementation of the --enable-random switch.
+# Check whether --enable-random was given.
+if test "${enable_random+set}" = set; then :
+ enableval=$enable_random; random=`echo $enableval | tr 'A-Z' 'a-z'`
+fi
+
+if test "x$random" = "x" -o "$random" = "yes" -o "$random" = "no"; then
+ random=default
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which random module to use" >&5
+$as_echo_n "checking which random module to use... " >&6; }
+if test "$random" != "default" -a "$random" != "auto"; then
+
+name=$random
+list=$available_random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+ if test "$found" = "0"; then
+ as_fn_error "unsupported random module specified" "$LINENO" 5
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $random" >&5
+$as_echo "$random" >&6; }
+
+# Implementation of the --disable-dev-random switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of /dev/random is requested" >&5
+$as_echo_n "checking whether use of /dev/random is requested... " >&6; }
+# Check whether --enable-dev-random was given.
+if test "${enable_dev_random+set}" = set; then :
+ enableval=$enable_dev_random; try_dev_random=$enableval
+else
+ try_dev_random=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_dev_random" >&5
+$as_echo "$try_dev_random" >&6; }
+
+# Implementation of the --with-egd-socket switch.
+
+# Check whether --with-egd-socket was given.
+if test "${with_egd_socket+set}" = set; then :
+ withval=$with_egd_socket; egd_socket_name="$withval"
+else
+ egd_socket_name=""
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define EGD_SOCKET_NAME "$egd_socket_name"
+_ACEOF
+
+
+# Implementation of the --enable-random-daemon
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the experimental random daemon is requested" >&5
+$as_echo_n "checking whether the experimental random daemon is requested... " >&6; }
+# Check whether --enable-random-daemon was given.
+if test "${enable_random_daemon+set}" = set; then :
+ enableval=$enable_random_daemon; use_random_daemon=$enableval
+else
+ use_random_daemon=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_random_daemon" >&5
+$as_echo "$use_random_daemon" >&6; }
+if test x$use_random_daemon = xyes ; then
+
+$as_echo "#define USE_RANDOM_DAEMON 1" >>confdefs.h
+
+fi
+ if test x$use_random_daemon = xyes; then
+ USE_RANDOM_DAEMON_TRUE=
+ USE_RANDOM_DAEMON_FALSE='#'
+else
+ USE_RANDOM_DAEMON_TRUE='#'
+ USE_RANDOM_DAEMON_FALSE=
+fi
+
+
+
+# Implementation of --disable-asm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether MPI assembler modules are requested" >&5
+$as_echo_n "checking whether MPI assembler modules are requested... " >&6; }
+# Check whether --enable-asm was given.
+if test "${enable_asm+set}" = set; then :
+ enableval=$enable_asm; try_asm_modules=$enableval
+else
+ try_asm_modules=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $try_asm_modules" >&5
+$as_echo "$try_asm_modules" >&6; }
+
+# Implementation of the --enable-m-guard switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether memory guard is requested" >&5
+$as_echo_n "checking whether memory guard is requested... " >&6; }
+# Check whether --enable-m-guard was given.
+if test "${enable_m_guard+set}" = set; then :
+ enableval=$enable_m_guard; use_m_guard=$enableval
+else
+ use_m_guard=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_m_guard" >&5
+$as_echo "$use_m_guard" >&6; }
+if test "$use_m_guard" = yes ; then
+
+$as_echo "#define M_GUARD 1" >>confdefs.h
+
+fi
+
+# Implementation of the --with-capabilities switch.
+# Check whether we want to use Linux capabilities
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of capabilities is requested" >&5
+$as_echo_n "checking whether use of capabilities is requested... " >&6; }
+
+# Check whether --with-capabilities was given.
+if test "${with_capabilities+set}" = set; then :
+ withval=$with_capabilities; use_capabilities="$withval"
+else
+ use_capabilities=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_capabilities" >&5
+$as_echo "$use_capabilities" >&6; }
+
+# Implementation of the --enable-hmac-binary-check.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a HMAC binary check is requested" >&5
+$as_echo_n "checking whether a HMAC binary check is requested... " >&6; }
+# Check whether --enable-hmac-binary-check was given.
+if test "${enable_hmac_binary_check+set}" = set; then :
+ enableval=$enable_hmac_binary_check; use_hmac_binary_check=$enableval
+else
+ use_hmac_binary_check=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $use_hmac_binary_check" >&5
+$as_echo "$use_hmac_binary_check" >&6; }
+if test "$use_hmac_binary_check" = yes ; then
+
+$as_echo "#define ENABLE_HMAC_BINARY_CHECK 1" >>confdefs.h
+
+fi
+
+
+# Implementation of the --disable-padlock-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether padlock support is requested" >&5
+$as_echo_n "checking whether padlock support is requested... " >&6; }
+# Check whether --enable-padlock-support was given.
+if test "${enable_padlock_support+set}" = set; then :
+ enableval=$enable_padlock_support; padlocksupport=$enableval
+else
+ padlocksupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $padlocksupport" >&5
+$as_echo "$padlocksupport" >&6; }
+if test x"$padlocksupport" = xyes ; then
+
+$as_echo "#define ENABLE_PADLOCK_SUPPORT 1" >>confdefs.h
+
+fi
+
+# Implementation of the --disable-aesni-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AESNI support is requested" >&5
+$as_echo_n "checking whether AESNI support is requested... " >&6; }
+# Check whether --enable-aesni-support was given.
+if test "${enable_aesni_support+set}" = set; then :
+ enableval=$enable_aesni_support; aesnisupport=$enableval
+else
+ aesnisupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $aesnisupport" >&5
+$as_echo "$aesnisupport" >&6; }
+if test x"$aesnisupport" = xyes ; then
+
+$as_echo "#define ENABLE_AESNI_SUPPORT 1" >>confdefs.h
+
+fi
+
+# Implementation of the --disable-O-flag-munging switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a -O flag munging is requested" >&5
+$as_echo_n "checking whether a -O flag munging is requested... " >&6; }
+# Check whether --enable-O-flag-munging was given.
+if test "${enable_O_flag_munging+set}" = set; then :
+ enableval=$enable_O_flag_munging; enable_o_flag_munging=$enableval
+else
+ enable_o_flag_munging=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_o_flag_munging" >&5
+$as_echo "$enable_o_flag_munging" >&6; }
+ if test "$enable_o_flag_munging" = "yes"; then
+ ENABLE_O_FLAG_MUNGING_TRUE=
+ ENABLE_O_FLAG_MUNGING_FALSE='#'
+else
+ ENABLE_O_FLAG_MUNGING_TRUE='#'
+ ENABLE_O_FLAG_MUNGING_FALSE=
+fi
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRINTABLE_OS_NAME "$PRINTABLE_OS_NAME"
+_ACEOF
+
+
+# For some systems we know that we have ld_version scripts.
+# Use it then as default.
+have_ld_version_script=no
+case "${host}" in
+ *-*-linux*)
+ have_ld_version_script=yes
+ ;;
+ *-*-gnu*)
+ have_ld_version_script=yes
+ ;;
+esac
+# Check whether --enable-ld-version-script was given.
+if test "${enable_ld_version_script+set}" = set; then :
+ enableval=$enable_ld_version_script; have_ld_version_script=$enableval
+else
+ :
+fi
+
+ if test "$have_ld_version_script" = "yes"; then
+ HAVE_LD_VERSION_SCRIPT_TRUE=
+ HAVE_LD_VERSION_SCRIPT_FALSE='#'
+else
+ HAVE_LD_VERSION_SCRIPT_TRUE='#'
+ HAVE_LD_VERSION_SCRIPT_FALSE=
+fi
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define NAME_OF_DEV_RANDOM "$NAME_OF_DEV_RANDOM"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define NAME_OF_DEV_URANDOM "$NAME_OF_DEV_URANDOM"
+_ACEOF
+
+
+
+###############################
+#### Checks for libraries. ####
+###############################
+
+#
+# gpg-error is required.
+#
+
+# Check whether --with-gpg-error-prefix was given.
+if test "${with_gpg_error_prefix+set}" = set; then :
+ withval=$with_gpg_error_prefix; gpg_error_config_prefix="$withval"
+else
+ gpg_error_config_prefix=""
+fi
+
+ if test x$gpg_error_config_prefix != x ; then
+ if test x${GPG_ERROR_CONFIG+set} != xset ; then
+ GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config
+ fi
+ fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gpg-error-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gpg-error-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_GPG_ERROR_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $GPG_ERROR_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_GPG_ERROR_CONFIG="$GPG_ERROR_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_GPG_ERROR_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+GPG_ERROR_CONFIG=$ac_cv_path_GPG_ERROR_CONFIG
+if test -n "$GPG_ERROR_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GPG_ERROR_CONFIG" >&5
+$as_echo "$GPG_ERROR_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_GPG_ERROR_CONFIG"; then
+ ac_pt_GPG_ERROR_CONFIG=$GPG_ERROR_CONFIG
+ # Extract the first word of "gpg-error-config", so it can be a program name with args.
+set dummy gpg-error-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_GPG_ERROR_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $ac_pt_GPG_ERROR_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_ac_pt_GPG_ERROR_CONFIG="$ac_pt_GPG_ERROR_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_ac_pt_GPG_ERROR_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+ac_pt_GPG_ERROR_CONFIG=$ac_cv_path_ac_pt_GPG_ERROR_CONFIG
+if test -n "$ac_pt_GPG_ERROR_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_GPG_ERROR_CONFIG" >&5
+$as_echo "$ac_pt_GPG_ERROR_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_pt_GPG_ERROR_CONFIG" = x; then
+ GPG_ERROR_CONFIG="no"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ GPG_ERROR_CONFIG=$ac_pt_GPG_ERROR_CONFIG
+ fi
+else
+ GPG_ERROR_CONFIG="$ac_cv_path_GPG_ERROR_CONFIG"
+fi
+
+ min_gpg_error_version="$NEED_GPG_ERROR_VERSION"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GPG Error - version >= $min_gpg_error_version" >&5
+$as_echo_n "checking for GPG Error - version >= $min_gpg_error_version... " >&6; }
+ ok=no
+ if test "$GPG_ERROR_CONFIG" != "no" ; then
+ req_major=`echo $min_gpg_error_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\)/\1/'`
+ req_minor=`echo $min_gpg_error_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\)/\2/'`
+ gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version`
+ major=`echo $gpg_error_config_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\).*/\1/'`
+ minor=`echo $gpg_error_config_version | \
+ sed 's/\([0-9]*\)\.\([0-9]*\).*/\2/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -ge "$req_minor"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags`
+ GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gpg_error_config_version)" >&5
+$as_echo "yes ($gpg_error_config_version)" >&6; }
+ :
+ if test x"$host" != x ; then
+ gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
+ if test x"$gpg_error_config_host" != xnone ; then
+ if test x"$gpg_error_config_host" != x"$host" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** The config script $GPG_ERROR_CONFIG was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-gpg-error-prefix
+*** to specify a matching config script.
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** The config script $GPG_ERROR_CONFIG was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-gpg-error-prefix
+*** to specify a matching config script.
+***" >&2;}
+ fi
+ fi
+ fi
+ else
+ GPG_ERROR_CFLAGS=""
+ GPG_ERROR_LIBS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ :
+ fi
+
+
+
+if test "x$GPG_ERROR_LIBS" = "x"; then
+ as_fn_error "libgpg-error is needed.
+ See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ ." "$LINENO" 5
+fi
+
+
+$as_echo "#define GPG_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT" >>confdefs.h
+
+
+#
+# Check whether the GNU Pth library is available. We require this
+# to build the optional gcryptrnd program.
+#
+
+# Check whether --with-pth-prefix was given.
+if test "${with_pth_prefix+set}" = set; then :
+ withval=$with_pth_prefix; pth_config_prefix="$withval"
+else
+ pth_config_prefix=""
+fi
+
+if test x$pth_config_prefix != x ; then
+ PTH_CONFIG="$pth_config_prefix/bin/pth-config"
+fi
+if test "$use_random_daemon" = "yes"; then
+ # Extract the first word of "pth-config", so it can be a program name with args.
+set dummy pth-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PTH_CONFIG+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $PTH_CONFIG in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_PTH_CONFIG="$PTH_CONFIG" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_PTH_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ test -z "$ac_cv_path_PTH_CONFIG" && ac_cv_path_PTH_CONFIG="no"
+ ;;
+esac
+fi
+PTH_CONFIG=$ac_cv_path_PTH_CONFIG
+if test -n "$PTH_CONFIG"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTH_CONFIG" >&5
+$as_echo "$PTH_CONFIG" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "$PTH_CONFIG" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***" >&2;}
+ else
+
+ _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print $3}'`
+ _req_version="1.3.7"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PTH - version >= $_req_version" >&5
+$as_echo_n "checking for PTH - version >= $_req_version... " >&6; }
+ for _var in _pth_version _req_version; do
+ eval "_val=\"\$${_var}\""
+ _major=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\1/'`
+ _minor=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\2/'`
+ _rtype=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\3/'`
+ _micro=`echo $_val | sed 's/\([0-9]*\)\.\([0-9]*\)\([ab.]\)\([0-9]*\)/\4/'`
+ case $_rtype in
+ "a" ) _rtype=0 ;;
+ "b" ) _rtype=1 ;;
+ "." ) _rtype=2 ;;
+ esac
+ _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \
+ "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"`
+ eval "${_var}_hex=\"\$_hex\""
+ done
+ have_pth=no
+ if test ".$_pth_version_hex" != .; then
+ if test ".$_req_version_hex" != .; then
+ if test $_pth_version_hex -ge $_req_version_hex; then
+ have_pth=yes
+ fi
+ fi
+ fi
+ if test $have_pth = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PTH installation is sane" >&5
+$as_echo_n "checking whether PTH installation is sane... " >&6; }
+ if test "${gnupg_cv_pth_is_sane+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ _gnupg_pth_save_cflags=$CFLAGS
+ _gnupg_pth_save_ldflags=$LDFLAGS
+ _gnupg_pth_save_libs=$LIBS
+ CFLAGS="$CFLAGS `$PTH_CONFIG --cflags`"
+ LDFLAGS="$LDFLAGS `$PTH_CONFIG --ldflags`"
+ LIBS="$LIBS `$PTH_CONFIG --libs`"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <pth.h>
+
+int
+main ()
+{
+ pth_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gnupg_cv_pth_is_sane=yes
+else
+ gnupg_cv_pth_is_sane=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ CFLAGS=$_gnupg_pth_save_cflags
+ LDFLAGS=$_gnupg_pth_save_ldflags
+ LIBS=$_gnupg_pth_save_libs
+
+fi
+
+ if test $gnupg_cv_pth_is_sane != yes; then
+ have_pth=no
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_pth_is_sane" >&5
+$as_echo "$gnupg_cv_pth_is_sane" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+
+ if test $have_pth = yes; then
+ PTH_CFLAGS=`$PTH_CONFIG --cflags`
+ PTH_LIBS=`$PTH_CONFIG --ldflags`
+ PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`"
+
+$as_echo "#define USE_GNU_PTH 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PTH 1" >>confdefs.h
+
+ fi
+ fi
+fi
+
+
+
+
+# Solaris needs -lsocket and -lnsl. Unisys system includes
+# gethostbyname in libsocket but needs libnsl for socket.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_setsockopt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib -lnsl $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_setsockopt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_setsockopt+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_setsockopt+set}" = set; then :
+
+else
+ ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
+##################################
+#### Checks for header files. ####
+##################################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+for ac_header in unistd.h sys/select.h sys/msg.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+INSERT_SYS_SELECT_H=
+if test x"$ac_cv_header_sys_select_h" = xyes; then
+ INSERT_SYS_SELECT_H=" include <sys/select.h>"
+fi
+
+
+
+##########################################
+#### Checks for typedefs, structures, ####
+#### and compiler characteristics. ####
+##########################################
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+ /* Ultrix mips cc rejects this. */
+ typedef int charset[2];
+ const charset cs;
+ /* SunOS 4.1.1 cc rejects this. */
+ char const *const *pcpcc;
+ char **ppc;
+ /* NEC SVR4.0.2 mips cc rejects this. */
+ struct point {int x, y;};
+ static struct point const zero = {0,0};
+ /* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in
+ an arm of an if-expression whose if-part is not a constant
+ expression */
+ const char *g = "string";
+ pcpcc = &g + (g ? g-g : 0);
+ /* HPUX 7.0 cc rejects these. */
+ ++pcpcc;
+ ppc = (char**) pcpcc;
+ pcpcc = (char const *const *) ppc;
+ { /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+ if (s) return 0;
+ }
+ { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+ }
+ { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+ }
+ { /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+ }
+ { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+ if (!foo) return 0;
+ }
+ return !cs[0] && !zero.x;
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_const=yes
+else
+ ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if test "${ac_cv_c_inline+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+ inline | yes) ;;
+ *)
+ case $ac_cv_c_inline in
+ no) ac_val=;;
+ *) ac_val=$ac_cv_c_inline;;
+ esac
+ cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+ ;;
+esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
+$as_echo_n "checking return type of signal handlers... " >&6; }
+if test "${ac_cv_type_signal+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+#include <signal.h>
+
+int
+main ()
+{
+return *(signal (0, 0)) (0) == 1;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_type_signal=int
+else
+ ac_cv_type_signal=void
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
+$as_echo "$ac_cv_type_signal" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h>
+/* NetBSD declares sys_siglist in unistd.h. */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+"
+if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then :
+ ac_have_decl=1
+else
+ ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYS_SIGLIST $ac_have_decl
+_ACEOF
+
+
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for byte typedef" >&5
+$as_echo_n "checking for byte typedef... " >&6; }
+ if test "${gnupg_cv_typedef_byte+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>
+int
+main ()
+{
+
+ #undef byte
+ int a = sizeof(byte);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_typedef_byte=yes
+else
+ gnupg_cv_typedef_byte=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_byte" >&5
+$as_echo "$gnupg_cv_typedef_byte" >&6; }
+ if test "$gnupg_cv_typedef_byte" = yes; then
+
+$as_echo "#define HAVE_BYTE_TYPEDEF 1" >>confdefs.h
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ushort typedef" >&5
+$as_echo_n "checking for ushort typedef... " >&6; }
+ if test "${gnupg_cv_typedef_ushort+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>
+int
+main ()
+{
+
+ #undef ushort
+ int a = sizeof(ushort);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_typedef_ushort=yes
+else
+ gnupg_cv_typedef_ushort=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_ushort" >&5
+$as_echo "$gnupg_cv_typedef_ushort" >&6; }
+ if test "$gnupg_cv_typedef_ushort" = yes; then
+
+$as_echo "#define HAVE_USHORT_TYPEDEF 1" >>confdefs.h
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ulong typedef" >&5
+$as_echo_n "checking for ulong typedef... " >&6; }
+ if test "${gnupg_cv_typedef_ulong+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>
+int
+main ()
+{
+
+ #undef ulong
+ int a = sizeof(ulong);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_typedef_ulong=yes
+else
+ gnupg_cv_typedef_ulong=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_ulong" >&5
+$as_echo "$gnupg_cv_typedef_ulong" >&6; }
+ if test "$gnupg_cv_typedef_ulong" = yes; then
+
+$as_echo "#define HAVE_ULONG_TYPEDEF 1" >>confdefs.h
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u16 typedef" >&5
+$as_echo_n "checking for u16 typedef... " >&6; }
+ if test "${gnupg_cv_typedef_u16+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>
+int
+main ()
+{
+
+ #undef u16
+ int a = sizeof(u16);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_typedef_u16=yes
+else
+ gnupg_cv_typedef_u16=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_u16" >&5
+$as_echo "$gnupg_cv_typedef_u16" >&6; }
+ if test "$gnupg_cv_typedef_u16" = yes; then
+
+$as_echo "#define HAVE_U16_TYPEDEF 1" >>confdefs.h
+
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u32 typedef" >&5
+$as_echo_n "checking for u32 typedef... " >&6; }
+ if test "${gnupg_cv_typedef_u32+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#define _GNU_SOURCE 1
+ #include <stdlib.h>
+ #include <sys/types.h>
+int
+main ()
+{
+
+ #undef u32
+ int a = sizeof(u32);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gnupg_cv_typedef_u32=yes
+else
+ gnupg_cv_typedef_u32=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_typedef_u32" >&5
+$as_echo "$gnupg_cv_typedef_u32" >&6; }
+ if test "$gnupg_cv_typedef_u32" = yes; then
+
+$as_echo "#define HAVE_U32_TYPEDEF 1" >>confdefs.h
+
+ fi
+
+
+
+ for ac_header in sys/socket.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_socket_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_SOCKET_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+ :
+
+
+
+
+
+ if test $ac_cv_header_sys_socket_h = yes; then
+ SYS_SOCKET_H=''
+ else
+ for ac_header in winsock2.h ws2tcpip.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+ SYS_SOCKET_H='sys/socket.h'
+ fi
+
+
+ ac_fn_c_check_type "$LINENO" "socklen_t" "ac_cv_type_socklen_t" "#include <sys/types.h>
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #elif HAVE_WS2TCPIP_H
+ # include <ws2tcpip.h>
+ #endif
+"
+if test "x$ac_cv_type_socklen_t" = x""yes; then :
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
+$as_echo_n "checking for socklen_t equivalent... " >&6; }
+ if test "${gl_cv_gl_cv_socklen_t_equiv+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ gl_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);
+int
+main ()
+{
+$t len;
+ getpeername (0, 0, &len);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gl_cv_socklen_t_equiv="$t"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+
+fi
+
+ if test "$gl_cv_socklen_t_equiv" = ""; then
+ as_fn_error "Cannot find a type to use in place of socklen_t" "$LINENO" 5
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_socklen_t_equiv" >&5
+$as_echo "$gl_cv_socklen_t_equiv" >&6; }
+
+cat >>confdefs.h <<_ACEOF
+#define socklen_t $gl_cv_socklen_t_equiv
+_ACEOF
+
+fi
+
+case "${host}" in
+ *-*-mingw32*)
+ # socklen_t may or may not be defined depending on what headers
+ # are included. To be safe we use int as this is the actual type.
+ FALLBACK_SOCKLEN_T="typedef int gcry_socklen_t;"
+ ;;
+ *)
+ if test ".$gl_cv_socklen_t_equiv" = "."; then
+ FALLBACK_SOCKLEN_T="typedef socklen_t gcry_socklen_t;"
+ else
+ FALLBACK_SOCKLEN_T="typedef ${gl_cv_socklen_t_equiv} gcry_socklen_t;"
+ fi
+esac
+
+
+#
+# Check for ELF visibility support.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the visibility attribute is supported" >&5
+$as_echo_n "checking whether the visibility attribute is supported... " >&6; }
+if test "${gcry_cv_visibility_attribute+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_visibility_attribute=no
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo __attribute__ ((visibility ("hidden"))) = 1;
+ int bar __attribute__ ((visibility ("protected"))) = 1;
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then
+ if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then
+ gcry_cv_visibility_attribute=yes
+ fi
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_visibility_attribute" >&5
+$as_echo "$gcry_cv_visibility_attribute" >&6; }
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken visibility attribute" >&5
+$as_echo_n "checking for broken visibility attribute... " >&6; }
+if test "${gcry_cv_broken_visibility_attribute+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_broken_visibility_attribute=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo (int x);
+ int bar (int x) __asm__ ("foo")
+ __attribute__ ((visibility ("hidden")));
+ int bar (int x) { return x; }
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep '\.hidden[ _]foo' conftest.s >/dev/null 2>&1;
+ then
+ gcry_cv_broken_visibility_attribute=no
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_broken_visibility_attribute" >&5
+$as_echo "$gcry_cv_broken_visibility_attribute" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken alias attribute" >&5
+$as_echo_n "checking for broken alias attribute... " >&6; }
+if test "${gcry_cv_broken_alias_attribute+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_broken_alias_attribute=yes
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern int foo (int x) __asm ("xyzzy");
+ int bar (int x) { return x; }
+ extern __typeof (bar) foo __attribute ((weak, alias ("bar")));
+ extern int dfoo;
+ extern __typeof (dfoo) dfoo __asm ("abccb");
+ int dfoo = 1;
+
+_ACEOF
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&5 2>&5 ; then
+ if grep 'xyzzy' conftest.s >/dev/null 2>&1 && \
+ grep 'abccb' conftest.s >/dev/null 2>&1; then
+ gcry_cv_broken_alias_attribute=no
+ fi
+ fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_broken_alias_attribute" >&5
+$as_echo "$gcry_cv_broken_alias_attribute" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -fvisibility=hidden" >&5
+$as_echo_n "checking if gcc supports -fvisibility=hidden... " >&6; }
+if test "${gcry_cv_gcc_has_f_visibility+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcry_cv_gcc_has_f_visibility=no
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fvisibility=hidden"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ gcry_cv_gcc_has_f_visibility=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS=$_gcc_cflags_save;
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_has_f_visibility" >&5
+$as_echo "$gcry_cv_gcc_has_f_visibility" >&6; }
+fi
+if test "$gcry_cv_visibility_attribute" = "yes" \
+ && test "$gcry_cv_broken_visibility_attribute" != "yes" \
+ && test "$gcry_cv_broken_alias_attribute" != "yes" \
+ && test "$gcry_cv_gcc_has_f_visibility" = "yes"
+ then
+
+$as_echo "#define GCRY_USE_VISIBILITY 1" >>confdefs.h
+
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+fi
+
+
+#######################################
+#### Checks for library functions. ####
+#######################################
+
+for ac_func in vprintf
+do :
+ ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = x""yes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+# We have replacements for these in src/missing-string.c
+for ac_func in stpcpy strcasecmp
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# We have replacements for these in src/g10lib.h
+for ac_func in strtoul memmove stricmp atexit raise
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# Other checks
+for ac_func in strerror rand mmap getpagesize sysconf waitpid wait4
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in gettimeofday getrusage gethrtime clock_gettime syslog
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in fcntl ftruncate
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ for ac_func in mlock
+do :
+ ac_fn_c_check_func "$LINENO" "mlock" "ac_cv_func_mlock"
+if test "x$ac_cv_func_mlock" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_MLOCK 1
+_ACEOF
+
+fi
+done
+
+ if test "$ac_cv_func_mlock" = "no"; then
+ for ac_header in sys/mman.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+ if test "$ac_cv_header_sys_mman_h" = "yes"; then
+ # Add librt to LIBS:
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memlk in -lrt" >&5
+$as_echo_n "checking for memlk in -lrt... " >&6; }
+if test "${ac_cv_lib_rt_memlk+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char memlk ();
+int
+main ()
+{
+return memlk ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_rt_memlk=yes
+else
+ ac_cv_lib_rt_memlk=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_memlk" >&5
+$as_echo "$ac_cv_lib_rt_memlk" >&6; }
+if test "x$ac_cv_lib_rt_memlk" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+ LIBS="-lrt $LIBS"
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is in sys/mman.h" >&5
+$as_echo_n "checking whether mlock is in sys/mman.h... " >&6; }
+if test "${gnupg_cv_mlock_is_in_sys_mman+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+ #include <assert.h>
+ #ifdef HAVE_SYS_MMAN_H
+ #include <sys/mman.h>
+ #endif
+
+int
+main ()
+{
+
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS. Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias. */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ gnupg_cv_mlock_is_in_sys_mman=yes
+else
+ gnupg_cv_mlock_is_in_sys_mman=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gnupg_cv_mlock_is_in_sys_mman" >&5
+$as_echo "$gnupg_cv_mlock_is_in_sys_mman" >&6; }
+ if test "$gnupg_cv_mlock_is_in_sys_mman" = "yes"; then
+
+$as_echo "#define HAVE_MLOCK 1" >>confdefs.h
+
+ fi
+ fi
+ fi
+ if test "$ac_cv_func_mlock" = "yes"; then
+ for ac_func in sysconf getpagesize
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is broken" >&5
+$as_echo_n "checking whether mlock is broken... " >&6; }
+ if test "${gnupg_cv_have_broken_mlock+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ gnupg_cv_have_broken_mlock="assume-no"
+
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+int main()
+{
+ char *pool;
+ int err;
+ long int pgsize;
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize = sysconf (_SC_PAGESIZE);
+#elif defined (HAVE_GETPAGESIZE)
+ pgsize = getpagesize();
+#else
+ pgsize = -1;
+#endif
+
+ if (pgsize == -1)
+ pgsize = 4096;
+
+ pool = malloc( 4096 + pgsize );
+ if( !pool )
+ return 2;
+ pool += (pgsize - ((long int)pool % pgsize));
+
+ err = mlock( pool, 4096 );
+ if( !err || errno == EPERM )
+ return 0; /* okay */
+
+ return 1; /* hmmm */
+}
+
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gnupg_cv_have_broken_mlock="no"
+else
+ gnupg_cv_have_broken_mlock="yes"
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+
+ if test "$gnupg_cv_have_broken_mlock" = "yes"; then
+
+$as_echo "#define HAVE_BROKEN_MLOCK 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ if test "$gnupg_cv_have_broken_mlock" = "no"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: assuming no" >&5
+$as_echo "assuming no" >&6; }
+ fi
+ fi
+ fi
+
+
+#
+# Replacement functions.
+#
+for ac_func in getpid clock
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+ case " $LIBOBJS " in
+ *" $ac_func.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+ ;;
+esac
+
+fi
+done
+
+
+
+
+#
+# Check wether it is necessary to link against libdl.
+#
+DL_LIBS=""
+if test "$use_hmac_binary_check" = yes ; then
+ _gcry_save_libs="$LIBS"
+ LIBS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+$as_echo_n "checking for library containing dlopen... " >&6; }
+if test "${ac_cv_search_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' c dl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_dlopen=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if test "${ac_cv_search_dlopen+set}" = set; then :
+ break
+fi
+done
+if test "${ac_cv_search_dlopen+set}" = set; then :
+
+else
+ ac_cv_search_dlopen=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
+$as_echo "$ac_cv_search_dlopen" >&6; }
+ac_res=$ac_cv_search_dlopen
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+ DL_LIBS=$LIBS
+ LIBS="$_gcry_save_libs"
+ LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${DL_LIBS}"
+fi
+
+
+
+#
+# Check whether we can use Linux capabilities as requested.
+#
+if test "$use_capabilities" = "yes" ; then
+use_capabilities=no
+for ac_header in sys/capability.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_capability_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_CAPABILITY_H 1
+_ACEOF
+
+fi
+
+done
+
+if test "$ac_cv_header_sys_capability_h" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_init in -lcap" >&5
+$as_echo_n "checking for cap_init in -lcap... " >&6; }
+if test "${ac_cv_lib_cap_cap_init+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcap $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cap_init ();
+int
+main ()
+{
+return cap_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_cap_cap_init=yes
+else
+ ac_cv_lib_cap_cap_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_init" >&5
+$as_echo "$ac_cv_lib_cap_cap_init" >&6; }
+if test "x$ac_cv_lib_cap_cap_init" = x""yes; then :
+ ac_need_libcap=1
+fi
+
+ if test "$ac_cv_lib_cap_cap_init" = "yes"; then
+
+$as_echo "#define USE_CAPABILITIES 1" >>confdefs.h
+
+ LIBS="$LIBS -lcap"
+ use_capabilities=yes
+ fi
+fi
+if test "$use_capabilities" = "no" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***" >&5
+$as_echo "$as_me: WARNING:
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***" >&2;}
+fi
+fi
+
+# Check whether a random device is available.
+if test "$try_dev_random" = yes ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5
+$as_echo_n "checking for random device... " >&6; }
+if test "${ac_cv_have_dev_random+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
+ ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_have_dev_random" >&5
+$as_echo "$ac_cv_have_dev_random" >&6; }
+ if test "$ac_cv_have_dev_random" = yes; then
+
+$as_echo "#define HAVE_DEV_RANDOM 1" >>confdefs.h
+
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5
+$as_echo_n "checking for random device... " >&6; }
+ ac_cv_have_dev_random=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: has been disabled" >&5
+$as_echo "has been disabled" >&6; }
+fi
+
+# Figure out the random modules for this configuration.
+if test "$random" = "default"; then
+
+ # Select default value.
+ if test "$ac_cv_have_dev_random" = yes; then
+ # Try Linuxish random device.
+ random_modules="linux"
+ else
+ case "${host}" in
+ *-*-mingw32ce*)
+ # WindowsCE random device.
+ random_modules="w32ce"
+ ;;
+ *-*-mingw32*|*-*-cygwin*)
+ # Windows random device.
+ random_modules="w32"
+ ;;
+ *)
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ ;;
+ esac
+ fi
+else
+ if test "$random" = "auto"; then
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ else
+ random_modules="$random"
+ fi
+fi
+
+
+#
+# Setup assembler stuff.
+#
+
+tmp_do_check="no"
+case "${host}" in
+ *-mingw32msvc*)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ i386-emx-os2 | i345686-pc-os2*emx | i386-pc-msdosdjgpp)
+ ac_cv_sys_symbol_underscore=yes
+ ;;
+ *)
+ if test "$cross_compiling" = yes; then
+ if test "x$ac_cv_sys_symbol_underscore" = x ; then
+ ac_cv_sys_symbol_underscore=yes
+ fi
+ else
+ tmp_do_check="yes"
+ fi
+ ;;
+esac
+if test "$tmp_do_check" = "yes"; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+ if test "${ac_cv_sys_symbol_underscore+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_sys_symbol_underscore=no
+ cat > conftest.$ac_ext <<EOF
+ void nm_test_func(){}
+ int main(){nm_test_func;return 0;}
+EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest*
+
+fi
+
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+ fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_symbol_underscore" >&5
+$as_echo "$ac_cv_sys_symbol_underscore" >&6; }
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+
+$as_echo "#define WITH_SYMBOL_UNDERSCORE 1" >>confdefs.h
+
+fi
+
+# Check whether --enable-mpi-path was given.
+if test "${enable_mpi_path+set}" = set; then :
+ enableval=$enable_mpi_path; mpi_extra_path="$enableval"
+else
+ mpi_extra_path=""
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi assembler functions" >&5
+$as_echo_n "checking for mpi assembler functions... " >&6; }
+if test -f $srcdir/mpi/config.links ; then
+ . $srcdir/mpi/config.links
+ ac_config_links="$ac_config_links "$mpi_ln_list""
+
+ ac_cv_mpi_sflags="$mpi_sflags"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+ as_fn_error "mpi/config.links missing!" "$LINENO" 5
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+
+
+ if test "$mpi_mod_asm_mpih_add1" = yes; then
+ MPI_MOD_ASM_MPIH_ADD1_TRUE=
+ MPI_MOD_ASM_MPIH_ADD1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_ADD1_TRUE='#'
+ MPI_MOD_ASM_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_sub1" = yes; then
+ MPI_MOD_ASM_MPIH_SUB1_TRUE=
+ MPI_MOD_ASM_MPIH_SUB1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_SUB1_TRUE='#'
+ MPI_MOD_ASM_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul1" = yes; then
+ MPI_MOD_ASM_MPIH_MUL1_TRUE=
+ MPI_MOD_ASM_MPIH_MUL1_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL1_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul2" = yes; then
+ MPI_MOD_ASM_MPIH_MUL2_TRUE=
+ MPI_MOD_ASM_MPIH_MUL2_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL2_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul3" = yes; then
+ MPI_MOD_ASM_MPIH_MUL3_TRUE=
+ MPI_MOD_ASM_MPIH_MUL3_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_MUL3_TRUE='#'
+ MPI_MOD_ASM_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_lshift" = yes; then
+ MPI_MOD_ASM_MPIH_LSHIFT_TRUE=
+ MPI_MOD_ASM_MPIH_LSHIFT_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_LSHIFT_TRUE='#'
+ MPI_MOD_ASM_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_rshift" = yes; then
+ MPI_MOD_ASM_MPIH_RSHIFT_TRUE=
+ MPI_MOD_ASM_MPIH_RSHIFT_FALSE='#'
+else
+ MPI_MOD_ASM_MPIH_RSHIFT_TRUE='#'
+ MPI_MOD_ASM_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv" = yes; then
+ MPI_MOD_ASM_UDIV_TRUE=
+ MPI_MOD_ASM_UDIV_FALSE='#'
+else
+ MPI_MOD_ASM_UDIV_TRUE='#'
+ MPI_MOD_ASM_UDIV_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv_qrnnd" = yes; then
+ MPI_MOD_ASM_UDIV_QRNND_TRUE=
+ MPI_MOD_ASM_UDIV_QRNND_FALSE='#'
+else
+ MPI_MOD_ASM_UDIV_QRNND_TRUE='#'
+ MPI_MOD_ASM_UDIV_QRNND_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_add1" = yes; then
+ MPI_MOD_C_MPIH_ADD1_TRUE=
+ MPI_MOD_C_MPIH_ADD1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_ADD1_TRUE='#'
+ MPI_MOD_C_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_sub1" = yes; then
+ MPI_MOD_C_MPIH_SUB1_TRUE=
+ MPI_MOD_C_MPIH_SUB1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_SUB1_TRUE='#'
+ MPI_MOD_C_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul1" = yes; then
+ MPI_MOD_C_MPIH_MUL1_TRUE=
+ MPI_MOD_C_MPIH_MUL1_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL1_TRUE='#'
+ MPI_MOD_C_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul2" = yes; then
+ MPI_MOD_C_MPIH_MUL2_TRUE=
+ MPI_MOD_C_MPIH_MUL2_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL2_TRUE='#'
+ MPI_MOD_C_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul3" = yes; then
+ MPI_MOD_C_MPIH_MUL3_TRUE=
+ MPI_MOD_C_MPIH_MUL3_FALSE='#'
+else
+ MPI_MOD_C_MPIH_MUL3_TRUE='#'
+ MPI_MOD_C_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_lshift" = yes; then
+ MPI_MOD_C_MPIH_LSHIFT_TRUE=
+ MPI_MOD_C_MPIH_LSHIFT_FALSE='#'
+else
+ MPI_MOD_C_MPIH_LSHIFT_TRUE='#'
+ MPI_MOD_C_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_rshift" = yes; then
+ MPI_MOD_C_MPIH_RSHIFT_TRUE=
+ MPI_MOD_C_MPIH_RSHIFT_FALSE='#'
+else
+ MPI_MOD_C_MPIH_RSHIFT_TRUE='#'
+ MPI_MOD_C_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_udiv" = yes; then
+ MPI_MOD_C_UDIV_TRUE=
+ MPI_MOD_C_UDIV_FALSE='#'
+else
+ MPI_MOD_C_UDIV_TRUE='#'
+ MPI_MOD_C_UDIV_FALSE=
+fi
+
+ if test "$mpi_mod_c_udiv_qrnnd" = yes; then
+ MPI_MOD_C_UDIV_QRNND_TRUE=
+ MPI_MOD_C_UDIV_QRNND_FALSE='#'
+else
+ MPI_MOD_C_UDIV_QRNND_TRUE='#'
+ MPI_MOD_C_UDIV_QRNND_FALSE=
+fi
+
+
+if test "$is_development_version" = "yes"; then
+
+$as_echo "#define IS_DEVELOPMENT_VERSION 1" >>confdefs.h
+
+fi
+
+
+ if test x$cross_compiling = xyes; then
+ CROSS_COMPILING_TRUE=
+ CROSS_COMPILING_FALSE='#'
+else
+ CROSS_COMPILING_TRUE='#'
+ CROSS_COMPILING_FALSE=
+fi
+
+
+
+# This is handy for debugging so the compiler doesn't rearrange
+# things and eliminate variables.
+# Check whether --enable-optimization was given.
+if test "${enable_optimization+set}" = set; then :
+ enableval=$enable_optimization; if test $enableval = no ; then
+ CFLAGS=`echo $CFLAGS | sed 's/-O[0-9]//'`
+ fi
+fi
+
+
+# CFLAGS mangling when using gcc.
+if test "$GCC" = yes; then
+ CFLAGS="$CFLAGS -Wall"
+ if test "$USE_MAINTAINER_MODE" = "yes"; then
+ CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes"
+ CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
+
+ # If -Wno-missing-field-initializers is supported we can enable a
+ # a bunch of really useful warnings.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wno-missing-field-initializers" >&5
+$as_echo_n "checking if gcc supports -Wno-missing-field-initializers... " >&6; }
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wno-missing-field-initializers"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ _gcc_wopt=yes
+else
+ _gcc_wopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5
+$as_echo "$_gcc_wopt" >&6; }
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast"
+ CFLAGS="$CFLAGS -Wwrite-strings"
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+ CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+ CFLAGS="$CFLAGS -Wno-sign-compare"
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -Wpointer-arith" >&5
+$as_echo_n "checking if gcc supports -Wpointer-arith... " >&6; }
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wpointer-arith"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ _gcc_wopt=yes
+else
+ _gcc_wopt=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_gcc_wopt" >&5
+$as_echo "$_gcc_wopt" >&6; }
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -Wpointer-arith"
+ fi
+ fi
+
+fi
+
+# Check whether as(1) supports a noeexecstack feature. This test
+# includes an override option.
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether non excutable stack support is requested" >&5
+$as_echo_n "checking whether non excutable stack support is requested... " >&6; }
+# Check whether --enable-noexecstack was given.
+if test "${enable_noexecstack+set}" = set; then :
+ enableval=$enable_noexecstack; noexecstack_support=$enableval
+else
+ noexecstack_support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $noexecstack_support" >&5
+$as_echo "$noexecstack_support" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports --noexecstack option" >&5
+$as_echo_n "checking whether assembler supports --noexecstack option... " >&6; }
+if test "${cl_cv_as_noexecstack+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if { ac_try='${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; } \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && { ac_try='${CCAS} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cl_cv_as_noexecstack" >&5
+$as_echo "$cl_cv_as_noexecstack" >&6; }
+ if test "$noexecstack_support" = yes -a "$cl_cv_as_noexecstack" = yes; then
+ NOEXECSTACK_FLAGS="-Wa,--noexecstack"
+ else
+ NOEXECSTACK_FLAGS=
+ fi
+
+
+
+
+
+
+
+
+
+
+ac_config_commands="$ac_config_commands gcrypt-conf"
+
+
+#####################
+#### Conclusion. ####
+#####################
+
+# Define conditional sources and config.h symbols depending on the
+# selected ciphers, pubkey-ciphers, digests and random modules.
+
+
+name=arcfour
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1"; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo"
+
+$as_echo "#define USE_ARCFOUR 1" >>confdefs.h
+
+fi
+
+
+name=blowfish
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo"
+
+$as_echo "#define USE_BLOWFISH 1" >>confdefs.h
+
+fi
+
+
+name=cast5
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo"
+
+$as_echo "#define USE_CAST5 1" >>confdefs.h
+
+fi
+
+
+name=des
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo"
+
+$as_echo "#define USE_DES 1" >>confdefs.h
+
+fi
+
+
+name=aes
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo"
+
+$as_echo "#define USE_AES 1" >>confdefs.h
+
+fi
+
+
+name=twofish
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo"
+
+$as_echo "#define USE_TWOFISH 1" >>confdefs.h
+
+fi
+
+
+name=serpent
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
+
+$as_echo "#define USE_SERPENT 1" >>confdefs.h
+
+fi
+
+
+name=rfc2268
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo"
+
+$as_echo "#define USE_RFC2268 1" >>confdefs.h
+
+fi
+
+
+name=seed
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS seed.lo"
+
+$as_echo "#define USE_SEED 1" >>confdefs.h
+
+fi
+
+
+name=camellia
+list=$enabled_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo"
+
+$as_echo "#define USE_CAMELLIA 1" >>confdefs.h
+
+fi
+
+
+name=dsa
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
+
+$as_echo "#define USE_DSA 1" >>confdefs.h
+
+fi
+
+
+name=rsa
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS rsa.lo"
+
+$as_echo "#define USE_RSA 1" >>confdefs.h
+
+fi
+
+
+name=elgamal
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS elgamal.lo"
+
+$as_echo "#define USE_ELGAMAL 1" >>confdefs.h
+
+fi
+
+
+name=ecc
+list=$enabled_pubkey_ciphers
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ecc.lo"
+
+$as_echo "#define USE_ECC 1" >>confdefs.h
+
+fi
+
+
+name=crc
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
+
+$as_echo "#define USE_CRC 1" >>confdefs.h
+
+fi
+
+
+name=md4
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo"
+
+$as_echo "#define USE_MD4 1" >>confdefs.h
+
+fi
+
+
+name=md5
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md5.lo"
+
+$as_echo "#define USE_MD5 1" >>confdefs.h
+
+fi
+
+
+name=sha256
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
+
+$as_echo "#define USE_SHA256 1" >>confdefs.h
+
+fi
+
+
+name=sha512
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo"
+
+$as_echo "#define USE_SHA512 1" >>confdefs.h
+
+fi
+
+
+name=tiger
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo"
+
+$as_echo "#define USE_TIGER 1" >>confdefs.h
+
+fi
+
+
+name=whirlpool
+list=$enabled_digests
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo"
+
+$as_echo "#define USE_WHIRLPOOL 1" >>confdefs.h
+
+fi
+
+# rmd160 and sha1 should be included always.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo"
+
+$as_echo "#define USE_RMD160 1" >>confdefs.h
+
+
+$as_echo "#define USE_SHA1 1" >>confdefs.h
+
+
+
+name=linux
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo"
+
+$as_echo "#define USE_RNDLINUX 1" >>confdefs.h
+
+fi
+
+
+name=unix
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndunix.lo"
+
+$as_echo "#define USE_RNDUNIX 1" >>confdefs.h
+
+ print_egd_notice=yes
+fi
+
+
+name=egd
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndegd.lo"
+
+$as_echo "#define USE_RNDEGD 1" >>confdefs.h
+
+fi
+
+
+name=w32
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32.lo"
+
+$as_echo "#define USE_RNDW32 1" >>confdefs.h
+
+fi
+
+
+name=w32ce
+list=$random_modules
+found=0
+
+for n in $list; do
+ if test "x$name" = "x$n"; then
+ found=1
+ fi
+done
+
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+
+$as_echo "#define USE_RNDW32CE 1" >>confdefs.h
+
+fi
+
+
+
+
+
+
+LIBGCRYPT_CIPHERS=$enabled_ciphers
+
+LIBGCRYPT_PUBKEY_CIPHERS=$enabled_pubkey_ciphers
+
+LIBGCRYPT_DIGESTS=$enabled_digests
+
+
+# For printing the configuration we need a colon separated list of
+# algorithm names.
+tmp=`echo "$enabled_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_PUBKEY_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_digests" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_DIGESTS "$tmp"
+_ACEOF
+
+
+
+
+# Generate extended version information for W32.
+if test "$have_w32_system" = yes; then
+ BUILD_TIMESTAMP=`date --iso-8601=minutes`
+ BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
+ BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}"
+fi
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define BUILD_REVISION "$BUILD_REVISION"
+_ACEOF
+
+
+
+
+# And create the files.
+ac_config_files="$ac_config_files Makefile m4/Makefile compat/Makefile mpi/Makefile cipher/Makefile random/Makefile doc/Makefile src/Makefile src/gcrypt.h src/libgcrypt-config src/versioninfo.rc tests/Makefile"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+ as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
+ as_fn_error "conditional \"am__fastdepCCAS\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_W32_SYSTEM_TRUE}" && test -z "${HAVE_W32_SYSTEM_FALSE}"; then
+ as_fn_error "conditional \"HAVE_W32_SYSTEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_W32CE_SYSTEM_TRUE}" && test -z "${HAVE_W32CE_SYSTEM_FALSE}"; then
+ as_fn_error "conditional \"HAVE_W32CE_SYSTEM\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+if test -z "${USE_RANDOM_DAEMON_TRUE}" && test -z "${USE_RANDOM_DAEMON_FALSE}"; then
+ as_fn_error "conditional \"USE_RANDOM_DAEMON\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${ENABLE_O_FLAG_MUNGING_TRUE}" && test -z "${ENABLE_O_FLAG_MUNGING_FALSE}"; then
+ as_fn_error "conditional \"ENABLE_O_FLAG_MUNGING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then
+ as_fn_error "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_ADD1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_ADD1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_SUB1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_SUB1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL2_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL3_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_LSHIFT_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_LSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_RSHIFT_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_MPIH_RSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_UDIV_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_UDIV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_ASM_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_QRNND_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_ASM_UDIV_QRNND\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_C_MPIH_ADD1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_ADD1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_C_MPIH_SUB1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_SUB1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL1_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL1\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL2_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL3_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL3\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_LSHIFT_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_LSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_RSHIFT_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_MPIH_RSHIFT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_UDIV_TRUE}" && test -z "${MPI_MOD_C_UDIV_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_UDIV\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${MPI_MOD_C_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_C_UDIV_QRNND_FALSE}"; then
+ as_fn_error "conditional \"MPI_MOD_C_UDIV_QRNND\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then
+ as_fn_error "conditional \"CROSS_COMPILING\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by libgcrypt $as_me 1.5.0, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_links="$ac_config_links"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+ --header=FILE[:TEMPLATE]
+ instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration links:
+$config_links
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-libgcrypt@gnupg.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+libgcrypt config.status 1.5.0
+configured by $0, generated by GNU Autoconf 2.64,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --header | --heade | --head | --hea )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h)
+ # Conflict between --help and --header
+ as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+ --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+LD_RC='`$ECHO "X$LD_RC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds_RC='`$ECHO "X$old_archive_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_RC='`$ECHO "X$compiler_RC" | $Xsed -e "$delay_single_quote_subst"`'
+GCC_RC='`$ECHO "X$GCC_RC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_RC='`$ECHO "X$lt_prog_compiler_no_builtin_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_RC='`$ECHO "X$lt_prog_compiler_wl_RC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_RC='`$ECHO "X$lt_prog_compiler_pic_RC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static_RC='`$ECHO "X$lt_prog_compiler_static_RC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_RC='`$ECHO "X$lt_cv_prog_compiler_c_o_RC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc_RC='`$ECHO "X$archive_cmds_need_lc_RC" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_RC='`$ECHO "X$enable_shared_with_static_runtimes_RC" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_RC='`$ECHO "X$export_dynamic_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec_RC='`$ECHO "X$whole_archive_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object_RC='`$ECHO "X$compiler_needs_object_RC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_RC='`$ECHO "X$old_archive_from_new_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_RC='`$ECHO "X$old_archive_from_expsyms_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_RC='`$ECHO "X$archive_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds_RC='`$ECHO "X$archive_expsym_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds_RC='`$ECHO "X$module_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds_RC='`$ECHO "X$module_expsym_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld_RC='`$ECHO "X$with_gnu_ld_RC" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag_RC='`$ECHO "X$allow_undefined_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag_RC='`$ECHO "X$no_undefined_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_RC='`$ECHO "X$hardcode_libdir_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_RC='`$ECHO "X$hardcode_libdir_flag_spec_ld_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator_RC='`$ECHO "X$hardcode_libdir_separator_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_RC='`$ECHO "X$hardcode_direct_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute_RC='`$ECHO "X$hardcode_direct_absolute_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L_RC='`$ECHO "X$hardcode_minus_L_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_RC='`$ECHO "X$hardcode_shlibpath_var_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic_RC='`$ECHO "X$hardcode_automatic_RC" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath_RC='`$ECHO "X$inherit_rpath_RC" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs_RC='`$ECHO "X$link_all_deplibs_RC" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path_RC='`$ECHO "X$fix_srcfile_path_RC" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols_RC='`$ECHO "X$always_export_symbols_RC" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds_RC='`$ECHO "X$export_symbols_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms_RC='`$ECHO "X$exclude_expsyms_RC" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms_RC='`$ECHO "X$include_expsyms_RC" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds_RC='`$ECHO "X$prelink_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec_RC='`$ECHO "X$file_list_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action_RC='`$ECHO "X$hardcode_action_RC" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib \
+LD_RC \
+compiler_RC \
+lt_prog_compiler_no_builtin_flag_RC \
+lt_prog_compiler_wl_RC \
+lt_prog_compiler_pic_RC \
+lt_prog_compiler_static_RC \
+lt_cv_prog_compiler_c_o_RC \
+export_dynamic_flag_spec_RC \
+whole_archive_flag_spec_RC \
+compiler_needs_object_RC \
+with_gnu_ld_RC \
+allow_undefined_flag_RC \
+no_undefined_flag_RC \
+hardcode_libdir_flag_spec_RC \
+hardcode_libdir_flag_spec_ld_RC \
+hardcode_libdir_separator_RC \
+fix_srcfile_path_RC \
+exclude_expsyms_RC \
+include_expsyms_RC \
+file_list_spec_RC; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+old_archive_cmds_RC \
+old_archive_from_new_cmds_RC \
+old_archive_from_expsyms_cmds_RC \
+archive_cmds_RC \
+archive_expsym_cmds_RC \
+module_cmds_RC \
+module_expsym_cmds_RC \
+export_symbols_cmds_RC \
+prelink_cmds_RC; do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+ ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+prefix=$prefix
+exec_prefix=$exec_prefix
+libdir=$libdir
+datadir=$datadir
+DATADIRNAME=$DATADIRNAME
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+ case $ac_config_target in
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+ "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ ""$mpi_ln_list"") CONFIG_LINKS="$CONFIG_LINKS "$mpi_ln_list"" ;;
+ "gcrypt-conf") CONFIG_COMMANDS="$CONFIG_COMMANDS gcrypt-conf" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;;
+ "compat/Makefile") CONFIG_FILES="$CONFIG_FILES compat/Makefile" ;;
+ "mpi/Makefile") CONFIG_FILES="$CONFIG_FILES mpi/Makefile" ;;
+ "cipher/Makefile") CONFIG_FILES="$CONFIG_FILES cipher/Makefile" ;;
+ "random/Makefile") CONFIG_FILES="$CONFIG_FILES random/Makefile" ;;
+ "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+ "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+ "src/gcrypt.h") CONFIG_FILES="$CONFIG_FILES src/gcrypt.h" ;;
+ "src/libgcrypt-config") CONFIG_FILES="$CONFIG_FILES src/libgcrypt-config" ;;
+ "src/versioninfo.rc") CONFIG_FILES="$CONFIG_FILES src/versioninfo.rc" ;;
+ "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+ test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = "\a"
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+ ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+ if test -z "$ac_t"; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any. Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[ ]*#[ ]*define[ ][ ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ for (key in D) D_is_set[key] = 1
+ FS = "\a"
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+ line = \$ 0
+ split(line, arg, " ")
+ if (arg[1] == "#") {
+ defundef = arg[2]
+ mac1 = arg[3]
+ } else {
+ defundef = substr(arg[1], 2)
+ mac1 = arg[2]
+ }
+ split(mac1, mac2, "(") #)
+ macro = mac2[1]
+ prefix = substr(line, 1, index(line, defundef) - 1)
+ if (D_is_set[macro]) {
+ # Preserve the white space surrounding the "#".
+ print prefix "define", macro P[macro] D[macro]
+ next
+ } else {
+ # Replace #undef with comments. This is necessary, for example,
+ # in the case of _POSIX_SOURCE, which is predefined and required
+ # on some systems where configure will not decide to define it.
+ if (defundef == "undef") {
+ print "/*", prefix defundef, macro, "*/"
+ next
+ }
+ }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+ :H)
+ #
+ # CONFIG_HEADER
+ #
+ if test x"$ac_file" != x-; then
+ {
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+ } >"$tmp/config.h" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+ else
+ rm -f "$ac_file"
+ mv "$tmp/config.h" "$ac_file" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ fi
+ else
+ $as_echo "/* $configure_input */" \
+ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+ || as_fn_error "could not create -" "$LINENO" 5
+ fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$_am_arg" : 'X\(//\)[^/]' \| \
+ X"$_am_arg" : 'X\(//\)$' \| \
+ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+ :L)
+ #
+ # CONFIG_LINK
+ #
+
+ if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then
+ :
+ else
+ # Prefer the file from the source tree if names are identical.
+ if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then
+ ac_source=$srcdir/$ac_source
+ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5
+$as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
+
+ if test ! -r "$ac_source"; then
+ as_fn_error "$ac_source: file not found" "$LINENO" 5
+ fi
+ rm -f "$ac_file"
+
+ # Try a relative symlink, then a hard link, then a copy.
+ case $srcdir in
+ [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
+ *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
+ esac
+ ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
+ ln "$ac_source" "$ac_file" 2>/dev/null ||
+ cp -p "$ac_source" "$ac_file" ||
+ as_fn_error "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+ fi
+ ;;
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ case $ac_file$ac_mode in
+ "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+ # Autoconf 2.62 quotes --file arguments for eval, but not when files
+ # are listed without --file. Let's play safe and only enable the eval
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="RC "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Assembler program.
+AS=$AS
+
+# DLL creation program.
+DLLTOOL=$DLLTOOL
+
+# Object dumper program.
+OBJDUMP=$OBJDUMP
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: RC
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_RC
+
+# A language specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_RC
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_RC
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_RC
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_RC
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_RC
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_RC
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_RC
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# ### END LIBTOOL TAG CONFIG: RC
+_LT_EOF
+
+ ;;
+ "gcrypt-conf":C)
+chmod +x src/libgcrypt-config
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+# Give some feedback
+echo "
+ Libgcrypt v${VERSION} has been configured as follows:
+
+ Platform: $PRINTABLE_OS_NAME ($host)
+ Enabled cipher algorithms: $enabled_ciphers
+ Enabled digest algorithms: $enabled_digests
+ Enabled pubkey algorithms: $enabled_pubkey_ciphers
+ Random number generator: $random
+ Using linux capabilities: $use_capabilities
+ Try using Padlock crypto: $padlocksupport
+ Try using AES-NI crypto: $aesnisupport
+"
+
+if test "$print_egd_notice" = "yes"; then
+cat <<G10EOF
+
+ The performance of the Unix random gatherer module (rndunix) is not
+ very good and it does not keep the entropy pool over multiple
+ invocations of Libgcrypt base applications. The suggested way to
+ overcome this problem is to use the
+
+ Entropy Gathering Daemon (EGD)
+
+ which provides a entropy source for the whole system. It is written
+ in Perl and available at the GnuPG FTP servers. To enable EGD you
+ should rerun configure with the option "--enable-static-rnd=egd".
+ For more information consult the GnuPG webpages:
+
+ http://www.gnupg.org/download.html#egd
+
+G10EOF
+fi
+
+if test -n "$gpl"; then
+ echo "Please note that you are building a version of Libgcrypt with"
+ echo " $gpl"
+ echo "included. These parts are licensed under the GPL and thus the"
+ echo "use of this library has to comply with the conditions of the GPL."
+fi
--- /dev/null
+# Configure.ac script for Libgcrypt
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
+# 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# (Process this file with autoconf to produce a configure script.)
+AC_REVISION($Revision$)
+AC_PREREQ(2.60)
+min_automake_version="1.10"
+
+
+# Remember to change the version number immediately *after* a release.
+# Set my_issvn to "yes" for non-released code. Remember to run an
+# "svn up" and "autogen.sh" right before creating a distribution.
+m4_define([my_version], [1.5.0])
+m4_define([my_issvn], [no])
+
+m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \
+ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)]))
+m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \
+ | awk '/^\* / {printf "%s",$3}']))
+AC_INIT([libgcrypt],
+ [my_version[]m4_if(my_issvn,[yes],
+ [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])],
+ [bug-libgcrypt@gnupg.org])
+# LT Version numbers, remember to change them just *before* a release.
+# (Interfaces removed: CURRENT++, AGE=0, REVISION=0)
+# (Interfaces added: CURRENT++, AGE++, REVISION=0)
+# (No interfaces changed: REVISION++)
+LIBGCRYPT_LT_CURRENT=18
+LIBGCRYPT_LT_AGE=7
+LIBGCRYPT_LT_REVISION=0
+
+
+# If the API is changed in an incompatible way: increment the next counter.
+LIBGCRYPT_CONFIG_API_VERSION=1
+
+NEED_GPG_ERROR_VERSION=1.8
+
+is_development_version=my_issvn
+m4_define([git_brevis],m4_esyscmd(printf "%u" 0x[]m4_substr(git_revision,0,4)))
+BUILD_REVISION=m4_if(git_revision,[],[svn_revision],[git_brevis])
+PACKAGE=$PACKAGE_NAME
+VERSION=$PACKAGE_VERSION
+
+AC_CONFIG_SRCDIR([src/libgcrypt.vers])
+AM_INIT_AUTOMAKE([])
+AM_CONFIG_HEADER(config.h)
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_LIBOBJ_DIR([compat])
+AC_CANONICAL_HOST
+AM_MAINTAINER_MODE
+
+AH_TOP([
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+#define _GCRYPT_CONFIG_H_INCLUDED
+
+/* Enable gpg-error's strerror macro for W32CE. */
+#define GPG_ERR_ENABLE_ERRNO_MACROS 1
+])
+
+AH_BOTTOM([
+#define _GCRYPT_IN_LIBGCRYPT 1
+
+/* If the configure check for endianness has been disabled, get it from
+ OS macros. This is intended for making fat binary builds on OS X. */
+#ifdef DISABLED_ENDIAN_CHECK
+# if defined(__BIG_ENDIAN__)
+# define WORDS_BIGENDIAN 1
+# elif defined(__LITTLE_ENDIAN__)
+# undef WORDS_BIGENDIAN
+# else
+# error "No endianness found"
+# endif
+#endif /*DISABLED_ENDIAN_CHECK*/
+
+/* We basically use the original Camellia source. Make sure the symbols
+ properly prefixed. */
+#define CAMELLIA_EXT_SYM_PREFIX _gcry_
+
+/* This error code is only available with gpg-error 1.7. Thus
+ we define it here with the usual gcry prefix. */
+#define GCRY_GPG_ERR_NOT_OPERATIONAL 176
+
+
+#endif /*_GCRYPT_CONFIG_H_INCLUDED*/
+])
+
+AH_VERBATIM([_REENTRANT],
+[/* To allow the use of Libgcrypt in multithreaded programs we have to use
+ special features from the library. */
+#ifndef _REENTRANT
+# define _REENTRANT 1
+#endif
+])
+
+
+AC_SUBST(LIBGCRYPT_LT_CURRENT)
+AC_SUBST(LIBGCRYPT_LT_AGE)
+AC_SUBST(LIBGCRYPT_LT_REVISION)
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
+
+
+######################
+## Basic checks. ### (we need some results later on (e.g. $GCC)
+######################
+
+AC_PROG_MAKE_SET
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+# AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_PROG_CC
+AC_PROG_CPP
+AM_PROG_CC_C_O
+AM_PROG_AS
+AC_ISC_POSIX
+AC_PROG_INSTALL
+AC_PROG_AWK
+
+AC_GNU_SOURCE
+
+
+LT_PREREQ([2.2.6])
+LT_INIT([win32-dll disable-static])
+LT_LANG([Windows Resource])
+
+
+##########################
+## General definitions. ##
+##########################
+
+# Used by libgcrypt-config
+LIBGCRYPT_CONFIG_LIBS="-lgcrypt"
+LIBGCRYPT_CONFIG_CFLAGS=""
+LIBGCRYPT_CONFIG_HOST="$host"
+
+# Definitions for symmetric ciphers.
+available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed"
+available_ciphers="$available_ciphers camellia"
+enabled_ciphers=""
+
+# Definitions for public-key ciphers.
+available_pubkey_ciphers="dsa elgamal rsa ecc"
+enabled_pubkey_ciphers=""
+
+# Definitions for message digests.
+available_digests="crc md4 md5 rmd160 sha1 sha256"
+available_digests_64="sha512 tiger whirlpool"
+enabled_digests=""
+
+# Definitions for random modules.
+available_random_modules="linux egd unix"
+auto_random_modules="$available_random_modules"
+
+# Supported thread backends.
+LIBGCRYPT_THREAD_MODULES=""
+
+# Other definitions.
+print_egd_notice=no
+have_w32_system=no
+have_w32ce_system=no
+
+# Setup some stuff depending on host.
+case "${host}" in
+ *-*-mingw32*)
+ ac_cv_have_dev_random=no
+ have_w32_system=yes
+ case "${host}" in
+ *-mingw32ce*)
+ have_w32ce_system=yes
+ available_random_modules="w32ce"
+ ;;
+ *)
+ available_random_modules="w32"
+ ;;
+ esac
+ AC_DEFINE(USE_ONLY_8DOT3,1,
+ [set this to limit filenames to the 8.3 format])
+ AC_DEFINE(HAVE_DRIVE_LETTERS,1,
+ [defined if we must run on a stupid file system])
+ AC_DEFINE(HAVE_DOSISH_SYSTEM,1,
+ [defined if we run on some of the PCDOS like systems
+ (DOS, Windoze. OS/2) with special properties like
+ no file modes])
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx)
+ # OS/2 with the EMX environment
+ ac_cv_have_dev_random=no
+ AC_DEFINE(HAVE_DRIVE_LETTERS)
+ AC_DEFINE(HAVE_DOSISH_SYSTEM)
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ # DOS with the DJGPP environment
+ ac_cv_have_dev_random=no
+ AC_DEFINE(HAVE_DRIVE_LETTERS)
+ AC_DEFINE(HAVE_DOSISH_SYSTEM)
+ ;;
+
+ *-*-freebsd*)
+ # FreeBSD
+ CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib"
+ ;;
+
+ *-*-hpux*)
+ if test -z "$GCC" ; then
+ CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+ fi
+ ;;
+ *-dec-osf4*)
+ if test -z "$GCC" ; then
+ # Suppress all warnings
+ # to get rid of the unsigned/signed char mismatch warnings.
+ CFLAGS="$CFLAGS -w"
+ fi
+ ;;
+ m68k-atari-mint)
+ ;;
+ *)
+ ;;
+esac
+
+if test "$have_w32_system" = yes; then
+ AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system])
+ if test "$have_w32ce_system" = yes; then
+ AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE])
+ fi
+fi
+AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes)
+AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes)
+
+
+
+# A printable OS Name is sometimes useful.
+case "${host}" in
+ *-*-mingw32ce*)
+ PRINTABLE_OS_NAME="W32CE"
+ ;;
+
+ *-*-mingw32*)
+ PRINTABLE_OS_NAME="W32"
+ ;;
+
+ i?86-emx-os2 | i?86-*-os2*emx )
+ PRINTABLE_OS_NAME="OS/2"
+ ;;
+
+ i?86-*-msdosdjgpp*)
+ PRINTABLE_OS_NAME="MSDOS/DJGPP"
+ ;;
+
+ *-linux*)
+ PRINTABLE_OS_NAME="GNU/Linux"
+ ;;
+
+ *)
+ PRINTABLE_OS_NAME=`uname -s || echo "Unknown"`
+ ;;
+esac
+
+#
+# Figure out the name of the random device
+#
+case "${host}" in
+ *-openbsd*)
+ NAME_OF_DEV_RANDOM="/dev/srandom"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+
+ *)
+ NAME_OF_DEV_RANDOM="/dev/random"
+ NAME_OF_DEV_URANDOM="/dev/urandom"
+ ;;
+esac
+
+
+AC_ARG_ENABLE(endian-check,
+ AC_HELP_STRING([--disable-endian-check],
+ [disable the endian check and trust the OS provided macros]),
+ endiancheck=$enableval,endiancheck=yes)
+if test x"$endiancheck" = xyes ; then
+ AC_C_BIGENDIAN
+else
+ AC_DEFINE(DISABLED_ENDIAN_CHECK,1,[configure did not test for endianess])
+fi
+
+AC_CHECK_SIZEOF(unsigned short, 2)
+AC_CHECK_SIZEOF(unsigned int, 4)
+AC_CHECK_SIZEOF(unsigned long, 4)
+AC_CHECK_SIZEOF(unsigned long long, 0)
+
+AC_TYPE_UINTPTR_T
+
+if test "$ac_cv_sizeof_unsigned_short" = "0" \
+ || test "$ac_cv_sizeof_unsigned_int" = "0" \
+ || test "$ac_cv_sizeof_unsigned_long" = "0"; then
+ AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]);
+fi
+
+# Do we have any 64-bit data types?
+if test "$ac_cv_sizeof_unsigned_int" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long" != "8" \
+ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \
+ && test "$ac_cv_sizeof_uint64_t" != "8"; then
+ AC_MSG_WARN([No 64-bit types. Disabling TIGER/192, SHA-384, and SHA-512])
+else
+ available_digests="$available_digests $available_digests_64"
+fi
+
+# If not specified otherwise, all available algorithms will be
+# included.
+default_ciphers="$available_ciphers"
+default_pubkey_ciphers="$available_pubkey_ciphers"
+default_digests="$available_digests"
+
+# Substitutions to set generated files in a Emacs buffer to read-only.
+AC_SUBST(emacs_local_vars_begin, ['Local Variables:'])
+AC_SUBST(emacs_local_vars_read_only, ['buffer-read-only: t'])
+AC_SUBST(emacs_local_vars_end, ['End:'])
+
+############################
+## Command line switches. ##
+############################
+
+# Implementation of the --enable-ciphers switch.
+AC_ARG_ENABLE(ciphers,
+ AC_HELP_STRING([--enable-ciphers=ciphers],
+ [select the symmetric ciphers to include]),
+ [enabled_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_ciphers=""])
+if test "x$enabled_ciphers" = "x" \
+ -o "$enabled_ciphers" = "yes" \
+ -o "$enabled_ciphers" = "no"; then
+ enabled_ciphers=$default_ciphers
+fi
+AC_MSG_CHECKING([which symmetric ciphers to include])
+for cipher in $enabled_ciphers; do
+ LIST_MEMBER($cipher, $available_ciphers)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported cipher "$cipher" specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_ciphers])
+
+# Implementation of the --enable-pubkey-ciphers switch.
+AC_ARG_ENABLE(pubkey-ciphers,
+ AC_HELP_STRING([--enable-pubkey-ciphers=ciphers],
+ [select the public-key ciphers to include]),
+ [enabled_pubkey_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_pubkey_ciphers=""])
+if test "x$enabled_pubkey_ciphers" = "x" \
+ -o "$enabled_pubkey_ciphers" = "yes" \
+ -o "$enabled_pubkey_ciphers" = "no"; then
+ enabled_pubkey_ciphers=$default_pubkey_ciphers
+fi
+AC_MSG_CHECKING([which public-key ciphers to include])
+for cipher in $enabled_pubkey_ciphers; do
+ LIST_MEMBER($cipher, $available_pubkey_ciphers)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported public-key cipher specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_pubkey_ciphers])
+
+# Implementation of the --enable-digests switch.
+AC_ARG_ENABLE(digests,
+ AC_HELP_STRING([--enable-digests=digests],
+ [select the message digests to include]),
+ [enabled_digests=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`],
+ [enabled_digests=""])
+if test "x$enabled_digests" = "x" \
+ -o "$enabled_digests" = "yes" \
+ -o "$enabled_digests" = "no"; then
+ enabled_digests=$default_digests
+fi
+AC_MSG_CHECKING([which message digests to include])
+for digest in $enabled_digests; do
+ LIST_MEMBER($digest, $available_digests)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported message digest specified])
+ fi
+done
+AC_MSG_RESULT([$enabled_digests])
+
+# Implementation of the --enable-random switch.
+AC_ARG_ENABLE(random,
+ AC_HELP_STRING([--enable-random=name],
+ [select which random number generator to use]),
+ [random=`echo $enableval | tr '[A-Z]' '[a-z]'`],
+ [])
+if test "x$random" = "x" -o "$random" = "yes" -o "$random" = "no"; then
+ random=default
+fi
+AC_MSG_CHECKING([which random module to use])
+if test "$random" != "default" -a "$random" != "auto"; then
+ LIST_MEMBER($random, $available_random_modules)
+ if test "$found" = "0"; then
+ AC_MSG_ERROR([unsupported random module specified])
+ fi
+fi
+AC_MSG_RESULT($random)
+
+# Implementation of the --disable-dev-random switch.
+AC_MSG_CHECKING([whether use of /dev/random is requested])
+AC_ARG_ENABLE(dev-random,
+[ --disable-dev-random disable the use of dev random],
+ try_dev_random=$enableval, try_dev_random=yes)
+AC_MSG_RESULT($try_dev_random)
+
+# Implementation of the --with-egd-socket switch.
+AC_ARG_WITH(egd-socket,
+ [ --with-egd-socket=NAME Use NAME for the EGD socket)],
+ egd_socket_name="$withval", egd_socket_name="" )
+AC_DEFINE_UNQUOTED(EGD_SOCKET_NAME, "$egd_socket_name",
+ [Define if you don't want the default EGD socket name.
+ For details see cipher/rndegd.c])
+
+# Implementation of the --enable-random-daemon
+AC_MSG_CHECKING([whether the experimental random daemon is requested])
+AC_ARG_ENABLE([random-daemon],
+ AC_HELP_STRING([--enable-random-daemon],
+ [Build and support the experimental gcryptrnd]),
+ [use_random_daemon=$enableval],
+ [use_random_daemon=no])
+AC_MSG_RESULT($use_random_daemon)
+if test x$use_random_daemon = xyes ; then
+ AC_DEFINE(USE_RANDOM_DAEMON,1,
+ [Define to support the experimental random daemon])
+fi
+AM_CONDITIONAL(USE_RANDOM_DAEMON, test x$use_random_daemon = xyes)
+
+
+# Implementation of --disable-asm.
+AC_MSG_CHECKING([whether MPI assembler modules are requested])
+AC_ARG_ENABLE([asm],
+ AC_HELP_STRING([--disable-asm],
+ [Disable MPI assembler modules]),
+ [try_asm_modules=$enableval],
+ [try_asm_modules=yes])
+AC_MSG_RESULT($try_asm_modules)
+
+# Implementation of the --enable-m-guard switch.
+AC_MSG_CHECKING([whether memory guard is requested])
+AC_ARG_ENABLE(m-guard,
+ AC_HELP_STRING([--enable-m-guard],
+ [Enable memory guard facility]),
+ [use_m_guard=$enableval], [use_m_guard=no])
+AC_MSG_RESULT($use_m_guard)
+if test "$use_m_guard" = yes ; then
+ AC_DEFINE(M_GUARD,1,[Define to use the (obsolete) malloc guarding feature])
+fi
+
+# Implementation of the --with-capabilities switch.
+# Check whether we want to use Linux capabilities
+AC_MSG_CHECKING([whether use of capabilities is requested])
+AC_ARG_WITH(capabilities,
+ AC_HELP_STRING([--with-capabilities],
+ [Use linux capabilities [default=no]]),
+ [use_capabilities="$withval"],[use_capabilities=no])
+AC_MSG_RESULT($use_capabilities)
+
+# Implementation of the --enable-hmac-binary-check.
+AC_MSG_CHECKING([whether a HMAC binary check is requested])
+AC_ARG_ENABLE(hmac-binary-check,
+ AC_HELP_STRING([--enable-hmac-binary-check],
+ [Enable library integrity check]),
+ [use_hmac_binary_check=$enableval],
+ [use_hmac_binary_check=no])
+AC_MSG_RESULT($use_hmac_binary_check)
+if test "$use_hmac_binary_check" = yes ; then
+ AC_DEFINE(ENABLE_HMAC_BINARY_CHECK,1,
+ [Define to support an HMAC based integrity check])
+fi
+
+
+# Implementation of the --disable-padlock-support switch.
+AC_MSG_CHECKING([whether padlock support is requested])
+AC_ARG_ENABLE(padlock-support,
+ AC_HELP_STRING([--disable-padlock-support],
+ [Disable support for the PadLock Engine of VIA processors]),
+ padlocksupport=$enableval,padlocksupport=yes)
+AC_MSG_RESULT($padlocksupport)
+if test x"$padlocksupport" = xyes ; then
+ AC_DEFINE(ENABLE_PADLOCK_SUPPORT, 1,
+ [Enable support for the PadLock engine.])
+fi
+
+# Implementation of the --disable-aesni-support switch.
+AC_MSG_CHECKING([whether AESNI support is requested])
+AC_ARG_ENABLE(aesni-support,
+ AC_HELP_STRING([--disable-aesni-support],
+ [Disable support for the Intel AES-NI instructions]),
+ aesnisupport=$enableval,aesnisupport=yes)
+AC_MSG_RESULT($aesnisupport)
+if test x"$aesnisupport" = xyes ; then
+ AC_DEFINE(ENABLE_AESNI_SUPPORT, 1,
+ [Enable support for Intel AES-NI instructions.])
+fi
+
+# Implementation of the --disable-O-flag-munging switch.
+AC_MSG_CHECKING([whether a -O flag munging is requested])
+AC_ARG_ENABLE([O-flag-munging],
+ AC_HELP_STRING([--disable-O-flag-munging],
+ [Disable modification of the cc -O flag]),
+ [enable_o_flag_munging=$enableval],
+ [enable_o_flag_munging=yes])
+AC_MSG_RESULT($enable_o_flag_munging)
+AM_CONDITIONAL(ENABLE_O_FLAG_MUNGING, test "$enable_o_flag_munging" = "yes")
+
+
+
+AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
+ [A human readable text with the name of the OS])
+
+# For some systems we know that we have ld_version scripts.
+# Use it then as default.
+have_ld_version_script=no
+case "${host}" in
+ *-*-linux*)
+ have_ld_version_script=yes
+ ;;
+ *-*-gnu*)
+ have_ld_version_script=yes
+ ;;
+esac
+AC_ARG_ENABLE([ld-version-script],
+ AC_HELP_STRING([--enable-ld-version-script],
+ [enable/disable use of linker version script.
+ (default is system dependent)]),
+ [have_ld_version_script=$enableval],
+ [ : ] )
+AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
+
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM",
+ [defined to the name of the strong random device])
+AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM",
+ [defined to the name of the weaker random device])
+
+
+###############################
+#### Checks for libraries. ####
+###############################
+
+#
+# gpg-error is required.
+#
+AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION")
+if test "x$GPG_ERROR_LIBS" = "x"; then
+ AC_MSG_ERROR([libgpg-error is needed.
+ See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ .])
+fi
+
+AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GCRYPT,
+ [The default error source for libgcrypt.])
+
+#
+# Check whether the GNU Pth library is available. We require this
+# to build the optional gcryptrnd program.
+#
+AC_ARG_WITH(pth-prefix,
+ AC_HELP_STRING([--with-pth-prefix=PFX],
+ [prefix where GNU Pth is installed (optional)]),
+ pth_config_prefix="$withval", pth_config_prefix="")
+if test x$pth_config_prefix != x ; then
+ PTH_CONFIG="$pth_config_prefix/bin/pth-config"
+fi
+if test "$use_random_daemon" = "yes"; then
+ AC_PATH_PROG(PTH_CONFIG, pth-config, no)
+ if test "$PTH_CONFIG" = "no"; then
+ AC_MSG_WARN([[
+***
+*** To build the Libgcrypt's random number daemon
+*** we need the support of the GNU Portable Threads Library.
+*** Download it from ftp://ftp.gnu.org/gnu/pth/
+*** On a Debian GNU/Linux system you might want to try
+*** apt-get install libpth-dev
+***]])
+ else
+ GNUPG_PTH_VERSION_CHECK([1.3.7])
+ if test $have_pth = yes; then
+ PTH_CFLAGS=`$PTH_CONFIG --cflags`
+ PTH_LIBS=`$PTH_CONFIG --ldflags`
+ PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`"
+ AC_DEFINE(USE_GNU_PTH, 1,
+ [Defined if the GNU Portable Thread Library should be used])
+ AC_DEFINE(HAVE_PTH, 1,
+ [Defined if the GNU Pth is available])
+ fi
+ fi
+fi
+AC_SUBST(PTH_CFLAGS)
+AC_SUBST(PTH_LIBS)
+
+
+# Solaris needs -lsocket and -lnsl. Unisys system includes
+# gethostbyname in libsocket but needs libnsl for socket.
+AC_SEARCH_LIBS(setsockopt, [socket], ,
+ [AC_SEARCH_LIBS(setsockopt, [socket], , , [-lnsl])])
+AC_SEARCH_LIBS(setsockopt, [nsl])
+
+##################################
+#### Checks for header files. ####
+##################################
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h)
+INSERT_SYS_SELECT_H=
+if test x"$ac_cv_header_sys_select_h" = xyes; then
+ INSERT_SYS_SELECT_H=" include <sys/select.h>"
+fi
+AC_SUBST(INSERT_SYS_SELECT_H)
+
+
+##########################################
+#### Checks for typedefs, structures, ####
+#### and compiler characteristics. ####
+##########################################
+
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_TYPE_SIGNAL
+AC_DECL_SYS_SIGLIST
+AC_TYPE_PID_T
+
+GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF)
+GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF)
+GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF)
+GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF)
+GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF)
+
+gl_TYPE_SOCKLEN_T
+case "${host}" in
+ *-*-mingw32*)
+ # socklen_t may or may not be defined depending on what headers
+ # are included. To be safe we use int as this is the actual type.
+ FALLBACK_SOCKLEN_T="typedef int gcry_socklen_t;"
+ ;;
+ *)
+ if test ".$gl_cv_socklen_t_equiv" = "."; then
+ FALLBACK_SOCKLEN_T="typedef socklen_t gcry_socklen_t;"
+ else
+ FALLBACK_SOCKLEN_T="typedef ${gl_cv_socklen_t_equiv} gcry_socklen_t;"
+ fi
+esac
+AC_SUBST(FALLBACK_SOCKLEN_T)
+
+#
+# Check for ELF visibility support.
+#
+AC_CACHE_CHECK(whether the visibility attribute is supported,
+ gcry_cv_visibility_attribute,
+ [gcry_cv_visibility_attribute=no
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[int foo __attribute__ ((visibility ("hidden"))) = 1;
+ int bar __attribute__ ((visibility ("protected"))) = 1;
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then
+ if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then
+ gcry_cv_visibility_attribute=yes
+ fi
+ fi
+ fi
+ ])
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(for broken visibility attribute,
+ gcry_cv_broken_visibility_attribute,
+ [gcry_cv_broken_visibility_attribute=yes
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[int foo (int x);
+ int bar (int x) __asm__ ("foo")
+ __attribute__ ((visibility ("hidden")));
+ int bar (int x) { return x; }
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep '\.hidden@<:@ _@:>@foo' conftest.s >/dev/null 2>&1;
+ then
+ gcry_cv_broken_visibility_attribute=no
+ fi
+ fi
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(for broken alias attribute,
+ gcry_cv_broken_alias_attribute,
+ [gcry_cv_broken_alias_attribute=yes
+ AC_LANG_CONFTEST([AC_LANG_SOURCE(
+ [[extern int foo (int x) __asm ("xyzzy");
+ int bar (int x) { return x; }
+ extern __typeof (bar) foo __attribute ((weak, alias ("bar")));
+ extern int dfoo;
+ extern __typeof (dfoo) dfoo __asm ("abccb");
+ int dfoo = 1;
+ ]])])
+
+ if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then
+ if grep 'xyzzy' conftest.s >/dev/null 2>&1 && \
+ grep 'abccb' conftest.s >/dev/null 2>&1; then
+ gcry_cv_broken_alias_attribute=no
+ fi
+ fi
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes"; then
+ AC_CACHE_CHECK(if gcc supports -fvisibility=hidden,
+ gcry_cv_gcc_has_f_visibility,
+ [gcry_cv_gcc_has_f_visibility=no
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-fvisibility=hidden"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+ gcry_cv_gcc_has_f_visibility=yes)
+ CFLAGS=$_gcc_cflags_save;
+ ])
+fi
+if test "$gcry_cv_visibility_attribute" = "yes" \
+ && test "$gcry_cv_broken_visibility_attribute" != "yes" \
+ && test "$gcry_cv_broken_alias_attribute" != "yes" \
+ && test "$gcry_cv_gcc_has_f_visibility" = "yes"
+ then
+ AC_DEFINE(GCRY_USE_VISIBILITY, 1,
+ [Define to use the GNU C visibility attribute.])
+ CFLAGS="$CFLAGS -fvisibility=hidden"
+fi
+
+
+#######################################
+#### Checks for library functions. ####
+#######################################
+
+AC_FUNC_VPRINTF
+# We have replacements for these in src/missing-string.c
+AC_CHECK_FUNCS(stpcpy strcasecmp)
+# We have replacements for these in src/g10lib.h
+AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise)
+# Other checks
+AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4)
+AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog)
+AC_CHECK_FUNCS(fcntl ftruncate)
+
+GNUPG_CHECK_MLOCK
+
+#
+# Replacement functions.
+#
+AC_REPLACE_FUNCS([getpid clock])
+
+
+#
+# Check wether it is necessary to link against libdl.
+#
+DL_LIBS=""
+if test "$use_hmac_binary_check" = yes ; then
+ _gcry_save_libs="$LIBS"
+ LIBS=""
+ AC_SEARCH_LIBS(dlopen, c dl,,,)
+ DL_LIBS=$LIBS
+ LIBS="$_gcry_save_libs"
+ LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${DL_LIBS}"
+fi
+AC_SUBST(DL_LIBS)
+
+
+#
+# Check whether we can use Linux capabilities as requested.
+#
+if test "$use_capabilities" = "yes" ; then
+use_capabilities=no
+AC_CHECK_HEADERS(sys/capability.h)
+if test "$ac_cv_header_sys_capability_h" = "yes" ; then
+ AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1)
+ if test "$ac_cv_lib_cap_cap_init" = "yes"; then
+ AC_DEFINE(USE_CAPABILITIES,1,
+ [define if capabilities should be used])
+ LIBS="$LIBS -lcap"
+ use_capabilities=yes
+ fi
+fi
+if test "$use_capabilities" = "no" ; then
+ AC_MSG_WARN([[
+***
+*** The use of capabilities on this system is not possible.
+*** You need a recent Linux kernel and some patches:
+*** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9)
+*** fcap-module-990613.tar.gz (kernel module)
+*** libcap-1.92.tar.gz (user mode library and utilities)
+*** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN
+*** set (filesystems menu). Be warned: This code is *really* ALPHA.
+***]])
+fi
+fi
+
+# Check whether a random device is available.
+if test "$try_dev_random" = yes ; then
+ AC_CACHE_CHECK(for random device, ac_cv_have_dev_random,
+ [if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
+ ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi])
+ if test "$ac_cv_have_dev_random" = yes; then
+ AC_DEFINE(HAVE_DEV_RANDOM,1,
+ [defined if the system supports a random device] )
+ fi
+else
+ AC_MSG_CHECKING(for random device)
+ ac_cv_have_dev_random=no
+ AC_MSG_RESULT(has been disabled)
+fi
+
+# Figure out the random modules for this configuration.
+if test "$random" = "default"; then
+
+ # Select default value.
+ if test "$ac_cv_have_dev_random" = yes; then
+ # Try Linuxish random device.
+ random_modules="linux"
+ else
+ case "${host}" in
+ *-*-mingw32ce*)
+ # WindowsCE random device.
+ random_modules="w32ce"
+ ;;
+ *-*-mingw32*|*-*-cygwin*)
+ # Windows random device.
+ random_modules="w32"
+ ;;
+ *)
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ ;;
+ esac
+ fi
+else
+ if test "$random" = "auto"; then
+ # Build everything, allow to select at runtime.
+ random_modules="$auto_random_modules"
+ else
+ random_modules="$random"
+ fi
+fi
+
+
+#
+# Setup assembler stuff.
+#
+GNUPG_SYS_SYMBOL_UNDERSCORE()
+AC_ARG_ENABLE(mpi-path,
+ AC_HELP_STRING([--enable-mpi-path=EXTRA_PATH],
+ [prepend EXTRA_PATH to list of CPU specific optimizations]),
+ mpi_extra_path="$enableval",mpi_extra_path="")
+AC_MSG_CHECKING(for mpi assembler functions)
+if test -f $srcdir/mpi/config.links ; then
+ . $srcdir/mpi/config.links
+ AC_CONFIG_LINKS("$mpi_ln_list")
+ ac_cv_mpi_sflags="$mpi_sflags"
+ AC_MSG_RESULT(done)
+else
+ AC_MSG_RESULT(failed)
+ AC_MSG_ERROR([mpi/config.links missing!])
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+AC_SUBST(MPI_SFLAGS)
+
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_ADD1, test "$mpi_mod_asm_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_SUB1, test "$mpi_mod_asm_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL1, test "$mpi_mod_asm_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL2, test "$mpi_mod_asm_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL3, test "$mpi_mod_asm_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_LSHIFT, test "$mpi_mod_asm_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_RSHIFT, test "$mpi_mod_asm_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV, test "$mpi_mod_asm_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV_QRNND, test "$mpi_mod_asm_udiv_qrnnd" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_ADD1, test "$mpi_mod_c_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_SUB1, test "$mpi_mod_c_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL1, test "$mpi_mod_c_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL2, test "$mpi_mod_c_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL3, test "$mpi_mod_c_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_LSHIFT, test "$mpi_mod_c_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_RSHIFT, test "$mpi_mod_c_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV, test "$mpi_mod_c_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes)
+
+if test "$is_development_version" = "yes"; then
+ AC_DEFINE(IS_DEVELOPMENT_VERSION,1,
+ [Defined if this is not a regular release])
+fi
+
+
+AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes)
+
+
+# This is handy for debugging so the compiler doesn't rearrange
+# things and eliminate variables.
+AC_ARG_ENABLE(optimization,
+ AC_HELP_STRING([--disable-optimization],
+ [disable compiler optimization]),
+ [if test $enableval = no ; then
+ CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'`
+ fi])
+
+# CFLAGS mangling when using gcc.
+if test "$GCC" = yes; then
+ CFLAGS="$CFLAGS -Wall"
+ if test "$USE_MAINTAINER_MODE" = "yes"; then
+ CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes"
+ CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security"
+
+ # If -Wno-missing-field-initializers is supported we can enable a
+ # a bunch of really useful warnings.
+ AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wno-missing-field-initializers"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),_gcc_wopt=yes,_gcc_wopt=no)
+ AC_MSG_RESULT($_gcc_wopt)
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast"
+ CFLAGS="$CFLAGS -Wwrite-strings"
+ CFLAGS="$CFLAGS -Wdeclaration-after-statement"
+ CFLAGS="$CFLAGS -Wno-missing-field-initializers"
+ CFLAGS="$CFLAGS -Wno-sign-compare"
+ fi
+
+ AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
+ _gcc_cflags_save=$CFLAGS
+ CFLAGS="-Wpointer-arith"
+ AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),_gcc_wopt=yes,_gcc_wopt=no)
+ AC_MSG_RESULT($_gcc_wopt)
+ CFLAGS=$_gcc_cflags_save;
+ if test x"$_gcc_wopt" = xyes ; then
+ CFLAGS="$CFLAGS -Wpointer-arith"
+ fi
+ fi
+
+fi
+
+# Check whether as(1) supports a noeexecstack feature. This test
+# includes an override option.
+CL_AS_NOEXECSTACK
+
+
+AC_SUBST(LIBGCRYPT_CONFIG_API_VERSION)
+AC_SUBST(LIBGCRYPT_CONFIG_LIBS)
+AC_SUBST(LIBGCRYPT_CONFIG_CFLAGS)
+AC_SUBST(LIBGCRYPT_CONFIG_HOST)
+AC_SUBST(LIBGCRYPT_THREAD_MODULES)
+
+AC_CONFIG_COMMANDS([gcrypt-conf],[[
+chmod +x src/libgcrypt-config
+]],[[
+prefix=$prefix
+exec_prefix=$exec_prefix
+libdir=$libdir
+datadir=$datadir
+DATADIRNAME=$DATADIRNAME
+]])
+
+#####################
+#### Conclusion. ####
+#####################
+
+# Define conditional sources and config.h symbols depending on the
+# selected ciphers, pubkey-ciphers, digests and random modules.
+
+LIST_MEMBER(arcfour, $enabled_ciphers)
+if test "$found" = "1"; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo"
+ AC_DEFINE(USE_ARCFOUR, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(blowfish, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo"
+ AC_DEFINE(USE_BLOWFISH, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(cast5, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo"
+ AC_DEFINE(USE_CAST5, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(des, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo"
+ AC_DEFINE(USE_DES, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(aes, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo"
+ AC_DEFINE(USE_AES, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(twofish, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo"
+ AC_DEFINE(USE_TWOFISH, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(serpent, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
+ AC_DEFINE(USE_SERPENT, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(rfc2268, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo"
+ AC_DEFINE(USE_RFC2268, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(seed, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS seed.lo"
+ AC_DEFINE(USE_SEED, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(camellia, $enabled_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo"
+ AC_DEFINE(USE_CAMELLIA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(dsa, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo"
+ AC_DEFINE(USE_DSA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(rsa, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS rsa.lo"
+ AC_DEFINE(USE_RSA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(elgamal, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS elgamal.lo"
+ AC_DEFINE(USE_ELGAMAL, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(ecc, $enabled_pubkey_ciphers)
+if test "$found" = "1" ; then
+ GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ecc.lo"
+ AC_DEFINE(USE_ECC, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(crc, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo"
+ AC_DEFINE(USE_CRC, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(md4, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo"
+ AC_DEFINE(USE_MD4, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(md5, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS md5.lo"
+ AC_DEFINE(USE_MD5, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(sha256, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
+ AC_DEFINE(USE_SHA256, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(sha512, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo"
+ AC_DEFINE(USE_SHA512, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(tiger, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo"
+ AC_DEFINE(USE_TIGER, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(whirlpool, $enabled_digests)
+if test "$found" = "1" ; then
+ GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo"
+ AC_DEFINE(USE_WHIRLPOOL, 1, [Defined if this module should be included])
+fi
+
+# rmd160 and sha1 should be included always.
+GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo"
+AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included])
+AC_DEFINE(USE_SHA1, 1, [Defined if this module should be included])
+
+LIST_MEMBER(linux, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo"
+ AC_DEFINE(USE_RNDLINUX, 1, [Defined if the /dev/random RNG should be used.])
+fi
+
+LIST_MEMBER(unix, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndunix.lo"
+ AC_DEFINE(USE_RNDUNIX, 1, [Defined if the default Unix RNG should be used.])
+ print_egd_notice=yes
+fi
+
+LIST_MEMBER(egd, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndegd.lo"
+ AC_DEFINE(USE_RNDEGD, 1, [Defined if the EGD based RNG should be used.])
+fi
+
+LIST_MEMBER(w32, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32.lo"
+ AC_DEFINE(USE_RNDW32, 1,
+ [Defined if the Windows specific RNG should be used.])
+fi
+
+LIST_MEMBER(w32ce, $random_modules)
+if test "$found" = "1" ; then
+ GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+ AC_DEFINE(USE_RNDW32CE, 1,
+ [Defined if the WindowsCE specific RNG should be used.])
+fi
+
+AC_SUBST([GCRYPT_CIPHERS])
+AC_SUBST([GCRYPT_PUBKEY_CIPHERS])
+AC_SUBST([GCRYPT_DIGESTS])
+AC_SUBST([GCRYPT_RANDOM])
+
+AC_SUBST(LIBGCRYPT_CIPHERS, $enabled_ciphers)
+AC_SUBST(LIBGCRYPT_PUBKEY_CIPHERS, $enabled_pubkey_ciphers)
+AC_SUBST(LIBGCRYPT_DIGESTS, $enabled_digests)
+
+# For printing the configuration we need a colon separated list of
+# algorithm names.
+tmp=`echo "$enabled_ciphers" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_CIPHERS, "$tmp",
+ [List of available cipher algorithms])
+tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_PUBKEY_CIPHERS, "$tmp",
+ [List of available public key cipher algorithms])
+tmp=`echo "$enabled_digests" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_DIGESTS, "$tmp",
+ [List of available digest algorithms])
+
+
+
+# Generate extended version information for W32.
+if test "$have_w32_system" = yes; then
+ BUILD_TIMESTAMP=`date --iso-8601=minutes`
+ changequote(,)dnl
+ BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
+ changequote([,])dnl
+ BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}"
+fi
+AC_SUBST(BUILD_REVISION)
+AC_SUBST(BUILD_TIMESTAMP)
+AC_SUBST(BUILD_FILEVERSION)
+AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION",
+ [Subversion revision used to build this package])
+
+
+
+# And create the files.
+AC_CONFIG_FILES([
+Makefile
+m4/Makefile
+compat/Makefile
+mpi/Makefile
+cipher/Makefile
+random/Makefile
+doc/Makefile
+src/Makefile
+src/gcrypt.h
+src/libgcrypt-config
+src/versioninfo.rc
+tests/Makefile
+])
+AC_OUTPUT
+
+# Give some feedback
+echo "
+ Libgcrypt v${VERSION} has been configured as follows:
+
+ Platform: $PRINTABLE_OS_NAME ($host)
+ Enabled cipher algorithms: $enabled_ciphers
+ Enabled digest algorithms: $enabled_digests
+ Enabled pubkey algorithms: $enabled_pubkey_ciphers
+ Random number generator: $random
+ Using linux capabilities: $use_capabilities
+ Try using Padlock crypto: $padlocksupport
+ Try using AES-NI crypto: $aesnisupport
+"
+
+if test "$print_egd_notice" = "yes"; then
+cat <<G10EOF
+
+ The performance of the Unix random gatherer module (rndunix) is not
+ very good and it does not keep the entropy pool over multiple
+ invocations of Libgcrypt base applications. The suggested way to
+ overcome this problem is to use the
+
+ Entropy Gathering Daemon (EGD)
+
+ which provides a entropy source for the whole system. It is written
+ in Perl and available at the GnuPG FTP servers. To enable EGD you
+ should rerun configure with the option "--enable-static-rnd=egd".
+ For more information consult the GnuPG webpages:
+
+ http://www.gnupg.org/download.html#egd
+
+G10EOF
+fi
+
+if test -n "$gpl"; then
+ echo "Please note that you are building a version of Libgcrypt with"
+ echo " $gpl"
+ echo "included. These parts are licensed under the GPL and thus the"
+ echo "use of this library has to comply with the conditions of the GPL."
+fi
--- /dev/null
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2006-10-15.18
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software
+# Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+ '')
+ echo "$0: No command. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+ depmode Dependency tracking mode.
+ source Source file read by `PROGRAMS ARGS'.
+ object Object file output by `PROGRAMS ARGS'.
+ DEPDIR directory where to store dependencies.
+ depfile Dependency file to output.
+ tmpdepfile Temporary file to use when outputing dependencies.
+ libtool Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "depcomp $scriptversion"
+ exit $?
+ ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+ echo "depcomp: Variables source, object and depmode must be set" 1>&2
+ exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+ sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags. We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write. Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+ # HP compiler uses -M and no extra arg.
+ gccflag=-M
+ depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+ # This is just like dashmstdout with a different argument.
+ dashmflag=-xM
+ depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want. Yay! Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff. Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am. Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+ for arg
+ do
+ case $arg in
+ -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+ *) set fnord "$@" "$arg" ;;
+ esac
+ shift # fnord
+ shift # $arg
+ done
+ "$@"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ mv "$tmpdepfile" "$depfile"
+ ;;
+
+gcc)
+## There are various ways to get dependency output from gcc. Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+## up in a subdir. Having to rename by hand is ugly.
+## (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+## -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+## than renaming).
+ if test -z "$gccflag"; then
+ gccflag=-MD,
+ fi
+ "$@" -Wp,"$gccflag$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+ sed -e 's/^[^:]*: / /' \
+ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header). We avoid this by adding
+## dummy dependencies for each header file. Too bad gcc doesn't do
+## this for us directly.
+ tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'. On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp)
+ # This case exists only to let depend.m4 do its work. It works by
+ # looking at the text of this script. This case will never be run,
+ # since it is checked for above.
+ exit 1
+ ;;
+
+sgi)
+ if test "$libtool" = yes; then
+ "$@" "-Wp,-MDupdate,$tmpdepfile"
+ else
+ "$@" -MDupdate "$tmpdepfile"
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+
+ if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
+ echo "$object : \\" > "$depfile"
+
+ # Clip off the initial element (the dependent). Don't try to be
+ # clever and replace this with sed code, as IRIX sed won't handle
+ # lines with more than a fixed number of characters (4096 in
+ # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
+ # the IRIX cc adds comments like `#:fec' to the end of the
+ # dependency line.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+ tr '
+' ' ' >> $depfile
+ echo >> $depfile
+
+ # The second pass generates a dummy entry for each header file.
+ tr ' ' '
+' < "$tmpdepfile" \
+ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+ >> $depfile
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+aix)
+ # The C for AIX Compiler uses -M and outputs the dependencies
+ # in a .u file. In older versions, this file always lives in the
+ # current directory. Also, the AIX compiler puts `$object:' at the
+ # start of each line; $object doesn't have directory information.
+ # Version 6 uses the directory in both cases.
+ stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+ tmpdepfile="$stripped.u"
+ if test "$libtool" = yes; then
+ "$@" -Wc,-M
+ else
+ "$@" -M
+ fi
+ stat=$?
+
+ if test -f "$tmpdepfile"; then :
+ else
+ stripped=`echo "$stripped" | sed 's,^.*/,,'`
+ tmpdepfile="$stripped.u"
+ fi
+
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+
+ if test -f "$tmpdepfile"; then
+ outname="$stripped.o"
+ # Each line is of the form `foo.o: dependent.h'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+ sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+ else
+ # The sourcefile does not contain any dependencies, so just
+ # store a dummy comment line, to avoid errors with the Makefile
+ # "include basename.Plo" scheme.
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+icc)
+ # Intel's C compiler understands `-MD -MF file'. However on
+ # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+ # ICC 7.0 will fill foo.d with something like
+ # foo.o: sub/foo.c
+ # foo.o: sub/foo.h
+ # which is wrong. We want:
+ # sub/foo.o: sub/foo.c
+ # sub/foo.o: sub/foo.h
+ # sub/foo.c:
+ # sub/foo.h:
+ # ICC 7.1 will output
+ # foo.o: sub/foo.c sub/foo.h
+ # and will wrap long lines using \ :
+ # foo.o: sub/foo.c ... \
+ # sub/foo.h ... \
+ # ...
+
+ "$@" -MD -MF "$tmpdepfile"
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile"
+ exit $stat
+ fi
+ rm -f "$depfile"
+ # Each line is of the form `foo.o: dependent.h',
+ # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+ # Do two passes, one to just change these to
+ # `$object: dependent.h' and one to simply `dependent.h:'.
+ sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+ # Some versions of the HPUX 10.20 sed can't process this invocation
+ # correctly. Breaking it into two sed invocations is a workaround.
+ sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+ sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+hp2)
+ # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+ # compilers, which have integrated preprocessors. The correct option
+ # to use with these is +Maked; it writes dependencies to a file named
+ # 'foo.d', which lands next to the object file, wherever that
+ # happens to be.
+ # Much of this is similar to the tru64 case; see comments there.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+ if test "$libtool" = yes; then
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir.libs/$base.d
+ "$@" -Wc,+Maked
+ else
+ tmpdepfile1=$dir$base.d
+ tmpdepfile2=$dir$base.d
+ "$@" +Maked
+ fi
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+ # Add `dependent.h:' lines.
+ sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile" "$tmpdepfile2"
+ ;;
+
+tru64)
+ # The Tru64 compiler uses -MD to generate dependencies as a side
+ # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+ # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+ # dependencies in `foo.d' instead, so we check for that too.
+ # Subdirectories are respected.
+ dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+ test "x$dir" = "x$object" && dir=
+ base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+ if test "$libtool" = yes; then
+ # With Tru64 cc, shared objects can also be used to make a
+ # static library. This mechanism is used in libtool 1.4 series to
+ # handle both shared and static libraries in a single compilation.
+ # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+ #
+ # With libtool 1.5 this exception was removed, and libtool now
+ # generates 2 separate objects for the 2 libraries. These two
+ # compilations output dependencies in $dir.libs/$base.o.d and
+ # in $dir$base.o.d. We have to check for both files, because
+ # one of the two compilations can be disabled. We should prefer
+ # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+ # automatically cleaned when .libs/ is deleted, while ignoring
+ # the former would cause a distcleancheck panic.
+ tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
+ tmpdepfile2=$dir$base.o.d # libtool 1.5
+ tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
+ tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
+ "$@" -Wc,-MD
+ else
+ tmpdepfile1=$dir$base.o.d
+ tmpdepfile2=$dir$base.d
+ tmpdepfile3=$dir$base.d
+ tmpdepfile4=$dir$base.d
+ "$@" -MD
+ fi
+
+ stat=$?
+ if test $stat -eq 0; then :
+ else
+ rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ exit $stat
+ fi
+
+ for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+ do
+ test -f "$tmpdepfile" && break
+ done
+ if test -f "$tmpdepfile"; then
+ sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+ # That's a tab and a space in the [].
+ sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+ else
+ echo "#dummy" > "$depfile"
+ fi
+ rm -f "$tmpdepfile"
+ ;;
+
+#nosideeffect)
+ # This comment above is used by automake to tell side-effect
+ # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ test -z "$dashmflag" && dashmflag=-M
+ # Require at least two characters before searching for `:'
+ # in the target name. This is to cope with DOS-style filenames:
+ # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+ "$@" $dashmflag |
+ sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+dashXmstdout)
+ # This case only exists to satisfy depend.m4. It is never actually
+ # run, as this mode is specially recognized in the preamble.
+ exit 1
+ ;;
+
+makedepend)
+ "$@" || exit $?
+ # Remove any Libtool call
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+ # X makedepend
+ shift
+ cleared=no
+ for arg in "$@"; do
+ case $cleared in
+ no)
+ set ""; shift
+ cleared=yes ;;
+ esac
+ case "$arg" in
+ -D*|-I*)
+ set fnord "$@" "$arg"; shift ;;
+ # Strip any option that makedepend may not understand. Remove
+ # the object too, otherwise makedepend will parse it as a source file.
+ -*|$object)
+ ;;
+ *)
+ set fnord "$@" "$arg"; shift ;;
+ esac
+ done
+ obj_suffix="`echo $object | sed 's/^.*\././'`"
+ touch "$tmpdepfile"
+ ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+ rm -f "$depfile"
+ cat < "$tmpdepfile" > "$depfile"
+ sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly. Breaking it into two sed invocations is a workaround.
+ sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile" "$tmpdepfile".bak
+ ;;
+
+cpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout.
+ "$@" || exit $?
+
+ # Remove the call to Libtool.
+ if test "$libtool" = yes; then
+ while test $1 != '--mode=compile'; do
+ shift
+ done
+ shift
+ fi
+
+ # Remove `-o $object'.
+ IFS=" "
+ for arg
+ do
+ case $arg in
+ -o)
+ shift
+ ;;
+ $object)
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift # fnord
+ shift # $arg
+ ;;
+ esac
+ done
+
+ "$@" -E |
+ sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+ sed '$ s: \\$::' > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ cat < "$tmpdepfile" >> "$depfile"
+ sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+msvisualcpp)
+ # Important note: in order to support this mode, a compiler *must*
+ # always write the preprocessed file to stdout, regardless of -o,
+ # because we must use -o when running libtool.
+ "$@" || exit $?
+ IFS=" "
+ for arg
+ do
+ case "$arg" in
+ "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+ set fnord "$@"
+ shift
+ shift
+ ;;
+ *)
+ set fnord "$@" "$arg"
+ shift
+ shift
+ ;;
+ esac
+ done
+ "$@" -E |
+ sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+ rm -f "$depfile"
+ echo "$object : \\" > "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
+ echo " " >> "$depfile"
+ . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+ rm -f "$tmpdepfile"
+ ;;
+
+none)
+ exec "$@"
+ ;;
+
+*)
+ echo "Unknown depmode $depmode" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+2009-10-28 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Multi-Threading): Add examples.
+
+2009-07-02 Daiki Ueno <ueno@unixuser.org>
+
+ * gcrypt.texi (Working with S-expressions): Describe format
+ character '%S'. Typo fixes. Fixes bug#1079.
+
+2009-05-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Clarified that
+ keylengths are in bytes.
+
+2009-04-02 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Self-Tests): Fix register fucntion names.
+
+2009-02-22 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Memory allocation): Fix describion of gcry-calloc.
+ Reported by Sergi Blanch i Torné.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Cryptographic Functions): Explain the domain
+ parameter for key generation.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Updates for pubkey generation.
+
+2008-10-20 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Error handler): Fix description of
+ gcry_handler_no_mem_t. Reported by Patrick Strateman. desribe
+ what what the error handler is expected to do. Fixes bug #961.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (FIPS Mode): Add state transition Error to Error.
+ * fips-fsm.fig: Ditto.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Add a couple of index items.
+ (FIPS Mode): Reflect recent changes.
+ (Controlling the library): Describe gcry_fips_mode_active.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (FIPS Mode): Describe new transitions 18 and 19.
+ * fips-fsm.fig: Add new transitions.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Fold the two FIPS appendices into one.
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Public-Key Subsystem Architecture): Explain RSA
+ blinding.
+
+2008-09-08 Marcus Brinkmann <marcus@g10code.com>
+
+ * gcrypt.texi: Some typos fixed.
+
+2008-09-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Formatting cleanups.
+ * lgpl.texi (Library Copying): Replace @appendix by @unnumbered.
+ * gpl.texi (Copying): Ditto.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (online): Take care of development versions.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Top): Remove the detailmenu.
+ (Public Key Cryptographi (II)): Move into a section of the PK
+ interface description.
+ (Hashing): Move after the encryption chapters.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Remove
+ GCRYCTL_DUMP_CONFIG because it is not implemented.
+ (Initializing the library): Describe initialization steps with
+ regard to secure memory.
+
+ * gcrypt.texi (Working with cipher handles): Adjust for
+ implementation changes of gcry_cipher_setkey, gcry_cipher_setiv and
+ gcry_cipher_setctr.
+
+2008-01-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Add remark that the
+ theoritical attack on a seed file is not feasible under Linux.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Various minor corrections as reported by Elie De
+ Brauer more than a year ago.
+
+2007-06-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Clarified the use of
+ GCRYCTL_ENABLE_QUICK_RANDOM.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * HACKING: New. Two items by Marcus.
+ * README.apichanges: Move from .. to here.
+ * Makefile.am (EXTRA_DIST): Add new files.
+
+2007-04-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.texi: Fix some typos.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (General public-key related Functions): Typo.
+
+2006-09-19 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (online): New target.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi (Available ciphers): Add missing ciphers.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2005-04-25)
+
+ * gcrypt.texi: Document SHA-224 and typo fixes.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * gcrypt.texi (Available cipher modes): Typo fix, add a little
+ more detail on cipher modes vs cipher algorithms.
+
+2006-01-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added documentation for more gcry_control commands.
+
+ * gcrypt.texi: Fixed several typos; thanks to Tommi Vainikainen.
+
+2005-12-16 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (MPI formats): Fix return types of functions:
+ gcry_mpi_scan, gcry_mpi_print, gcry_mpi_aprint.
+
+2005-11-26 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: New chapter: Prime numbers.
+
+2005-11-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (MPI formats): Document that for gcry_mpi_scan and
+ in the case of GCRYMPI_FMT_HEX, BUFLEN must be zero.
+
+2005-10-31 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added more gcry_control related descriptions.
+
+2005-10-16 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Controlling the library): Start documenting the
+ existing control commands.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available hash algorithms): Add entry for Whirlpool.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with IO objects): Document ac io objects;
+ adjust ac scheme functions, which do now use io objects.
+
+2005-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Clarify CTS mode.
+
+2005-02-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Fixed direntry.
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Using cryptographic functions): Document new
+ encoding and scheme crypto functionality.
+
+2005-02-03 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Fixed several typos; thanks to Michele Baldessari.
+
+2005-01-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.texi: Updated to use @copying. Fixed list of copyright
+ years; we had real changes in 2004. Fixed some formatting issues.
+
+2004-08-24 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Miscellaneous): Document gcry_mpi_randomize.
+
+2004-08-18 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Multi Threading): Document
+ GCRY_THREAD_OPTION_PTH_IMPL, GCRY_THREAD_OPTION_PTHREAD_IMPL.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * gcrypt.texi: Merged several fixes reported by Umberto Salsi.
+
+2004-04-08 Moritz Schulte <moritz@g10code.de>
+
+ * gcrypt.texi (Multi Threading): Typo fix.
+
+2004-03-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.texi (Multi Threading): Partially document new thread
+ support.
+
+2004-02-24 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Calculations): Typo fix.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.texi (General cipher functions): Fixed descriptions of
+ the arguments for GCRYCTL_GET_KEYLEN, GCRYCTL_GET_BLKLEN; reported
+ by Randy.
+
+2004-01-14 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.texi (Public Key cryptography II): Adjusted to new
+ gcry_ac_* API; document flags.
+
+2003-12-04 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (gcrypt_TEXINFOS): Removed fdl.texi.
+
+2003-12-03 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Changed license from FDL to GPL because this is a
+ reference manual only useful along with actual code.
+ * fdl.texi: Removed.
+
+ * gcrypt.texi: Minor cleanups
+ (Working with keys): Clarified generation of RSA's E parameter.
+ (Multi Threading): Clarified.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Working with S-expressions): Added "%b".
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Retrieving random numbers): Add gcry_create_nonce.
+
+2003-08-30 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Working with hash algorithms): Clarified that HMAC
+ does not work with all algorithms.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available asymmetric algorithms): Mention
+ GCRY_AC_ELG_E.
+
+2003-07-28 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with keys): Mention that gcry_pk_testkey
+ and gcry_ac_key_test only verify private keys.
+ (Working with keys): Fix typo.
+ (General public-key related Functions): Fixed some sentences,
+ thanks to Neil Spring.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Adjusted description of gcry_mpi_scan and
+ gcry_mpi_dump. Add gcry_mpi_dump.
+
+2003-07-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Added more documentation for the register
+ mechanism.
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Misc): Add a warning on the use of opaque values.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Overview): Mention the non-thread-safe-nature of
+ functions modifying context stored in handles.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Available ciphers): Added: TWOFISH128.
+ (Error Handling): Merged a lot of documentation taken from GPGME.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with sets of data): Documented:
+ gcry_ac_data_copy.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented module system.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Working with cipher handles): Small fix by Simon
+ Josefsson <jas@extundo.com>.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented ac interface.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Small fixes.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * cipher-ref.sgml: Removed file.
+ * digest-ref.sgml: Likewise.
+ * misc-ref.sgml: Likewise.
+ * pubkey-ref.sgml: Likewise.
+ * reference.sgml: Likewise.
+ * version.sgml.in: Likewise.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Documented several parts of the library, merged
+ some documentation from GPGME's manual, re-structured the whole
+ manual, added more menus.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Hash Functions): Adjusteded description of
+ gcry_md_copy.
+
+2003-06-12 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Fix example S-Exp, i.e.:
+ added the number of following digits as prefix to the number of
+ bits.
+ (Public Key Functions): Document the general usage of `flags',
+ including the no-blinding flag.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (Hash Functions): Document possible values of HD.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Version Check): Changed description of
+ gcry_check_version; the user now *must* call the function to
+ initialize the library.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi: Change for libgpg-error.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Fixed typo.
+
+2003-05-17 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Public Key Functions): Mention that only the
+ checking of secret keys is supported currently.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi: Add CTR.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi: Add CBC-MAC.
+
+2003-03-04 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.texi (Cipher Functions): Added gcry_cipher_reset.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi (gcry_pk_decrypt): Described use of FLAGS
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.texi (Hash Functions): Add CRC.
+
+2003-01-19 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Most functions are now documented. Still need to
+ fine tune the menu structure, document some utility functions,
+ mark up indices and references and add examples.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.texi: Typo fixes.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ * lgpl.texi: New.
+ * gcrypt.texi: Included lgpl and commented not yet converted text.
+
+2002-04-16 Werner Koch <wk@gnupg.org>
+
+ * version.sgml.in, cipher-ref.sgml, digest-ref.sgml, misc-ref.sgml
+ * pubkey-ref.sgml, reference.sgml: Removed.
+ * gcrypt.texi: New. Based on the old sgml version.
+ * gpl.texi, fdl.texi: New.
+ * Makefile.am: Adjusted for use with texinfo.
+
+2000-12-21 Werner Koch <wk@gnupg.org>
+
+ Renamed the gcryptref.sgml files and removed the GnuPG stuff.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am (SUBDIRS): Removed gph from this development series
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am (SUBDIRS): New subdir gph for the manual.
+
+Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.sgml (--always-trust): Added.
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Create a dummy man page if docbook-to-man is missing.
+
+Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg1.pod: Removed.
+ * gpg.sgml: New. Replaces the pod file
+ * Makefile.am: Add rule to make a man file from sgml
+
+Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.in.in: Use DESTDIR.
+
+Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.1pod: Enhanced the Bugs section (Michael).
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gpg.1pod: Spelling and grammar corrections (John A. Martin)
+ * FAQ: Ditto.
+ * DETAILS: Ditto.
+
+ Copyright 1999, 2000, 2002, 2003, 2008 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+ Various hacking notes -*- text -*-
+ =======================
+
+
+Taking optimized MPI code out of GMP:
+-------------------------------------
+
+ I generated the pentium4/* files by glueing the existing assembler
+ prologues to the GMP 4.2.1 assembler files generated with the m4
+ tool in GMP's build process, for example:
+
+ $ m4 -DHAVE_CONFIG_H -D__GMP_WITHIN_GMP -DOPERATION_rshift -DPIC \
+ rshift.asm >tmp-rshift.s
+
+ Then tmp-rshift will contain the assembler instructions for the
+ configured platform. Unfortunately, this way the comments are lost.
+ For most files I re-inserted some of the comments, but this is
+ tedious work.
+
+
+Debugging math stuff:
+---------------------
+
+ While debugging the ECC code in libgcrypt, I was in need for some
+ computer algebra system which would allow me to verify the numbers
+ in the debugging easily. I found that PARI (pari-gp package in
+ Debian) has support for elliptic curves. The below commands shows
+ how they are set up and used with an example.
+
+ ===8<========
+ hextodec(s)=local(v=Vec(s),a=10,b=11,c=12,d=13,e=14,f=15,A=10,B=11,C=12,D=13,E=14,F=15,h);if(#setunion(Set(v),Vec("0123456789ABCDEFabcdef"))>22,error);for(i=1,#v,h=shift(h,4)+eval(v[i]));h
+
+ p = hextodec("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF")
+ a = hextodec("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC")
+ b = hextodec("51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00")
+
+ /* Set up y^2 = x^3 + ax + b mod (p). */
+ e = ellinit(Mod(1,p)*[0,0,0,a,b]);
+
+ gx = hextodec ("00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")
+ gy = hextodec ("011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650")
+ g = Mod(1,p)*[gx,gy]
+
+ n = hextodec ("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409")
+
+ /* Verify that G is on the curve, and that n is the order. */
+ ellisoncurve (e,g)
+ isprime (n)
+ ellpow (e,g,n)
+
+ d = hextodec ("018F9573F25059571BDF614529953DE2540497CEDABD04F3AF78813BED7BB163A2FD919EECF822848FCA39EF55E500F8CE861C7D53D371857F7774B79428E887F81B")
+
+ qx = hextodec ("00316AAAD3E905875938F588BD9E8A4785EF9BDB76D62A83A5340F82CB8E800B25619F5C3EA02B7A4FA43D7497C7702F7DFBEAC8E8F92C3CAABD9F84182FDA391B3B")
+ /* Note: WRONG! (It is apparent that this is the same as X shifted by
+ 8 bit). */
+ qy = hextodec ("0000316AAAD3E905875938F588BD9E8A4785EF9BDB76D62A83A5340F82CB8E800B25619F5C3EA02B7A4FA43D7497C7702F7DFBEAC8E8F92C3CAABD9F84182FDA391B")
+ q = Mod(1,p)*[qx,qy]
+
+ /* Calculate what Q should be given d. */
+ ellpow (e,g,d)
+
+ /* This is not 0 and thus shows that libgcrypt gave Q and d that do
+ not match. */
+ ellpow (e,g,d) - q
+ ====8<=====================
--- /dev/null
+## Process this file with automake to create Makefile.in
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+EXTRA_DIST = README.apichanges HACKING \
+ libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+DISTCLEANFILES = gcrypt.cps
+
+BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+info_TEXINFOS = gcrypt.texi
+gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
+
+
+.fig.png:
+ fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.jpg:
+ fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.eps:
+ fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.pdf:
+ fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+
+# Make sure that gcrypt.texi is touched if any other source file has
+# been modified. This is required so that the version.texi magic
+# updates the release date.
+gnupg.texi : $(gcrypt_TEXINFOS)
+ touch $(srcdir)/gcrypt.texi
+
+online: gcrypt.html gcrypt.pdf gcrypt.info
+ set -e; \
+ echo "Uploading current manuals to www.gnupg.org ..."; \
+ cp libgcrypt-modules.png gcrypt.html/; \
+ cp fips-fsm.png gcrypt.html/; \
+ user=werner ; dashdevel="" ; \
+ if echo "@PACKAGE_VERSION@" | grep -- "-svn" >/dev/null; then \
+ dashdevel="-devel" ; \
+ cp gcrypt.pdf gcrypt.html/; \
+ cp gcrypt.info gcrypt.html/; \
+ else \
+ rsync -v gcrypt.pdf gcrypt.info \
+ $${user}@trithemius.gnupg.org:webspace/manuals/ ; \
+ fi ; \
+ cd gcrypt.html ; \
+ rsync -vr --exclude='.svn' . \
+ $${user}@trithemius.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = doc
+DIST_COMMON = $(gcrypt_TEXINFOS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/stamp-vti \
+ $(srcdir)/version.texi ChangeLog mdate-sh texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+INFO_DEPS = $(srcdir)/gcrypt.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = gcrypt.dvi
+PDFS = gcrypt.pdf
+PSS = gcrypt.ps
+HTMLS = gcrypt.html
+TEXINFOS = gcrypt.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__installdirs = "$(DESTDIR)$(infodir)"
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = README.apichanges HACKING \
+ libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+DISTCLEANFILES = gcrypt.cps
+BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
+ libgcrypt-modules.png fips-fsm.png \
+ libgcrypt-modules.pdf fips-fsm.pdf
+
+info_TEXINFOS = gcrypt.texi
+gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .dvi .eps .fig .html .info .jpg .pdf .png .ps .texi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu doc/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+.texi.info:
+ restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+ am__cwd=`pwd` && $(am__cd) $(srcdir) && \
+ rm -rf $$backupdir && mkdir $$backupdir && \
+ if ($(MAKEINFO) --version) >/dev/null 2>&1; then \
+ for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+ if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+ done; \
+ else :; fi && \
+ cd "$$am__cwd"; \
+ if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $@ $<; \
+ then \
+ rc=0; \
+ $(am__cd) $(srcdir); \
+ else \
+ rc=$$?; \
+ $(am__cd) $(srcdir) && \
+ $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+ fi; \
+ rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2DVI) $<
+
+.texi.pdf:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+ $(TEXI2PDF) $<
+
+.texi.html:
+ rm -rf $(@:.html=.htp)
+ if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+ -o $(@:.html=.htp) $<; \
+ then \
+ rm -rf $@; \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+ else \
+ if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+ rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+ exit 1; \
+ fi
+$(srcdir)/gcrypt.info: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.dvi: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.pdf: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+gcrypt.html: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
+$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: gcrypt.texi $(top_srcdir)/configure
+ @(dir=.; test -f ./gcrypt.texi || dir=$(srcdir); \
+ set `$(SHELL) $(srcdir)/mdate-sh $$dir/gcrypt.texi`; \
+ echo "@set UPDATED $$1 $$2 $$3"; \
+ echo "@set UPDATED-MONTH $$2 $$3"; \
+ echo "@set EDITION $(VERSION)"; \
+ echo "@set VERSION $(VERSION)") > vti.tmp
+ @cmp -s vti.tmp $(srcdir)/version.texi \
+ || (echo "Updating $(srcdir)/version.texi"; \
+ cp vti.tmp $(srcdir)/version.texi)
+ -@rm -f vti.tmp
+ @cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+ -rm -f vti.tmp
+
+maintainer-clean-vti:
+@MAINTAINER_MODE_TRUE@ -rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+.dvi.ps:
+ TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+ $(DVIPS) -o $@ $<
+
+uninstall-dvi-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \
+ rm -f "$(DESTDIR)$(dvidir)/$$f"; \
+ done
+
+uninstall-html-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \
+ rm -rf "$(DESTDIR)$(htmldir)/$$f"; \
+ done
+
+uninstall-info-am:
+ @$(PRE_UNINSTALL)
+ @if test -d '$(DESTDIR)$(infodir)' && \
+ (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+ if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+ then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \
+ done; \
+ else :; fi
+ @$(NORMAL_UNINSTALL)
+ @list='$(INFO_DEPS)'; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+ (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \
+ echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \
+ rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+ else :; fi); \
+ done
+
+uninstall-pdf-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(pdfdir)/$$f"; \
+ done
+
+uninstall-ps-am:
+ @$(NORMAL_UNINSTALL)
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(psdir)/$$f"; \
+ done
+
+dist-info: $(INFO_DEPS)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; \
+ for base in $$list; do \
+ case $$base in \
+ $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$base; then d=.; else d=$(srcdir); fi; \
+ base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \
+ if test -f $$file; then \
+ relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+ test -f "$(distdir)/$$relfile" || \
+ cp -p $$file "$(distdir)/$$relfile"; \
+ else :; fi; \
+ done; \
+ done
+
+mostlyclean-aminfo:
+ -rm -rf gcrypt.aux gcrypt.cp gcrypt.cps gcrypt.fn gcrypt.fns gcrypt.ky \
+ gcrypt.kys gcrypt.log gcrypt.pg gcrypt.tmp gcrypt.toc \
+ gcrypt.tp gcrypt.vr gcrypt.vrs
+
+clean-aminfo:
+ -test -z "gcrypt.dvi gcrypt.pdf gcrypt.ps gcrypt.html" \
+ || rm -rf gcrypt.dvi gcrypt.pdf gcrypt.ps gcrypt.html
+
+maintainer-clean-aminfo:
+ @list='$(INFO_DEPS)'; for i in $$list; do \
+ i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+ echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+ rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-info
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(INFO_DEPS)
+installdirs:
+ for dir in "$(DESTDIR)$(infodir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am
+
+install-dvi: install-dvi-am
+
+install-dvi-am: $(DVIS)
+ @$(NORMAL_INSTALL)
+ test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
+ @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \
+ done
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am: $(HTMLS)
+ @$(NORMAL_INSTALL)
+ test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
+ @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ $(am__strip_dir) \
+ if test -d "$$d$$p"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
+ echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+ $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+ else \
+ list2="$$list2 $$d$$p"; \
+ fi; \
+ done; \
+ test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \
+ done; }
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+ @$(NORMAL_INSTALL)
+ test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)"
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ esac; \
+ if test -f $$file; then d=.; else d=$(srcdir); fi; \
+ file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+ for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+ $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+ if test -f $$ifile; then \
+ echo "$$ifile"; \
+ else : ; fi; \
+ done; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
+ @$(POST_INSTALL)
+ @if (install-info --version && \
+ install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+ list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+ for file in $$list; do \
+ relfile=`echo "$$file" | sed 's|^.*/||'`; \
+ echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+ install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+ done; \
+ else : ; fi
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am: $(PDFS)
+ @$(NORMAL_INSTALL)
+ test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
+ @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done
+install-ps: install-ps-am
+
+install-ps-am: $(PSS)
+ @$(NORMAL_INSTALL)
+ test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
+ @list='$(PSS)'; test -n "$(psdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \
+ mostlyclean-libtool mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+.MAKE: all check install install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-aminfo clean-generic \
+ clean-libtool dist-info distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-aminfo \
+ maintainer-clean-generic maintainer-clean-vti mostlyclean \
+ mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool \
+ mostlyclean-vti pdf pdf-am ps ps-am uninstall uninstall-am \
+ uninstall-dvi-am uninstall-html-am uninstall-info-am \
+ uninstall-pdf-am uninstall-ps-am
+
+
+.fig.png:
+ fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.jpg:
+ fig2dev -L jpg `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.eps:
+ fig2dev -L eps `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+.fig.pdf:
+ fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
+
+# Make sure that gcrypt.texi is touched if any other source file has
+# been modified. This is required so that the version.texi magic
+# updates the release date.
+gnupg.texi : $(gcrypt_TEXINFOS)
+ touch $(srcdir)/gcrypt.texi
+
+online: gcrypt.html gcrypt.pdf gcrypt.info
+ set -e; \
+ echo "Uploading current manuals to www.gnupg.org ..."; \
+ cp libgcrypt-modules.png gcrypt.html/; \
+ cp fips-fsm.png gcrypt.html/; \
+ user=werner ; dashdevel="" ; \
+ if echo "@PACKAGE_VERSION@" | grep -- "-svn" >/dev/null; then \
+ dashdevel="-devel" ; \
+ cp gcrypt.pdf gcrypt.html/; \
+ cp gcrypt.info gcrypt.html/; \
+ else \
+ rsync -v gcrypt.pdf gcrypt.info \
+ $${user}@trithemius.gnupg.org:webspace/manuals/ ; \
+ fi ; \
+ cd gcrypt.html ; \
+ rsync -vr --exclude='.svn' . \
+ $${user}@trithemius.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+README.apichanges 2003-07-28
+
+ NOTE: THESE ARE API CHANGES DONE BEFORE THE FIRST STABLE RELEASE SO
+ THEY ARE NOT RELEVANT ANYMORE [stable is 1.2.4 right now]
+
+We decided to change a couple of annoying things in Libgcrypt and to
+cleanup the API. The new API better fits into a multi-threaded
+environment and is more consistent. One import change is that all
+functions return error codes from a set of error codes shared between
+GnuPG, GPGME and Libgcrypt.
+
+This file contains some hints on how to port your application from
+libgcrypt <= 1.1.12 to the current API as of 1.1.42. We hope that
+there won't be another need for such a major change.
+
+
+* Types
+
+ All types definitions changed to a foo_t scheme; for some time we
+ will support the old names but you better start to rename them:
+
+ s/GCRY_MPI/gcry_mpi_t/
+ s/GcryMPI/gcry_mpi_t/
+ s/GCRY_SEXP/gcry_sexp_t/
+ s/GcrySexp/gcry_sexp_t/
+ s/GCRY_CIPHER_HD/gcry_cipher_hd_t/
+ s/GcryCipherHd/gcry_cipher_hd_t/
+ s/GCRY_MD_HD/gcry_md_hd_t/
+ s/GcryMDHd/gcry_md_hd_t/
+
+* Initialization
+
+ For proper initialization of the library, you must call
+ gcry_check_version() before calling any other function except for
+ these gcry_control operations:
+ GCRYCTL_SUSPEND_SECMEM_WARN
+ GCRYCTL_DISABLE_INTERNAL_LOCKING
+ GCRYCTL_ANY_INITIALIZATION_P
+ GCRYCTL_INITIALIZATION_FINISHED_P
+
+
+* Handles
+
+ gcry_cipher_open and gcry_md_open do now return an error code
+ instead of a NULL handle; the handle is now returned by
+ asigning it to the first argument. Example on how to change your
+ code:
+
+ Old:
+
+ hd = gcry_md_open (algo, flags);
+ if (!hd)
+ {
+ fprintf (stderr, "md_open failed: %s\n", gcry_errno (-1));
+ ....
+
+ New:
+
+ rc = gcry_md_open (&hd, algo, flags);
+ if (rc)
+ {
+ fprintf (stderr, "md_open failed: %s\n", gcry_strerror (rc));
+ ....
+
+ If you are not interested in the error code, you can do it in a
+ simplified way:
+
+ gcry_md_open (&hd, algo, flags);
+ if (!hd)
+ abort ();
+
+ i.e. the function makes sure that HD points to NULL in case of an error.
+ The required change for gcry_cipher_open is similar.
+
+* Message Digests
+
+ The order of the arguments to gcry_md_copy has been changed in order
+ to be more consistent with other functions of this type. This means
+ that the new message digest handle will be a copy of the message
+ handle specified by the second argument and stored at the address
+ pointed to by the first argument.
+
+* Error codes
+
+ gcry_errno () has been removed because it is hard to use in
+ multi-threaded environment. You need to save the error code
+ returned by the functions and use it either numerical or passing it
+ to gcry_strerror (since gcry_strerror is a wrapper function for
+ gpg_strerror, the latter function can also be used).
+
+ Instead of using the error codes GCRYERR_*, you have to use the
+ GPG_ERR_* names.
+
+* S-expressions
+
+ gcry_sexp_canon_len used to return a `historical' error code in
+ `errcode', this is not the case anymore; the value returned in
+ `errcode' is now a standard Libgcrypt (i.e. gpg-error) error code.
+
+* MPI
+
+ gcry_mpi_scan and gcry_mpi_print need the size of a provided buffer
+ as input and return the number of bytes actually scanned/printed to
+ the user. The old API used a single size_t Pointer for both tasks,
+ the new API distinguishes between the input and the output values.
+
+* Public Key cryptography
+
+ gcry_pk_decrypt used to return a `simple S-expression part' that
+ contains a single MPI value. In case the `data' S-expression
+ contains a `flags' element, the result S-expression is filled with a
+ complete S-expression of the following format:
+
+ (value PLAINTEXT)
+
--- /dev/null
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: /home/wk/w/libgcrypt/doc/fips-fsm.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 4
+%%CreationDate: Mon Mar 28 14:04:57 2011
+%%For: wk@vigenere (Werner Koch,,,)
+%%BoundingBox: 0 0 497 579
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+/col32 {0.609 0.000 0.000 srgb} bind def
+/col33 {0.547 0.547 0.547 srgb} bind def
+/col34 {0.547 0.547 0.547 srgb} bind def
+/col35 {0.258 0.258 0.258 srgb} bind def
+/col36 {0.547 0.547 0.547 srgb} bind def
+/col37 {0.258 0.258 0.258 srgb} bind def
+/col38 {0.547 0.547 0.547 srgb} bind def
+/col39 {0.258 0.258 0.258 srgb} bind def
+/col40 {0.547 0.547 0.547 srgb} bind def
+/col41 {0.258 0.258 0.258 srgb} bind def
+/col42 {0.547 0.547 0.547 srgb} bind def
+/col43 {0.258 0.258 0.258 srgb} bind def
+
+end
+save
+newpath 0 579 moveto 0 0 lineto 497 0 lineto 497 579 lineto closepath clip newpath
+-56.9 596.0 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Courier-Oblique /Courier-Oblique-iso isovec ReEncode
+/Times-Roman /Times-Roman-iso isovec ReEncode
+ /DrawEllipse {
+ /endangle exch def
+ /startangle exch def
+ /yrad exch def
+ /xrad exch def
+ /y exch def
+ /x exch def
+ /savematrix mtrx currentmatrix def
+ x y tr xrad yrad sc 0 0 1 startangle endangle arc
+ closepath
+ savematrix setmatrix
+ } def
+
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+% Ellipse
+7.500 slw
+n 3238 1735 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+3157 1805 m
+gs 1 -1 sc (1) col0 sh gr
+% Ellipse
+n 2408 3749 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+2327 3819 m
+gs 1 -1 sc (2) col0 sh gr
+% Ellipse
+n 1708 5809 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+1627 5879 m
+gs 1 -1 sc (3) col0 sh gr
+% Ellipse
+n 5848 1685 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+5767 1755 m
+gs 1 -1 sc (6) col0 sh gr
+% Ellipse
+n 6128 7899 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+6047 7969 m
+gs 1 -1 sc (7) col0 sh gr
+% Ellipse
+n 7568 4889 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+7487 4959 m
+gs 1 -1 sc (8) col0 sh gr
+% Ellipse
+n 6008 3879 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+5882 3940 m
+gs 1 -1 sc (10) col0 sh gr
+% Ellipse
+n 5418 2659 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+5292 2720 m
+gs 1 -1 sc (11) col0 sh gr
+% Ellipse
+n 4268 3715 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+4142 3776 m
+gs 1 -1 sc (12) col0 sh gr
+% Ellipse
+n 3208 5865 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+3082 5926 m
+gs 1 -1 sc (13) col0 sh gr
+% Ellipse
+n 4178 6765 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+4052 6826 m
+gs 1 -1 sc (14) col0 sh gr
+% Ellipse
+n 4558 7355 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+4432 7416 m
+gs 1 -1 sc (15) col0 sh gr
+% Ellipse
+n 5208 7365 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+5127 7435 m
+gs 1 -1 sc (5) col0 sh gr
+% Ellipse
+n 3708 7715 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+3582 7776 m
+gs 1 -1 sc (16) col0 sh gr
+% Ellipse
+n 3038 7925 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+2957 7995 m
+gs 1 -1 sc (4) col0 sh gr
+% Ellipse
+n 6568 5895 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+6487 5965 m
+gs 1 -1 sc (9) col0 sh gr
+% Polyline
+n 3900 8370 m 3600 8370 3600 9150 300 arcto 4 {pop} repeat
+ 3600 9450 5670 9450 300 arcto 4 {pop} repeat
+ 5970 9450 5970 8670 300 arcto 4 {pop} repeat
+ 5970 8370 3900 8370 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+3870 9000 m
+gs 1 -1 sc (Operational) col0 sh gr
+% Polyline
+n 1215 4335 m 915 4335 915 5145 300 arcto 4 {pop} repeat
+ 915 5445 2640 5445 300 arcto 4 {pop} repeat
+ 2940 5445 2940 4635 300 arcto 4 {pop} repeat
+ 2940 4335 1215 4335 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+1620 4995 m
+gs 1 -1 sc (Init) col0 sh gr
+% Polyline
+n 1230 6345 m 930 6345 930 7155 300 arcto 4 {pop} repeat
+ 930 7455 2655 7455 300 arcto 4 {pop} repeat
+ 2955 7455 2955 6645 300 arcto 4 {pop} repeat
+ 2955 6345 1230 6345 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+1215 7020 m
+gs 1 -1 sc (Self-Test) col0 sh gr
+% Polyline
+n 7050 6360 m 6750 6360 6750 7170 300 arcto 4 {pop} repeat
+ 6750 7470 8475 7470 300 arcto 4 {pop} repeat
+ 8775 7470 8775 6660 300 arcto 4 {pop} repeat
+ 8775 6360 7050 6360 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+7335 7020 m
+gs 1 -1 sc (Error) col0 sh gr
+% Polyline
+n 4125 4335 m 3825 4335 3825 5145 300 arcto 4 {pop} repeat
+ 3825 5445 5550 5445 300 arcto 4 {pop} repeat
+ 5850 5445 5850 4635 300 arcto 4 {pop} repeat
+ 5850 4335 4125 4335 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+3915 4995 m
+gs 1 -1 sc (Fatal-Error) col0 sh gr
+% Polyline
+n 7050 2310 m 6750 2310 6750 3120 300 arcto 4 {pop} repeat
+ 6750 3420 8475 3420 300 arcto 4 {pop} repeat
+ 8775 3420 8775 2610 300 arcto 4 {pop} repeat
+ 8775 2310 7050 2310 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+6930 2970 m
+gs 1 -1 sc (Shutdown) col0 sh gr
+% Polyline
+n 2775 2295 m 2475 2295 2475 3105 300 arcto 4 {pop} repeat
+ 2475 3405 4200 3405 300 arcto 4 {pop} repeat
+ 4500 3405 4500 2595 300 arcto 4 {pop} repeat
+ 4500 2295 2775 2295 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+2655 2970 m
+gs 1 -1 sc (Power-On) col0 sh gr
+% Polyline
+n 2775 285 m 2475 285 2475 1095 300 arcto 4 {pop} repeat
+ 2475 1395 4200 1395 300 arcto 4 {pop} repeat
+ 4500 1395 4500 585 300 arcto 4 {pop} repeat
+ 4500 285 2775 285 300 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Times-Roman-iso ff 360.00 scf sf
+2565 945 m
+gs 1 -1 sc (Power-Off) col0 sh gr
+% Ellipse
+n 4192 6338 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+4066 6399 m
+gs 1 -1 sc (17) col0 sh gr
+% Ellipse
+n 3202 4507 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+3076 4568 m
+gs 1 -1 sc (19) col0 sh gr
+% Ellipse
+n 3181 5161 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+3055 5222 m
+gs 1 -1 sc (18) col0 sh gr
+% Ellipse
+n 7709 7996 142 142 0 360 DrawEllipse gs col0 s gr
+
+/Courier-Oblique-iso ff 180.00 scf sf
+7612 8047 m
+gs 1 -1 sc (20) col0 sh gr
+% Arc
+15.000 slw
+1 slc
+gs clippath
+2899 6648 m 2920 6766 l 3203 6716 l 2957 6699 l 3182 6598 l cp
+eoclip
+n 4837.5 16740.0 10215.6 -79.2 -100.8 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slc
+n 3182 6598 m 2957 6699 l 3203 6716 l 3182 6598 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+2911 7184 m 2908 7304 l 3195 7313 l 2957 7246 l 3198 7193 l cp
+eoclip
+n 3026.1 8399.8 1159.2 -1.5 -95.0 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slc
+n 3198 7193 m 2957 7246 l 3195 7313 l 3198 7193 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+6757 6631 m 6772 6512 l 6487 6477 l 6718 6566 l 6472 6596 l cp
+eoclip
+n 7663.1 -2028.8 8647.1 123.6 96.1 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slc
+n 6472 6596 m 6718 6566 l 6487 6477 l 6472 6596 l cp gs 0.00 setgray ef gr col0 s
+% Arc
+1 slc
+gs clippath
+8336 7494 m 8241 7421 l 8066 7650 l 8260 7496 l 8162 7723 l cp
+eoclip
+n 7717.5 7211.2 619.2 155.3 24.7 arcn
+gs col0 s gr
+ gr
+
+% arrowhead
+0 slc
+n 8162 7723 m 8260 7496 l 8066 7650 l 8162 7723 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3360 2310 m 3480 2310 l 3480 2023 l 3420 2263 l 3360 2023 l cp
+eoclip
+n 3420 1395 m
+ 3420 2295 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 3360 2023 m 3420 2263 l 3480 2023 l 3360 2023 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4794 4378 m 4860 4278 l 4621 4118 l 4788 4302 l 4555 4218 l cp
+eoclip
+n 3465 3420 m
+ 4815 4320 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 4555 4218 m 4788 4302 l 4621 4118 l 4555 4218 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+1830 6360 m 1950 6360 l 1950 6073 l 1890 6313 l 1830 6073 l cp
+eoclip
+n 1890 5445 m
+ 1890 6345 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 1830 6073 m 1890 6313 l 1950 6073 l 1830 6073 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3699 8465 m 3790 8386 l 3601 8170 l 3714 8391 l 3511 8249 l cp
+eoclip
+n 2835 7380 m
+ 3735 8415 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 3511 8249 m 3714 8391 l 3601 8170 l 3511 8249 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4785 5475 m 4665 5475 l 4665 5762 l 4725 5522 l 4785 5762 l cp
+eoclip
+n 4725 8370 m
+ 4725 5490 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 4785 5762 m 4725 5522 l 4665 5762 l 4785 5762 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+7395 3432 m 7287 3380 l 7162 3639 l 7321 3449 l 7270 3691 l cp
+eoclip
+n 4950 8370 m
+ 7335 3420 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 7270 3691 m 7321 3449 l 7162 3639 l 7270 3691 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6765 6990 m 6765 6870 l 6478 6870 l 6718 6930 l 6478 6990 l cp
+eoclip
+n 2925 6930 m
+ 6750 6930 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 6478 6990 m 6718 6930 l 6478 6870 l 6478 6990 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3969 5384 m 3880 5303 l 3686 5515 l 3893 5379 l 3774 5596 l cp
+eoclip
+n 2880 6480 m
+ 3915 5355 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 3774 5596 m 3893 5379 l 3686 5515 l 3774 5596 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6765 2895 m 6765 2775 l 6478 2775 l 6718 2835 l 6478 2895 l cp
+eoclip
+n 4500 2835 m
+ 6750 2835 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 6478 2895 m 6718 2835 l 6478 2775 l 6478 2895 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+7800 3405 m 7680 3405 l 7680 3692 l 7740 3452 l 7800 3692 l cp
+eoclip
+n 7740 6345 m
+ 7740 3420 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 7800 3692 m 7740 3452 l 7680 3692 l 7800 3692 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+1846 4276 m 1908 4379 l 2154 4229 l 1918 4303 l 2092 4127 l cp
+eoclip
+n 3375 3420 m
+ 1890 4320 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 2092 4127 m 1918 4303 l 2154 4229 l 2092 4127 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6893 3361 m 6808 3276 l 6604 3480 l 6817 3353 l 6689 3565 l cp
+eoclip
+n 5760 4410 m
+ 6840 3330 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 6689 3565 m 6817 3353 l 6604 3480 l 6689 3565 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+4510 794 m 4461 903 l 4724 1020 l 4530 868 l 4773 910 l cp
+eoclip
+n 7740 2295 m
+ 4500 855 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 4773 910 m 4530 868 l 4724 1020 l 4773 910 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+5791 5301 m 5706 5386 l 5910 5590 l 5783 5378 l 5995 5505 l cp
+eoclip
+n 6840 6435 m
+ 5760 5355 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 5995 5505 m 5783 5378 l 5910 5590 l 5995 5505 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+6895 7408 m 6804 7329 l 6615 7545 l 6819 7404 l 6706 7624 l cp
+eoclip
+n 5895 8460 m
+ 6840 7380 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 6706 7624 m 6819 7404 l 6615 7545 l 6706 7624 l cp gs 0.00 setgray ef gr col0 s
+% Polyline
+1 slc
+gs clippath
+3840 4740 m 3840 4620 l 3553 4620 l 3793 4680 l 3553 4740 l cp
+eoclip
+n 2925 4680 m
+ 3825 4680 l gs col0 s gr gr
+
+% arrowhead
+0 slc
+n 3553 4740 m 3793 4680 l 3553 4620 l 3553 4740 l cp gs 0.00 setgray ef gr col0 s
+% here ends figure;
+$F2psEnd
+rs
+showpage
--- /dev/null
+#FIG 3.2
+Portrait
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+0 32 #9c0000
+0 33 #8c8c8c
+0 34 #8c8c8c
+0 35 #424242
+0 36 #8c8c8c
+0 37 #424242
+0 38 #8c8c8c
+0 39 #424242
+0 40 #8c8c8c
+0 41 #424242
+0 42 #8c8c8c
+0 43 #424242
+6 900 270 8775 9450
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 4837.500 16740.000 6750 6705 4725 6525 2925 6705
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 3026.138 8399.825 4185 8370 3870 7605 2925 7245
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 7663.125 -2028.750 2880 5175 4770 6120 6750 6570
+ 1 1 2.00 120.00 240.00
+5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 7717.500 7211.250 7155 7470 7740 7830 8280 7470
+ 1 1 2.00 120.00 240.00
+6 3096 1593 3380 1877
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3238 1735 142 142 3238 1735 3103 1690
+4 0 0 50 -1 13 12 0.0000 4 105 105 3157 1805 1\001
+-6
+6 2266 3607 2550 3891
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2408 3749 142 142 2408 3749 2273 3704
+4 0 0 50 -1 13 12 0.0000 4 105 105 2327 3819 2\001
+-6
+6 1566 5667 1850 5951
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 1708 5809 142 142 1708 5809 1573 5764
+4 0 0 50 -1 13 12 0.0000 4 105 105 1627 5879 3\001
+-6
+6 5706 1543 5990 1827
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5848 1685 142 142 5848 1685 5713 1640
+4 0 0 50 -1 13 12 0.0000 4 105 105 5767 1755 6\001
+-6
+6 5986 7757 6270 8041
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6128 7899 142 142 6128 7899 5993 7854
+4 0 0 50 -1 13 12 0.0000 4 105 105 6047 7969 7\001
+-6
+6 7426 4747 7710 5031
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7568 4889 142 142 7568 4889 7433 4844
+4 0 0 50 -1 13 12 0.0000 4 105 105 7487 4959 8\001
+-6
+6 5866 3737 6150 4021
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6008 3879 142 142 6008 3879 5873 3834
+4 0 0 50 -1 13 12 0.0000 4 105 210 5882 3940 10\001
+-6
+6 5276 2517 5560 2801
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5418 2659 142 142 5418 2659 5283 2614
+4 0 0 50 -1 13 12 0.0000 4 105 210 5292 2720 11\001
+-6
+6 4126 3573 4410 3857
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4268 3715 142 142 4268 3715 4133 3670
+4 0 0 50 -1 13 12 0.0000 4 105 210 4142 3776 12\001
+-6
+6 3066 5723 3350 6007
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3208 5865 142 142 3208 5865 3073 5820
+4 0 0 50 -1 13 12 0.0000 4 105 210 3082 5926 13\001
+-6
+6 4036 6623 4320 6907
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4178 6765 142 142 4178 6765 4043 6720
+4 0 0 50 -1 13 12 0.0000 4 105 210 4052 6826 14\001
+-6
+6 4416 7213 4700 7497
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4558 7355 142 142 4558 7355 4423 7310
+4 0 0 50 -1 13 12 0.0000 4 105 210 4432 7416 15\001
+-6
+6 5066 7223 5350 7507
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5208 7365 142 142 5208 7365 5073 7320
+4 0 0 50 -1 13 12 0.0000 4 105 105 5127 7435 5\001
+-6
+6 3566 7573 3850 7857
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3708 7715 142 142 3708 7715 3573 7670
+4 0 0 50 -1 13 12 0.0000 4 105 210 3582 7776 16\001
+-6
+6 2896 7783 3180 8067
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3038 7925 142 142 3038 7925 2903 7880
+4 0 0 50 -1 13 12 0.0000 4 105 105 2957 7995 4\001
+-6
+6 6426 5753 6710 6037
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6568 5895 142 142 6568 5895 6433 5850
+4 0 0 50 -1 13 12 0.0000 4 105 105 6487 5965 9\001
+-6
+6 3600 8370 5985 9450
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 5970 9450 3600 9450 3600 8370 5970 8370 5970 9450
+4 0 0 50 -1 0 24 0.0000 4 330 1725 3870 9000 Operational\001
+-6
+6 900 4320 2970 5445
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 2940 5445 915 5445 915 4335 2940 4335 2940 5445
+4 0 0 50 -1 0 24 0.0000 4 240 510 1620 4995 Init\001
+-6
+6 900 6345 2970 7470
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 2955 7455 930 7455 930 6345 2955 6345 2955 7455
+4 0 0 50 -1 0 24 0.0000 4 255 1335 1215 7020 Self-Test\001
+-6
+6 6750 6345 8775 7470
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 8775 7470 6750 7470 6750 6360 8775 6360 8775 7470
+4 0 0 50 -1 0 24 0.0000 4 240 765 7335 7020 Error\001
+-6
+6 3825 4320 5850 5445
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 5850 5445 3825 5445 3825 4335 5850 4335 5850 5445
+4 0 0 50 -1 0 24 0.0000 4 255 1620 3915 4995 Fatal-Error\001
+-6
+6 6750 2295 8775 3420
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 8775 3420 6750 3420 6750 2310 8775 2310 8775 3420
+4 0 0 50 -1 0 24 0.0000 4 240 1455 6930 2970 Shutdown\001
+-6
+6 2475 2295 4500 3420
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 4500 3405 2475 3405 2475 2295 4500 2295 4500 3405
+4 0 0 50 -1 0 24 0.0000 4 240 1470 2655 2970 Power-On\001
+-6
+6 2475 270 4500 1395
+2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5
+ 4500 1395 2475 1395 2475 285 4500 285 4500 1395
+4 0 0 50 -1 0 24 0.0000 4 240 1530 2565 945 Power-Off\001
+-6
+6 4050 6196 4334 6480
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4192 6338 142 142 4192 6338 4057 6293
+4 0 0 50 -1 13 12 0.0000 4 105 210 4066 6399 17\001
+-6
+6 3053 4358 3351 4656
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3202 4507 142 142 3202 4507 3067 4462
+4 0 0 50 -1 13 12 0.0000 4 105 210 3076 4568 19\001
+-6
+6 3032 5012 3330 5310
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3181 5161 142 142 3181 5161 3046 5116
+4 0 0 50 -1 13 12 0.0000 4 105 210 3055 5222 18\001
+-6
+6 7560 7847 7858 8145
+1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7709 7996 142 142 7709 7996 7574 7951
+4 0 0 50 -1 13 12 0.0000 4 105 210 7612 8047 20\001
+-6
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3420 1395 3420 2295
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3465 3420 4815 4320
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 1890 5445 1890 6345
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2835 7380 3735 8415
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4725 8370 4725 5490
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4950 8370 7335 3420
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2925 6930 6750 6930
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2880 6480 3915 5355
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 4500 2835 6750 2835
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 7740 6345 7740 3420
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 3375 3420 1890 4320
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 5760 4410 6840 3330
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 7740 2295 4500 855
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 6840 6435 5760 5355
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 5895 8460 6840 7380
+2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2
+ 1 1 2.00 120.00 240.00
+ 2925 4680 3825 4680
+-6
--- /dev/null
+This is /home/wk/w/libgcrypt/doc/gcrypt.info, produced by makeinfo
+version 4.13 from /home/wk/w/libgcrypt/doc/gcrypt.texi.
+
+This manual is for Libgcrypt (version 1.5.0, 29 June 2011), which is
+GNU's library of cryptographic building blocks.
+
+ Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
+Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+
+INFO-DIR-SECTION GNU Libraries
+START-INFO-DIR-ENTRY
+* libgcrypt: (gcrypt). Cryptographic function library.
+END-INFO-DIR-ENTRY
+
+\1f
+Indirect:
+gcrypt.info-1: 832
+\1f
+Tag Table:
+(Indirect)
+Node: Top\7f832
+Node: Introduction\7f3123
+Node: Getting Started\7f3495
+Node: Features\7f4376
+Node: Overview\7f5160
+Node: Preparation\7f5791
+Node: Header\7f6648
+Node: Building sources\7f7719
+Node: Building sources using Automake\7f9633
+Node: Initializing the library\7f10815
+Ref: sample-use-suspend-secmem\7f13990
+Ref: sample-use-resume-secmem\7f14610
+Node: Multi-Threading\7f15506
+Ref: Multi-Threading-Footnote-1\7f20134
+Node: Enabling FIPS mode\7f20542
+Node: Generalities\7f22408
+Node: Controlling the library\7f22733
+Node: Modules\7f35470
+Node: Error Handling\7f36249
+Node: Error Values\7f38772
+Node: Error Sources\7f43712
+Node: Error Codes\7f45983
+Node: Error Strings\7f49468
+Node: Handler Functions\7f50651
+Node: Progress handler\7f51210
+Node: Allocation handler\7f53206
+Node: Error handler\7f54757
+Node: Logging handler\7f56324
+Node: Symmetric cryptography\7f56916
+Node: Available ciphers\7f57721
+Node: Cipher modules\7f60228
+Node: Available cipher modes\7f64841
+Node: Working with cipher handles\7f66516
+Node: General cipher functions\7f74831
+Node: Public Key cryptography\7f77349
+Node: Available algorithms\7f78264
+Node: Used S-expressions\7f78613
+Node: RSA key parameters\7f79725
+Node: DSA key parameters\7f81000
+Node: ECC key parameters\7f81658
+Node: Public key modules\7f83423
+Node: Cryptographic Functions\7f89093
+Node: General public-key related Functions\7f96945
+Node: AC Interface\7f109262
+Node: Available asymmetric algorithms\7f110397
+Node: Working with sets of data\7f111066
+Node: Working with IO objects\7f115568
+Node: Working with handles\7f118288
+Node: Working with keys\7f119235
+Node: Using cryptographic functions\7f123317
+Node: Handle-independent functions\7f130224
+Node: Hashing\7f130972
+Node: Available hash algorithms\7f131763
+Node: Hash algorithm modules\7f135212
+Node: Working with hash algorithms\7f139149
+Node: Key Derivation\7f150451
+Node: Random Numbers\7f152520
+Node: Quality of random numbers\7f152801
+Node: Retrieving random numbers\7f153485
+Node: S-expressions\7f154969
+Node: Data types for S-expressions\7f155613
+Node: Working with S-expressions\7f155939
+Node: MPI library\7f165835
+Node: Data types\7f166793
+Node: Basic functions\7f166987
+Node: MPI formats\7f169055
+Node: Calculations\7f171938
+Node: Comparisons\7f174192
+Node: Bit manipulations\7f175067
+Node: Miscellaneous\7f176382
+Node: Prime numbers\7f178351
+Node: Generation\7f178621
+Node: Checking\7f179905
+Node: Utilities\7f180318
+Node: Memory allocation\7f180511
+Node: Architecture\7f181838
+Ref: fig:subsystems\7f183358
+Ref: Architecture-Footnote-1\7f184443
+Ref: Architecture-Footnote-2\7f184505
+Node: Public-Key Subsystem Architecture\7f184589
+Node: Symmetric Encryption Subsystem Architecture\7f187530
+Node: Hashing and MACing Subsystem Architecture\7f188977
+Node: Multi-Precision-Integer Subsystem Architecture\7f190901
+Node: Prime-Number-Generator Subsystem Architecture\7f192342
+Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1\7f194273
+Node: Random-Number Subsystem Architecture\7f194560
+Node: CSPRNG Description\7f197049
+Ref: CSPRNG Description-Footnote-1\7f198611
+Node: FIPS PRNG Description\7f198734
+Node: Self-Tests\7f200869
+Node: FIPS Mode\7f212561
+Ref: fig:fips-fsm\7f216541
+Ref: tbl:fips-states\7f216643
+Ref: tbl:fips-state-transitions\7f217896
+Node: Library Copying\7f221510
+Node: Copying\7f249628
+Node: Figures and Tables\7f268802
+Node: Concept Index\7f269212
+Node: Function and Data Index\7f274915
+\1f
+End Tag Table
--- /dev/null
+This is /home/wk/w/libgcrypt/doc/gcrypt.info, produced by makeinfo
+version 4.13 from /home/wk/w/libgcrypt/doc/gcrypt.texi.
+
+This manual is for Libgcrypt (version 1.5.0, 29 June 2011), which is
+GNU's library of cryptographic building blocks.
+
+ Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
+Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+
+INFO-DIR-SECTION GNU Libraries
+START-INFO-DIR-ENTRY
+* libgcrypt: (gcrypt). Cryptographic function library.
+END-INFO-DIR-ENTRY
+
+\1f
+File: gcrypt.info, Node: Top, Next: Introduction, Up: (dir)
+
+The Libgcrypt Library
+*********************
+
+This manual is for Libgcrypt (version 1.5.0, 29 June 2011), which is
+GNU's library of cryptographic building blocks.
+
+ Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
+Free Software Foundation, Inc.
+
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version. The text of the
+ license can be found in the section entitled "GNU General Public
+ License".
+
+* Menu:
+
+* Introduction:: What is Libgcrypt.
+* Preparation:: What you should do before using the library.
+* Generalities:: General library functions and data types.
+* Handler Functions:: Working with handler functions.
+* Symmetric cryptography:: How to use symmetric cryptography.
+* Public Key cryptography:: How to use public key cryptography.
+* Hashing:: How to use hash and MAC algorithms.
+* Key Derivation:: How to derive keys from strings
+* Random Numbers:: How to work with random numbers.
+* S-expressions:: How to manage S-expressions.
+* MPI library:: How to work with multi-precision-integers.
+* Prime numbers:: How to use the Prime number related functions.
+* Utilities:: Utility functions.
+* Architecture:: How Libgcrypt works internally.
+
+Appendices
+
+* Self-Tests:: Description of the self-tests.
+* FIPS Mode:: Description of the FIPS mode.
+* Library Copying:: The GNU Lesser General Public License
+ says how you can copy and share Libgcrypt.
+* Copying:: The GNU General Public License says how you
+ can copy and share some parts of Libgcrypt.
+
+Indices
+
+* Figures and Tables:: Index of figures and tables.
+* Concept Index:: Index of concepts and programs.
+* Function and Data Index:: Index of functions, variables and data types.
+
+\1f
+File: gcrypt.info, Node: Introduction, Next: Preparation, Prev: Top, Up: Top
+
+1 Introduction
+**************
+
+Libgcrypt is a library providing cryptographic building blocks.
+
+* Menu:
+
+* Getting Started:: How to use this manual.
+* Features:: A glance at Libgcrypt's features.
+* Overview:: Overview about the library.
+
+\1f
+File: gcrypt.info, Node: Getting Started, Next: Features, Up: Introduction
+
+1.1 Getting Started
+===================
+
+This manual documents the Libgcrypt library application programming
+interface (API). All functions and data types provided by the library
+are explained.
+
+The reader is assumed to possess basic knowledge about applied
+cryptography.
+
+ This manual can be used in several ways. If read from the beginning
+to the end, it gives a good introduction into the library and how it
+can be used in an application. Forward references are included where
+necessary. Later on, the manual can be used as a reference manual to
+get just the information needed about any particular interface of the
+library. Experienced programmers might want to start looking at the
+examples at the end of the manual, and then only read up those parts of
+the interface which are unclear.
+
+\1f
+File: gcrypt.info, Node: Features, Next: Overview, Prev: Getting Started, Up: Introduction
+
+1.2 Features
+============
+
+Libgcrypt might have a couple of advantages over other libraries doing
+a similar job.
+
+It's Free Software
+ Anybody can use, modify, and redistribute it under the terms of
+ the GNU Lesser General Public License (*note Library Copying::).
+ Note, that some parts (which are in general not needed by
+ applications) are subject to the terms of the GNU General Public
+ License (*note Copying::); please see the README file of the
+ distribution for of list of these parts.
+
+It encapsulates the low level cryptography
+ Libgcrypt provides a high level interface to cryptographic
+ building blocks using an extensible and flexible API.
+
+
+\1f
+File: gcrypt.info, Node: Overview, Prev: Features, Up: Introduction
+
+1.3 Overview
+============
+
+The Libgcrypt library is fully thread-safe, where it makes sense to be
+thread-safe. Not thread-safe are some cryptographic functions that
+modify a certain context stored in handles. If the user really intents
+to use such functions from different threads on the same handle, he has
+to take care of the serialization of such functions himself. If not
+described otherwise, every function is thread-safe.
+
+ Libgcrypt depends on the library `libgpg-error', which contains
+common error handling related code for GnuPG components.
+
+\1f
+File: gcrypt.info, Node: Preparation, Next: Generalities, Prev: Introduction, Up: Top
+
+2 Preparation
+*************
+
+To use Libgcrypt, you have to perform some changes to your sources and
+the build system. The necessary changes are small and explained in the
+following sections. At the end of this chapter, it is described how
+the library is initialized, and how the requirements of the library are
+verified.
+
+* Menu:
+
+* Header:: What header file you need to include.
+* Building sources:: How to build sources using the library.
+* Building sources using Automake:: How to build sources with the help of Automake.
+* Initializing the library:: How to initialize the library.
+* Multi-Threading:: How Libgcrypt can be used in a MT environment.
+* Enabling FIPS mode:: How to enable the FIPS mode.
+
+\1f
+File: gcrypt.info, Node: Header, Next: Building sources, Up: Preparation
+
+2.1 Header
+==========
+
+All interfaces (data types and functions) of the library are defined in
+the header file `gcrypt.h'. You must include this in all source files
+using the library, either directly or through some other header file,
+like this:
+
+ #include <gcrypt.h>
+
+ The name space of Libgcrypt is `gcry_*' for function and type names
+and `GCRY*' for other symbols. In addition the same name prefixes with
+one prepended underscore are reserved for internal use and should never
+be used by an application. Note that Libgcrypt uses libgpg-error,
+which uses `gpg_*' as name space for function and type names and
+`GPG_*' for other symbols, including all the error codes.
+
+Certain parts of gcrypt.h may be excluded by defining these macros:
+
+`GCRYPT_NO_MPI_MACROS'
+ Do not define the shorthand macros `mpi_*' for `gcry_mpi_*'.
+
+`GCRYPT_NO_DEPRECATED'
+ Do not include definitions for deprecated features. This is
+ useful to make sure that no deprecated features are used.
+
+\1f
+File: gcrypt.info, Node: Building sources, Next: Building sources using Automake, Prev: Header, Up: Preparation
+
+2.2 Building sources
+====================
+
+If you want to compile a source file including the `gcrypt.h' header
+file, you must make sure that the compiler can find it in the directory
+hierarchy. This is accomplished by adding the path to the directory in
+which the header file is located to the compilers include file search
+path (via the `-I' option).
+
+ However, the path to the include file is determined at the time the
+source is configured. To solve this problem, Libgcrypt ships with a
+small helper program `libgcrypt-config' that knows the path to the
+include file and other configuration options. The options that need to
+be added to the compiler invocation at compile time are output by the
+`--cflags' option to `libgcrypt-config'. The following example shows
+how it can be used at the command line:
+
+ gcc -c foo.c `libgcrypt-config --cflags`
+
+ Adding the output of `libgcrypt-config --cflags' to the compilers
+command line will ensure that the compiler can find the Libgcrypt header
+file.
+
+ A similar problem occurs when linking the program with the library.
+Again, the compiler has to find the library files. For this to work,
+the path to the library files has to be added to the library search path
+(via the `-L' option). For this, the option `--libs' to
+`libgcrypt-config' can be used. For convenience, this option also
+outputs all other options that are required to link the program with
+the Libgcrypt libraries (in particular, the `-lgcrypt' option). The
+example shows how to link `foo.o' with the Libgcrypt library to a
+program `foo'.
+
+ gcc -o foo foo.o `libgcrypt-config --libs`
+
+ Of course you can also combine both examples to a single command by
+specifying both options to `libgcrypt-config':
+
+ gcc -o foo foo.c `libgcrypt-config --cflags --libs`
+
+\1f
+File: gcrypt.info, Node: Building sources using Automake, Next: Initializing the library, Prev: Building sources, Up: Preparation
+
+2.3 Building sources using Automake
+===================================
+
+It is much easier if you use GNU Automake instead of writing your own
+Makefiles. If you do that, you do not have to worry about finding and
+invoking the `libgcrypt-config' script at all. Libgcrypt provides an
+extension to Automake that does all the work for you.
+
+ -- Macro: AM_PATH_LIBGCRYPT ([MINIMUM-VERSION], [ACTION-IF-FOUND],
+ [ACTION-IF-NOT-FOUND])
+ Check whether Libgcrypt (at least version MINIMUM-VERSION, if
+ given) exists on the host system. If it is found, execute
+ ACTION-IF-FOUND, otherwise do ACTION-IF-NOT-FOUND, if given.
+
+ Additionally, the function defines `LIBGCRYPT_CFLAGS' to the flags
+ needed for compilation of the program to find the `gcrypt.h'
+ header file, and `LIBGCRYPT_LIBS' to the linker flags needed to
+ link the program to the Libgcrypt library.
+
+ You can use the defined Autoconf variables like this in your
+`Makefile.am':
+
+ AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
+ LDADD = $(LIBGCRYPT_LIBS)
+
+\1f
+File: gcrypt.info, Node: Initializing the library, Next: Multi-Threading, Prev: Building sources using Automake, Up: Preparation
+
+2.4 Initializing the library
+============================
+
+Before the library can be used, it must initialize itself. This is
+achieved by invoking the function `gcry_check_version' described below.
+
+ Also, it is often desirable to check that the version of Libgcrypt
+used is indeed one which fits all requirements. Even with binary
+compatibility, new features may have been introduced, but due to
+problem with the dynamic linker an old version may actually be used.
+So you may want to check that the version is okay right after program
+startup.
+
+ -- Function: const char * gcry_check_version (const char *REQ_VERSION)
+ The function `gcry_check_version' initializes some subsystems used
+ by Libgcrypt and must be invoked before any other function in the
+ library, with the exception of the `GCRYCTL_SET_THREAD_CBS' command
+ (called via the `gcry_control' function). *Note Multi-Threading::.
+
+ Furthermore, this function returns the version number of the
+ library. It can also verify that the version number is higher
+ than a certain required version number REQ_VERSION, if this value
+ is not a null pointer.
+
+ Libgcrypt uses a concept known as secure memory, which is a region of
+memory set aside for storing sensitive data. Because such memory is a
+scarce resource, it needs to be setup in advanced to a fixed size.
+Further, most operating systems have special requirements on how that
+secure memory can be used. For example, it might be required to install
+an application as "setuid(root)" to allow allocating such memory.
+Libgcrypt requires a sequence of initialization steps to make sure that
+this works correctly. The following examples show the necessary steps.
+
+ If you don't have a need for secure memory, for example if your
+application does not use secret keys or other confidential data or it
+runs in a controlled environment where key material floating around in
+memory is not a problem, you should initialize Libgcrypt this way:
+
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are intialized. */
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fputs ("libgcrypt version mismatch\n", stderr);
+ exit (2);
+ }
+
+ /* Disable secure memory. */
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ If you have to protect your keys or other information in memory
+against being swapped out to disk and to enable an automatic overwrite
+of used and freed memory, you need to initialize Libgcrypt this way:
+
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are intialized. */
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fputs ("libgcrypt version mismatch\n", stderr);
+ exit (2);
+ }
+
+ /* We don't want to see any warnings, e.g. because we have not yet
+ parsed program options which might be used to suppress such
+ warnings. */
+ gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. Note that the
+ process might still be running with increased privileges and that
+ the secure memory has not been intialized. */
+
+ /* Allocate a pool of 16k secure memory. This make the secure memory
+ available and also drops privileges where needed. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* It is now okay to let Libgcrypt complain when there was/is
+ a problem with the secure memory. */
+ gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ It is important that these initialization steps are not done by a
+library but by the actual application. A library using Libgcrypt might
+want to check for finished initialization using:
+
+ if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
+ {
+ fputs ("libgcrypt has not been initialized\n", stderr);
+ abort ();
+ }
+
+ Instead of terminating the process, the library may instead print a
+warning and try to initialize Libgcrypt itself. See also the section on
+multi-threading below for more pitfalls.
+
+\1f
+File: gcrypt.info, Node: Multi-Threading, Next: Enabling FIPS mode, Prev: Initializing the library, Up: Preparation
+
+2.5 Multi-Threading
+===================
+
+As mentioned earlier, the Libgcrypt library is thread-safe if you
+adhere to the following requirements:
+
+ * If your application is multi-threaded, you must set the thread
+ support callbacks with the `GCRYCTL_SET_THREAD_CBS' command
+ *before* any other function in the library.
+
+ This is easy enough if you are indeed writing an application using
+ Libgcrypt. It is rather problematic if you are writing a library
+ instead. Here are some tips what to do if you are writing a
+ library:
+
+ If your library requires a certain thread package, just initialize
+ Libgcrypt to use this thread package. If your library supports
+ multiple thread packages, but needs to be configured, you will
+ have to implement a way to determine which thread package the
+ application wants to use with your library anyway. Then configure
+ Libgcrypt to use this thread package.
+
+ If your library is fully reentrant without any special support by a
+ thread package, then you are lucky indeed. Unfortunately, this
+ does not relieve you from doing either of the two above, or use a
+ third option. The third option is to let the application
+ initialize Libgcrypt for you. Then you are not using Libgcrypt
+ transparently, though.
+
+ As if this was not difficult enough, a conflict may arise if two
+ libraries try to initialize Libgcrypt independently of each
+ others, and both such libraries are then linked into the same
+ application. To make it a bit simpler for you, this will probably
+ work, but only if both libraries have the same requirement for the
+ thread package. This is currently only supported for the
+ non-threaded case, GNU Pth and pthread.
+
+ If you use pthread and your applications forks and does not
+ directly call exec (even calling stdio functions), all kind of
+ problems may occur. Future versions of Libgcrypt will try to
+ cleanup using pthread_atfork but even that may lead to problems.
+ This is a common problem with almost all applications using
+ pthread and fork.
+
+ Note that future versions of Libgcrypt will drop this flexible
+ thread support and instead only support the platforms standard
+ thread implementation.
+
+ * The function `gcry_check_version' must be called before any other
+ function in the library, except the `GCRYCTL_SET_THREAD_CBS'
+ command (called via the `gcry_control' function), because it
+ initializes the thread support subsystem in Libgcrypt. To achieve
+ this in multi-threaded programs, you must synchronize the memory
+ with respect to other threads that also want to use Libgcrypt.
+ For this, it is sufficient to call `gcry_check_version' before
+ creating the other threads using Libgcrypt(1).
+
+ * Just like the function `gpg_strerror', the function
+ `gcry_strerror' is not thread safe. You have to use
+ `gpg_strerror_r' instead.
+
+
+ Libgcrypt contains convenient macros, which define the necessary
+thread callbacks for PThread and for GNU Pth:
+
+`GCRY_THREAD_OPTION_PTH_IMPL'
+ This macro defines the following (static) symbols:
+ `gcry_pth_init', `gcry_pth_mutex_init', `gcry_pth_mutex_destroy',
+ `gcry_pth_mutex_lock', `gcry_pth_mutex_unlock', `gcry_pth_read',
+ `gcry_pth_write', `gcry_pth_select', `gcry_pth_waitpid',
+ `gcry_pth_accept', `gcry_pth_connect', `gcry_threads_pth'.
+
+ After including this macro, `gcry_control()' shall be used with a
+ command of `GCRYCTL_SET_THREAD_CBS' in order to register the
+ thread callback structure named "gcry_threads_pth". Example:
+
+ ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+
+`GCRY_THREAD_OPTION_PTHREAD_IMPL'
+ This macro defines the following (static) symbols:
+ `gcry_pthread_mutex_init', `gcry_pthread_mutex_destroy',
+ `gcry_pthread_mutex_lock', `gcry_pthread_mutex_unlock',
+ `gcry_threads_pthread'.
+
+ After including this macro, `gcry_control()' shall be used with a
+ command of `GCRYCTL_SET_THREAD_CBS' in order to register the
+ thread callback structure named "gcry_threads_pthread". Example:
+
+ ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+
+
+ Note that these macros need to be terminated with a semicolon. Keep
+in mind that these are convenient macros for C programmers; C++
+programmers might have to wrap these macros in an "extern C" body.
+
+ ---------- Footnotes ----------
+
+ (1) At least this is true for POSIX threads, as `pthread_create' is
+a function that synchronizes memory with respects to other threads.
+There are many functions which have this property, a complete list can
+be found in POSIX, IEEE Std 1003.1-2003, Base Definitions, Issue 6, in
+the definition of the term "Memory Synchronization". For other thread
+packages, more relaxed or more strict rules may apply.
+
+\1f
+File: gcrypt.info, Node: Enabling FIPS mode, Prev: Multi-Threading, Up: Preparation
+
+2.6 How to enable the FIPS mode
+===============================
+
+Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not
+necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check
+the NIST database at `http://csrc.nist.gov/groups/STM/cmvp/' to see what
+versions of Libgcrypt are approved.
+
+ Because FIPS 140 has certain restrictions on the use of cryptography
+which are not always wanted, Libgcrypt needs to be put into FIPS mode
+explicitly. Three alternative mechanisms are provided to switch
+Libgcrypt into this mode:
+
+ * If the file `/proc/sys/crypto/fips_enabled' exists and contains a
+ numeric value other than `0', Libgcrypt is put into FIPS mode at
+ initialization time. Obviously this works only on systems with a
+ `proc' file system (i.e. GNU/Linux).
+
+ * If the file `/etc/gcrypt/fips_enabled' exists, Libgcrypt is put
+ into FIPS mode at initialization time. Note that this filename is
+ hardwired and does not depend on any configuration options.
+
+ * If the application requests FIPS mode using the control command
+ `GCRYCTL_FORCE_FIPS_MODE'. This must be done prior to any
+ initialization (i.e. before `gcry_check_version').
+
+
+ In addition to the standard FIPS mode, Libgcrypt may also be put into
+an Enforced FIPS mode by writing a non-zero value into the file
+`/etc/gcrypt/fips_enabled'. The Enforced FIPS mode helps to detect
+applications which don't fulfill all requirements for using Libgcrypt
+in FIPS mode (*note FIPS Mode::).
+
+ Once Libgcrypt has been put into FIPS mode, it is not possible to
+switch back to standard mode without terminating the process first. If
+the logging verbosity level of Libgcrypt has been set to at least 2,
+the state transitions and the self-tests are logged.
+
+\1f
+File: gcrypt.info, Node: Generalities, Next: Handler Functions, Prev: Preparation, Up: Top
+
+3 Generalities
+**************
+
+* Menu:
+
+* Controlling the library:: Controlling Libgcrypt's behavior.
+* Modules:: Description of extension modules.
+* Error Handling:: Error codes and such.
+
+\1f
+File: gcrypt.info, Node: Controlling the library, Next: Modules, Up: Generalities
+
+3.1 Controlling the library
+===========================
+
+ -- Function: gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...)
+ This function can be used to influence the general behavior of
+ Libgcrypt in several ways. Depending on CMD, more arguments can
+ or have to be provided.
+
+ `GCRYCTL_ENABLE_M_GUARD; Arguments: none'
+ This command enables the built-in memory guard. It must not
+ be used to activate the memory guard after the memory
+ management has already been used; therefore it can ONLY be
+ used before `gcry_check_version'. Note that the memory guard
+ is NOT used when the user of the library has set his own
+ memory management callbacks.
+
+ `GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none'
+ This command inhibits the use the very secure random quality
+ level (`GCRY_VERY_STRONG_RANDOM') and degrades all request
+ down to `GCRY_STRONG_RANDOM'. In general this is not
+ recommened. However, for some applications the extra quality
+ random Libgcrypt tries to create is not justified and this
+ option may help to get better performace. Please check with
+ a crypto expert whether this option can be used for your
+ application.
+
+ This option can only be used at initialization time.
+
+ `GCRYCTL_DUMP_RANDOM_STATS; Arguments: none'
+ This command dumps randum number generator related statistics
+ to the library's logging stream.
+
+ `GCRYCTL_DUMP_MEMORY_STATS; Arguments: none'
+ This command dumps memory managment related statistics to the
+ library's logging stream.
+
+ `GCRYCTL_DUMP_SECMEM_STATS; Arguments: none'
+ This command dumps secure memory manamgent related statistics
+ to the library's logging stream.
+
+ `GCRYCTL_DROP_PRIVS; Arguments: none'
+ This command disables the use of secure memory and drops the
+ priviliges of the current process. This command has not much
+ use; the suggested way to disable secure memory is to use
+ `GCRYCTL_DISABLE_SECMEM' right after initialization.
+
+ `GCRYCTL_DISABLE_SECMEM; Arguments: none'
+ This command disables the use of secure memory. If this
+ command is used in FIPS mode, FIPS mode will be disabled and
+ the function `gcry_fips_mode_active' returns false. However,
+ in Enforced FIPS mode this command has no effect at all.
+
+ Many applications do not require secure memory, so they
+ should disable it right away. This command should be
+ executed right after `gcry_check_version'.
+
+ `GCRYCTL_INIT_SECMEM; Arguments: int nbytes'
+ This command is used to allocate a pool of secure memory and
+ thus enabling the use of secure memory. It also drops all
+ extra privileges the process has (i.e. if it is run as setuid
+ (root)). If the argument NBYTES is 0, secure memory will be
+ disabled. The minimum amount of secure memory allocated is
+ currently 16384 bytes; you may thus use a value of 1 to
+ request that default size.
+
+ `GCRYCTL_TERM_SECMEM; Arguments: none'
+ This command zeroises the secure memory and destroys the
+ handler. The secure memory pool may not be used anymore
+ after running this command. If the secure memory pool as
+ already been destroyed, this command has no effect.
+ Applications might want to run this command from their exit
+ handler to make sure that the secure memory gets properly
+ destroyed. This command is not necessarily thread-safe but
+ that should not be needed in cleanup code. It may be called
+ from a signal handler.
+
+ `GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none'
+ Disable warning messages about problems with the secure memory
+ subsystem. This command should be run right after
+ `gcry_check_version'.
+
+ `GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none'
+ Postpone warning messages from the secure memory subsystem.
+ *Note the initialization example: sample-use-suspend-secmem,
+ on how to use it.
+
+ `GCRYCTL_RESUME_SECMEM_WARN; Arguments: none'
+ Resume warning messages from the secure memory subsystem.
+ *Note the initialization example: sample-use-resume-secmem,
+ on how to use it.
+
+ `GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none'
+ This command tells the PRNG to store random numbers in secure
+ memory. This command should be run right after
+ `gcry_check_version' and not later than the command
+ GCRYCTL_INIT_SECMEM. Note that in FIPS mode the secure
+ memory is always used.
+
+ `GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename'
+ This command specifies the file, which is to be used as seed
+ file for the PRNG. If the seed file is registered prior to
+ initialization of the PRNG, the seed file's content (if it
+ exists and seems to be valid) is fed into the PRNG pool.
+ After the seed file has been registered, the PRNG can be
+ signalled to write out the PRNG pool's content into the seed
+ file with the following command.
+
+ `GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none'
+ Write out the PRNG pool's content into the registered seed
+ file.
+
+ Multiple instances of the applications sharing the same
+ random seed file can be started in parallel, in which case
+ they will read out the same pool and then race for updating
+ it (the last update overwrites earlier updates). They will
+ differentiate only by the weak entropy that is added in
+ read_seed_file based on the PID and clock, and up to 16 bytes
+ of weak random non-blockingly. The consequence is that the
+ output of these different instances is correlated to some
+ extent. In a perfect attack scenario, the attacker can
+ control (or at least guess) the PID and clock of the
+ application, and drain the system's entropy pool to reduce
+ the "up to 16 bytes" above to 0. Then the dependencies of the
+ inital states of the pools are completely known. Note that
+ this is not an issue if random of `GCRY_VERY_STRONG_RANDOM'
+ quality is requested as in this case enough extra entropy
+ gets mixed. It is also not an issue when using Linux
+ (rndlinux driver), because this one guarantees to read full
+ 16 bytes from /dev/urandom and thus there is no way for an
+ attacker without kernel access to control these 16 bytes.
+
+ `GCRYCTL_SET_VERBOSITY; Arguments: int level'
+ This command sets the verbosity of the logging. A level of 0
+ disables all extra logging whereas positive numbers enable
+ more verbose logging. The level may be changed at any time
+ but be aware that no memory synchronization is done so the
+ effect of this command might not immediately show up in other
+ threads. This command may even be used prior to
+ `gcry_check_version'.
+
+ `GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags'
+ Set the debug flag bits as given by the argument. Be aware
+ that that no memory synchronization is done so the effect of
+ this command might not immediately show up in other threads.
+ The debug flags are not considered part of the API and thus
+ may change without notice. As of now bit 0 enables debugging
+ of cipher functions and bit 1 debugging of
+ multi-precision-integers. This command may even be used
+ prior to `gcry_check_version'.
+
+ `GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags'
+ Set the debug flag bits as given by the argument. Be aware
+ that that no memory synchronization is done so the effect of
+ this command might not immediately show up in other threads.
+ This command may even be used prior to `gcry_check_version'.
+
+ `GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none'
+ This command does nothing. It exists only for backward
+ compatibility.
+
+ `GCRYCTL_ANY_INITIALIZATION_P; Arguments: none'
+ This command returns true if the library has been basically
+ initialized. Such a basic initialization happens implicitly
+ with many commands to get certain internal subsystems
+ running. The common and suggested way to do this basic
+ intialization is by calling gcry_check_version.
+
+ `GCRYCTL_INITIALIZATION_FINISHED; Arguments: none'
+ This command tells the library that the application has
+ finished the intialization.
+
+ `GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none'
+ This command returns true if the command
+ GCRYCTL_INITIALIZATION_FINISHED has already been run.
+
+ `GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops'
+ This command registers a thread-callback structure. *Note
+ Multi-Threading::.
+
+ `GCRYCTL_FAST_POLL; Arguments: none'
+ Run a fast random poll.
+
+ `GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename'
+ This command may be used to override the default name of the
+ EGD socket to connect to. It may be used only during
+ initialization as it is not thread safe. Changing the socket
+ name again is not supported. The function may return an
+ error if the given filename is too long for a local socket
+ name.
+
+ EGD is an alternative random gatherer, used only on systems
+ lacking a proper random device.
+
+ `GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream'
+ This command dumps information pertaining to the
+ configuration of the library to the given stream. If NULL is
+ given for STREAM, the log system is used. This command may
+ be used before the intialization has been finished but not
+ before a gcry_version_check.
+
+ `GCRYCTL_OPERATIONAL_P; Arguments: none'
+ This command returns true if the library is in an operational
+ state. This information makes only sense in FIPS mode. In
+ contrast to other functions, this is a pure test function and
+ won't put the library into FIPS mode or change the internal
+ state. This command may be used before the intialization has
+ been finished but not before a gcry_version_check.
+
+ `GCRYCTL_FIPS_MODE_P; Arguments: none'
+ This command returns true if the library is in FIPS mode.
+ Note, that this is no indication about the current state of
+ the library. This command may be used before the
+ intialization has been finished but not before a
+ gcry_version_check. An application may use this command or
+ the convenience macro below to check whether FIPS mode is
+ actually active.
+
+ -- Function: int gcry_fips_mode_active (void)
+ Returns true if the FIPS mode is active. Note that this
+ is implemented as a macro.
+
+ `GCRYCTL_FORCE_FIPS_MODE; Arguments: none'
+ Running this command puts the library into FIPS mode. If the
+ library is already in FIPS mode, a self-test is triggered and
+ thus the library will be put into operational state. This
+ command may be used before a call to gcry_check_version and
+ that is actually the recommended way to let an application
+ switch the library into FIPS mode. Note that Libgcrypt will
+ reject an attempt to switch to fips mode during or after the
+ intialization.
+
+ `GCRYCTL_SELFTEST; Arguments: none'
+ This may be used at anytime to have the library run all
+ implemented self-tests. It works in standard and in FIPS
+ mode. Returns 0 on success or an error code on failure.
+
+ `GCRYCTL_DISABLE_HWF; Arguments: const char *name'
+ Libgcrypt detects certain features of the CPU at startup
+ time. For performace tests it is sometimes required not to
+ use such a feature. This option may be used to disabale a
+ certain feature; i.e. Libgcrypt behaves as if this feature
+ has not been detected. Note that the detection code might be
+ run if the feature has been disabled. This command must be
+ used at initialization time; i.e. before calling
+ `gcry_check_version'.
+
+
+
+\1f
+File: gcrypt.info, Node: Modules, Next: Error Handling, Prev: Controlling the library, Up: Generalities
+
+3.2 Modules
+===========
+
+Libgcrypt supports the use of `extension modules', which implement
+algorithms in addition to those already built into the library directly.
+
+ -- Data type: gcry_module_t
+ This data type represents a `module'.
+
+ Functions registering modules provided by the user take a `module
+specification structure' as input and return a value of `gcry_module_t'
+and an ID that is unique in the modules' category. This ID can be used
+to reference the newly registered module. After registering a module
+successfully, the new functionality should be able to be used through
+the normal functions provided by Libgcrypt until it is unregistered
+again.
+
+\1f
+File: gcrypt.info, Node: Error Handling, Prev: Modules, Up: Generalities
+
+3.3 Error Handling
+==================
+
+Many functions in Libgcrypt can return an error if they fail. For this
+reason, the application should always catch the error condition and
+take appropriate measures, for example by releasing the resources and
+passing the error up to the caller, or by displaying a descriptive
+message to the user and cancelling the operation.
+
+ Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly. For
+example, if you try to decrypt a tempered message, the decryption will
+fail. Another error value actually means that the end of a data buffer
+or list has been reached. The following descriptions explain for many
+error codes what they mean usually. Some error values have specific
+meanings if returned by a certain functions. Such cases are described
+in the documentation of those functions.
+
+ Libgcrypt uses the `libgpg-error' library. This allows to share the
+error codes with other components of the GnuPG system, and to pass
+error values transparently from the crypto engine, or some helper
+application of the crypto engine, to the user. This way no information
+is lost. As a consequence, Libgcrypt does not use its own identifiers
+for error codes, but uses those provided by `libgpg-error'. They
+usually start with `GPG_ERR_'.
+
+ However, Libgcrypt does provide aliases for the functions defined in
+libgpg-error, which might be preferred for name space consistency.
+
+ Most functions in Libgcrypt return an error code in the case of
+failure. For this reason, the application should always catch the
+error condition and take appropriate measures, for example by releasing
+the resources and passing the error up to the caller, or by displaying
+a descriptive message to the user and canceling the operation.
+
+ Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.
+
+ GnuPG components, including Libgcrypt, use an extra library named
+libgpg-error to provide a common error handling scheme. For more
+information on libgpg-error, see the according manual.
+
+* Menu:
+
+* Error Values:: The error value and what it means.
+* Error Sources:: A list of important error sources.
+* Error Codes:: A list of important error codes.
+* Error Strings:: How to get a descriptive string from a value.
+
+\1f
+File: gcrypt.info, Node: Error Values, Next: Error Sources, Up: Error Handling
+
+3.3.1 Error Values
+------------------
+
+ -- Data type: gcry_err_code_t
+ The `gcry_err_code_t' type is an alias for the `libgpg-error' type
+ `gpg_err_code_t'. The error code indicates the type of an error,
+ or the reason why an operation failed.
+
+ A list of important error codes can be found in the next section.
+
+ -- Data type: gcry_err_source_t
+ The `gcry_err_source_t' type is an alias for the `libgpg-error'
+ type `gpg_err_source_t'. The error source has not a precisely
+ defined meaning. Sometimes it is the place where the error
+ happened, sometimes it is the place where an error was encoded
+ into an error value. Usually the error source will give an
+ indication to where to look for the problem. This is not always
+ true, but it is attempted to achieve this goal.
+
+ A list of important error sources can be found in the next section.
+
+ -- Data type: gcry_error_t
+ The `gcry_error_t' type is an alias for the `libgpg-error' type
+ `gpg_error_t'. An error value like this has always two
+ components, an error code and an error source. Both together form
+ the error value.
+
+ Thus, the error value can not be directly compared against an error
+ code, but the accessor functions described below must be used.
+ However, it is guaranteed that only 0 is used to indicate success
+ (`GPG_ERR_NO_ERROR'), and that in this case all other parts of the
+ error value are set to 0, too.
+
+ Note that in Libgcrypt, the error source is used purely for
+ diagnostic purposes. Only the error code should be checked to test
+ for a certain outcome of a function. The manual only documents the
+ error code part of an error value. The error source is left
+ unspecified and might be anything.
+
+ -- Function: gcry_err_code_t gcry_err_code (gcry_error_t ERR)
+ The static inline function `gcry_err_code' returns the
+ `gcry_err_code_t' component of the error value ERR. This function
+ must be used to extract the error code from an error value in
+ order to compare it with the `GPG_ERR_*' error code macros.
+
+ -- Function: gcry_err_source_t gcry_err_source (gcry_error_t ERR)
+ The static inline function `gcry_err_source' returns the
+ `gcry_err_source_t' component of the error value ERR. This
+ function must be used to extract the error source from an error
+ value in order to compare it with the `GPG_ERR_SOURCE_*' error
+ source macros.
+
+ -- Function: gcry_error_t gcry_err_make (gcry_err_source_t SOURCE,
+ gcry_err_code_t CODE)
+ The static inline function `gcry_err_make' returns the error value
+ consisting of the error source SOURCE and the error code CODE.
+
+ This function can be used in callback functions to construct an
+ error value to return it to the library.
+
+ -- Function: gcry_error_t gcry_error (gcry_err_code_t CODE)
+ The static inline function `gcry_error' returns the error value
+ consisting of the default error source and the error code CODE.
+
+ For GCRY applications, the default error source is
+ `GPG_ERR_SOURCE_USER_1'. You can define `GCRY_ERR_SOURCE_DEFAULT'
+ before including `gcrypt.h' to change this default.
+
+ This function can be used in callback functions to construct an
+ error value to return it to the library.
+
+ The `libgpg-error' library provides error codes for all system error
+numbers it knows about. If ERR is an unknown error number, the error
+code `GPG_ERR_UNKNOWN_ERRNO' is used. The following functions can be
+used to construct error values from system errno numbers.
+
+ -- Function: gcry_error_t gcry_err_make_from_errno
+ (gcry_err_source_t SOURCE, int ERR)
+ The function `gcry_err_make_from_errno' is like `gcry_err_make',
+ but it takes a system error like `errno' instead of a
+ `gcry_err_code_t' error code.
+
+ -- Function: gcry_error_t gcry_error_from_errno (int ERR)
+ The function `gcry_error_from_errno' is like `gcry_error', but it
+ takes a system error like `errno' instead of a `gcry_err_code_t'
+ error code.
+
+ Sometimes you might want to map system error numbers to error codes
+directly, or map an error code representing a system error back to the
+system error number. The following functions can be used to do that.
+
+ -- Function: gcry_err_code_t gcry_err_code_from_errno (int ERR)
+ The function `gcry_err_code_from_errno' returns the error code for
+ the system error ERR. If ERR is not a known system error, the
+ function returns `GPG_ERR_UNKNOWN_ERRNO'.
+
+ -- Function: int gcry_err_code_to_errno (gcry_err_code_t ERR)
+ The function `gcry_err_code_to_errno' returns the system error for
+ the error code ERR. If ERR is not an error code representing a
+ system error, or if this system error is not defined on this
+ system, the function returns `0'.
+
+\1f
+File: gcrypt.info, Node: Error Sources, Next: Error Codes, Prev: Error Values, Up: Error Handling
+
+3.3.2 Error Sources
+-------------------
+
+The library `libgpg-error' defines an error source for every component
+of the GnuPG system. The error source part of an error value is not
+well defined. As such it is mainly useful to improve the diagnostic
+error message for the user.
+
+ If the error code part of an error value is `0', the whole error
+value will be `0'. In this case the error source part is of course
+`GPG_ERR_SOURCE_UNKNOWN'.
+
+ The list of error sources that might occur in applications using
+Libgcrypt is:
+
+`GPG_ERR_SOURCE_UNKNOWN'
+ The error source is not known. The value of this error source is
+ `0'.
+
+`GPG_ERR_SOURCE_GPGME'
+ The error source is GPGME itself.
+
+`GPG_ERR_SOURCE_GPG'
+ The error source is GnuPG, which is the crypto engine used for the
+ OpenPGP protocol.
+
+`GPG_ERR_SOURCE_GPGSM'
+ The error source is GPGSM, which is the crypto engine used for the
+ OpenPGP protocol.
+
+`GPG_ERR_SOURCE_GCRYPT'
+ The error source is `libgcrypt', which is used by crypto engines
+ to perform cryptographic operations.
+
+`GPG_ERR_SOURCE_GPGAGENT'
+ The error source is `gpg-agent', which is used by crypto engines
+ to perform operations with the secret key.
+
+`GPG_ERR_SOURCE_PINENTRY'
+ The error source is `pinentry', which is used by `gpg-agent' to
+ query the passphrase to unlock a secret key.
+
+`GPG_ERR_SOURCE_SCD'
+ The error source is the SmartCard Daemon, which is used by
+ `gpg-agent' to delegate operations with the secret key to a
+ SmartCard.
+
+`GPG_ERR_SOURCE_KEYBOX'
+ The error source is `libkbx', a library used by the crypto engines
+ to manage local keyrings.
+
+`GPG_ERR_SOURCE_USER_1'
+
+`GPG_ERR_SOURCE_USER_2'
+
+`GPG_ERR_SOURCE_USER_3'
+
+`GPG_ERR_SOURCE_USER_4'
+ These error sources are not used by any GnuPG component and can be
+ used by other software. For example, applications using Libgcrypt
+ can use them to mark error values coming from callback handlers.
+ Thus `GPG_ERR_SOURCE_USER_1' is the default for errors created
+ with `gcry_error' and `gcry_error_from_errno', unless you define
+ `GCRY_ERR_SOURCE_DEFAULT' before including `gcrypt.h'.
+
+\1f
+File: gcrypt.info, Node: Error Codes, Next: Error Strings, Prev: Error Sources, Up: Error Handling
+
+3.3.3 Error Codes
+-----------------
+
+The library `libgpg-error' defines many error values. The following
+list includes the most important error codes.
+
+`GPG_ERR_EOF'
+ This value indicates the end of a list, buffer or file.
+
+`GPG_ERR_NO_ERROR'
+ This value indicates success. The value of this error code is
+ `0'. Also, it is guaranteed that an error value made from the
+ error code `0' will be `0' itself (as a whole). This means that
+ the error source information is lost for this error code, however,
+ as this error code indicates that no error occurred, this is
+ generally not a problem.
+
+`GPG_ERR_GENERAL'
+ This value means that something went wrong, but either there is not
+ enough information about the problem to return a more useful error
+ value, or there is no separate error value for this type of
+ problem.
+
+`GPG_ERR_ENOMEM'
+ This value means that an out-of-memory condition occurred.
+
+`GPG_ERR_E...'
+ System errors are mapped to GPG_ERR_EFOO where FOO is the symbol
+ for the system error.
+
+`GPG_ERR_INV_VALUE'
+ This value means that some user provided data was out of range.
+
+`GPG_ERR_UNUSABLE_PUBKEY'
+ This value means that some recipients for a message were invalid.
+
+`GPG_ERR_UNUSABLE_SECKEY'
+ This value means that some signers were invalid.
+
+`GPG_ERR_NO_DATA'
+ This value means that data was expected where no data was found.
+
+`GPG_ERR_CONFLICT'
+ This value means that a conflict of some sort occurred.
+
+`GPG_ERR_NOT_IMPLEMENTED'
+ This value indicates that the specific function (or operation) is
+ not implemented. This error should never happen. It can only
+ occur if you use certain values or configuration options which do
+ not work, but for which we think that they should work at some
+ later time.
+
+`GPG_ERR_DECRYPT_FAILED'
+ This value indicates that a decryption operation was unsuccessful.
+
+`GPG_ERR_WRONG_KEY_USAGE'
+ This value indicates that a key is not used appropriately.
+
+`GPG_ERR_NO_SECKEY'
+ This value indicates that no secret key for the user ID is
+ available.
+
+`GPG_ERR_UNSUPPORTED_ALGORITHM'
+ This value means a verification failed because the cryptographic
+ algorithm is not supported by the crypto backend.
+
+`GPG_ERR_BAD_SIGNATURE'
+ This value means a verification failed because the signature is
+ bad.
+
+`GPG_ERR_NO_PUBKEY'
+ This value means a verification failed because the public key is
+ not available.
+
+`GPG_ERR_NOT_OPERATIONAL'
+ This value means that the library is not yet in state which allows
+ to use this function. This error code is in particular returned if
+ Libgcrypt is operated in FIPS mode and the internal state of the
+ library does not yet or not anymore allow the use of a service.
+
+ This error code is only available with newer libgpg-error
+ versions, thus you might see "invalid error code" when passing
+ this to `gpg_strerror'. The numeric value of this error code is
+ 176.
+
+`GPG_ERR_USER_1'
+
+`GPG_ERR_USER_2'
+
+`...'
+
+`GPG_ERR_USER_16'
+ These error codes are not used by any GnuPG component and can be
+ freely used by other software. Applications using Libgcrypt might
+ use them to mark specific errors returned by callback handlers if
+ no suitable error codes (including the system errors) for these
+ errors exist already.
+
+\1f
+File: gcrypt.info, Node: Error Strings, Prev: Error Codes, Up: Error Handling
+
+3.3.4 Error Strings
+-------------------
+
+ -- Function: const char * gcry_strerror (gcry_error_t ERR)
+ The function `gcry_strerror' returns a pointer to a statically
+ allocated string containing a description of the error code
+ contained in the error value ERR. This string can be used to
+ output a diagnostic message to the user.
+
+ -- Function: const char * gcry_strsource (gcry_error_t ERR)
+ The function `gcry_strerror' returns a pointer to a statically
+ allocated string containing a description of the error source
+ contained in the error value ERR. This string can be used to
+ output a diagnostic message to the user.
+
+ The following example illustrates the use of the functions described
+above:
+
+ {
+ gcry_cipher_hd_t handle;
+ gcry_error_t err = 0;
+
+ err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ {
+ fprintf (stderr, "Failure: %s/%s\n",
+ gcry_strsource (err),
+ gcry_strerror (err));
+ }
+ }
+
+\1f
+File: gcrypt.info, Node: Handler Functions, Next: Symmetric cryptography, Prev: Generalities, Up: Top
+
+4 Handler Functions
+*******************
+
+Libgcrypt makes it possible to install so called `handler functions',
+which get called by Libgcrypt in case of certain events.
+
+* Menu:
+
+* Progress handler:: Using a progress handler function.
+* Allocation handler:: Using special memory allocation functions.
+* Error handler:: Using error handler functions.
+* Logging handler:: Using a special logging function.
+
+\1f
+File: gcrypt.info, Node: Progress handler, Next: Allocation handler, Up: Handler Functions
+
+4.1 Progress handler
+====================
+
+It is often useful to retrieve some feedback while long running
+operations are performed.
+
+ -- Data type: gcry_handler_progress_t
+ Progress handler functions have to be of the type
+ `gcry_handler_progress_t', which is defined as:
+
+ `void (*gcry_handler_progress_t) (void *, const char *, int, int,
+ int)'
+
+ The following function may be used to register a handler function for
+this purpose.
+
+ -- Function: void gcry_set_progress_handler (gcry_handler_progress_t
+ CB, void *CB_DATA)
+ This function installs CB as the `Progress handler' function. It
+ may be used only during initialization. CB must be defined as
+ follows:
+
+ void
+ my_progress_handler (void *CB_DATA, const char *WHAT,
+ int PRINTCHAR, int CURRENT, int TOTAL)
+ {
+ /* Do something. */
+ }
+
+ A description of the arguments of the progress handler function
+ follows.
+
+ CB_DATA
+ The argument provided in the call to
+ `gcry_set_progress_handler'.
+
+ WHAT
+ A string identifying the type of the progress output. The
+ following values for WHAT are defined:
+
+ `need_entropy'
+ Not enough entropy is available. TOTAL holds the number
+ of required bytes.
+
+ `primegen'
+ Values for PRINTCHAR:
+ `\n'
+ Prime generated.
+
+ `!'
+ Need to refresh the pool of prime numbers.
+
+ `<, >'
+ Number of bits adjusted.
+
+ `^'
+ Searching for a generator.
+
+ `.'
+ Fermat test on 10 candidates failed.
+
+ `:'
+ Restart with a new random value.
+
+ `+'
+ Rabin Miller test passed.
+
+
+
+\1f
+File: gcrypt.info, Node: Allocation handler, Next: Error handler, Prev: Progress handler, Up: Handler Functions
+
+4.2 Allocation handler
+======================
+
+It is possible to make Libgcrypt use special memory allocation
+functions instead of the built-in ones.
+
+ Memory allocation functions are of the following types:
+
+ -- Data type: gcry_handler_alloc_t
+ This type is defined as: `void *(*gcry_handler_alloc_t) (size_t
+ n)'.
+
+ -- Data type: gcry_handler_secure_check_t
+ This type is defined as: `int *(*gcry_handler_secure_check_t)
+ (const void *)'.
+
+ -- Data type: gcry_handler_realloc_t
+ This type is defined as: `void *(*gcry_handler_realloc_t) (void
+ *p, size_t n)'.
+
+ -- Data type: gcry_handler_free_t
+ This type is defined as: `void *(*gcry_handler_free_t) (void *)'.
+
+ Special memory allocation functions can be installed with the
+following function:
+
+ -- Function: void gcry_set_allocation_handler (gcry_handler_alloc_t
+ FUNC_ALLOC, gcry_handler_alloc_t FUNC_ALLOC_SECURE,
+ gcry_handler_secure_check_t FUNC_SECURE_CHECK,
+ gcry_handler_realloc_t FUNC_REALLOC, gcry_handler_free_t
+ FUNC_FREE)
+ Install the provided functions and use them instead of the built-in
+ functions for doing memory allocation. Using this function is in
+ general not recommended because the standard Libgcrypt allocation
+ functions are guaranteed to zeroize memory if needed.
+
+ This function may be used only during initialization and may not be
+ used in fips mode.
+
+
+\1f
+File: gcrypt.info, Node: Error handler, Next: Logging handler, Prev: Allocation handler, Up: Handler Functions
+
+4.3 Error handler
+=================
+
+The following functions may be used to register handler functions that
+are called by Libgcrypt in case certain error conditions occur. They
+may and should be registered prior to calling `gcry_check_version'.
+
+ -- Data type: gcry_handler_no_mem_t
+ This type is defined as: `int (*gcry_handler_no_mem_t) (void *,
+ size_t, unsigned int)'
+
+ -- Function: void gcry_set_outofcore_handler (gcry_handler_no_mem_t
+ FUNC_NO_MEM, void *CB_DATA)
+ This function registers FUNC_NO_MEM as `out-of-core handler',
+ which means that it will be called in the case of not having enough
+ memory available. The handler is called with 3 arguments: The
+ first one is the pointer CB_DATA as set with this function, the
+ second is the requested memory size and the last being a flag. If
+ bit 0 of the flag is set, secure memory has been requested. The
+ handler should either return true to indicate that Libgcrypt
+ should try again allocating memory or return false to let
+ Libgcrypt use its default fatal error handler.
+
+ -- Data type: gcry_handler_error_t
+ This type is defined as: `void (*gcry_handler_error_t) (void *,
+ int, const char *)'
+
+ -- Function: void gcry_set_fatalerror_handler (gcry_handler_error_t
+ FUNC_ERROR, void *CB_DATA)
+ This function registers FUNC_ERROR as `error handler', which means
+ that it will be called in error conditions.
+
+\1f
+File: gcrypt.info, Node: Logging handler, Prev: Error handler, Up: Handler Functions
+
+4.4 Logging handler
+===================
+
+ -- Data type: gcry_handler_log_t
+ This type is defined as: `void (*gcry_handler_log_t) (void *, int,
+ const char *, va_list)'
+
+ -- Function: void gcry_set_log_handler (gcry_handler_log_t FUNC_LOG,
+ void *CB_DATA)
+ This function registers FUNC_LOG as `logging handler', which means
+ that it will be called in case Libgcrypt wants to log a message.
+ This function may and should be used prior to calling
+ `gcry_check_version'.
+
+\1f
+File: gcrypt.info, Node: Symmetric cryptography, Next: Public Key cryptography, Prev: Handler Functions, Up: Top
+
+5 Symmetric cryptography
+************************
+
+The cipher functions are used for symmetrical cryptography, i.e.
+cryptography using a shared key. The programming model follows an
+open/process/close paradigm and is in that similar to other building
+blocks provided by Libgcrypt.
+
+* Menu:
+
+* Available ciphers:: List of ciphers supported by the library.
+* Cipher modules:: How to work with cipher modules.
+* Available cipher modes:: List of cipher modes supported by the library.
+* Working with cipher handles:: How to perform operations related to cipher handles.
+* General cipher functions:: General cipher functions independent of cipher handles.
+
+\1f
+File: gcrypt.info, Node: Available ciphers, Next: Cipher modules, Up: Symmetric cryptography
+
+5.1 Available ciphers
+=====================
+
+`GCRY_CIPHER_NONE'
+ This is not a real algorithm but used by some functions as error
+ return. The value always evaluates to false.
+
+`GCRY_CIPHER_IDEA'
+ This is the IDEA algorithm. The constant is provided but there is
+ currently no implementation for it because the algorithm is
+ patented.
+
+`GCRY_CIPHER_3DES'
+ Triple-DES with 3 Keys as EDE. The key size of this algorithm is
+ 168 but you have to pass 192 bits because the most significant
+ bits of each byte are ignored.
+
+`GCRY_CIPHER_CAST5'
+ CAST128-5 block cipher algorithm. The key size is 128 bits.
+
+`GCRY_CIPHER_BLOWFISH'
+ The blowfish algorithm. The current implementation allows only for
+ a key size of 128 bits.
+
+`GCRY_CIPHER_SAFER_SK128'
+ Reserved and not currently implemented.
+
+`GCRY_CIPHER_DES_SK'
+ Reserved and not currently implemented.
+
+`GCRY_CIPHER_AES'
+`GCRY_CIPHER_AES128'
+`GCRY_CIPHER_RIJNDAEL'
+`GCRY_CIPHER_RIJNDAEL128'
+ AES (Rijndael) with a 128 bit key.
+
+`GCRY_CIPHER_AES192'
+`GCRY_CIPHER_RIJNDAEL192'
+ AES (Rijndael) with a 192 bit key.
+
+`GCRY_CIPHER_AES256'
+`GCRY_CIPHER_RIJNDAEL256'
+ AES (Rijndael) with a 256 bit key.
+
+`GCRY_CIPHER_TWOFISH'
+ The Twofish algorithm with a 256 bit key.
+
+`GCRY_CIPHER_TWOFISH128'
+ The Twofish algorithm with a 128 bit key.
+
+`GCRY_CIPHER_ARCFOUR'
+ An algorithm which is 100% compatible with RSA Inc.'s RC4
+ algorithm. Note that this is a stream cipher and must be used
+ very carefully to avoid a couple of weaknesses.
+
+`GCRY_CIPHER_DES'
+ Standard DES with a 56 bit key. You need to pass 64 bit but the
+ high bits of each byte are ignored. Note, that this is a weak
+ algorithm which can be broken in reasonable time using a brute
+ force approach.
+
+`GCRY_CIPHER_SERPENT128'
+`GCRY_CIPHER_SERPENT192'
+`GCRY_CIPHER_SERPENT256'
+ The Serpent cipher from the AES contest.
+
+`GCRY_CIPHER_RFC2268_40'
+`GCRY_CIPHER_RFC2268_128'
+ Ron's Cipher 2 in the 40 and 128 bit variants. Note, that we
+ currently only support the 40 bit variant. The identifier for 128
+ is reserved for future use.
+
+`GCRY_CIPHER_SEED'
+ A 128 bit cipher as described by RFC4269.
+
+`GCRY_CIPHER_CAMELLIA128'
+`GCRY_CIPHER_CAMELLIA192'
+`GCRY_CIPHER_CAMELLIA256'
+ The Camellia cipher by NTT. See
+ `http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html'.
+
+
+\1f
+File: gcrypt.info, Node: Cipher modules, Next: Available cipher modes, Prev: Available ciphers, Up: Symmetric cryptography
+
+5.2 Cipher modules
+==================
+
+Libgcrypt makes it possible to load additional `cipher modules'; these
+ciphers can be used just like the cipher algorithms that are built into
+the library directly. For an introduction into extension modules, see
+*Note Modules::.
+
+ -- Data type: gcry_cipher_spec_t
+ This is the `module specification structure' needed for registering
+ cipher modules, which has to be filled in by the user before it
+ can be used to register a module. It contains the following
+ members:
+
+ `const char *name'
+ The primary name of the algorithm.
+
+ `const char **aliases'
+ A list of strings that are `aliases' for the algorithm. The
+ list must be terminated with a NULL element.
+
+ `gcry_cipher_oid_spec_t *oids'
+ A list of OIDs that are to be associated with the algorithm.
+ The list's last element must have it's `oid' member set to
+ NULL. See below for an explanation of this type.
+
+ `size_t blocksize'
+ The block size of the algorithm, in bytes.
+
+ `size_t keylen'
+ The length of the key, in bits.
+
+ `size_t contextsize'
+ The size of the algorithm-specific `context', that should be
+ allocated for each handle.
+
+ `gcry_cipher_setkey_t setkey'
+ The function responsible for initializing a handle with a
+ provided key. See below for a description of this type.
+
+ `gcry_cipher_encrypt_t encrypt'
+ The function responsible for encrypting a single block. See
+ below for a description of this type.
+
+ `gcry_cipher_decrypt_t decrypt'
+ The function responsible for decrypting a single block. See
+ below for a description of this type.
+
+ `gcry_cipher_stencrypt_t stencrypt'
+ Like `encrypt', for stream ciphers. See below for a
+ description of this type.
+
+ `gcry_cipher_stdecrypt_t stdecrypt'
+ Like `decrypt', for stream ciphers. See below for a
+ description of this type.
+
+ -- Data type: gcry_cipher_oid_spec_t
+ This type is used for associating a user-provided algorithm
+ implementation with certain OIDs. It contains the following
+ members:
+ `const char *oid'
+ Textual representation of the OID.
+
+ `int mode'
+ Cipher mode for which this OID is valid.
+
+ -- Data type: gcry_cipher_setkey_t
+ Type for the `setkey' function, defined as: gcry_err_code_t
+ (*gcry_cipher_setkey_t) (void *c, const unsigned char *key,
+ unsigned keylen)
+
+ -- Data type: gcry_cipher_encrypt_t
+ Type for the `encrypt' function, defined as: gcry_err_code_t
+ (*gcry_cipher_encrypt_t) (void *c, const unsigned char *outbuf,
+ const unsigned char *inbuf)
+
+ -- Data type: gcry_cipher_decrypt_t
+ Type for the `decrypt' function, defined as: gcry_err_code_t
+ (*gcry_cipher_decrypt_t) (void *c, const unsigned char *outbuf,
+ const unsigned char *inbuf)
+
+ -- Data type: gcry_cipher_stencrypt_t
+ Type for the `stencrypt' function, defined as: gcry_err_code_t
+ (*gcry_cipher_stencrypt_t) (void *c, const unsigned char *outbuf,
+ const unsigned char *, unsigned int n)
+
+ -- Data type: gcry_cipher_stdecrypt_t
+ Type for the `stdecrypt' function, defined as: gcry_err_code_t
+ (*gcry_cipher_stdecrypt_t) (void *c, const unsigned char *outbuf,
+ const unsigned char *, unsigned int n)
+
+ -- Function: gcry_error_t gcry_cipher_register (gcry_cipher_spec_t
+ *CIPHER, unsigned int *algorithm_id, gcry_module_t *MODULE)
+ Register a new cipher module whose specification can be found in
+ CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representing this module is stored in MODULE.
+ Deprecated; the module register interface will be removed in a
+ future version.
+
+ -- Function: void gcry_cipher_unregister (gcry_module_t MODULE)
+ Unregister the cipher identified by MODULE, which must have been
+ registered with gcry_cipher_register.
+
+ -- Function: gcry_error_t gcry_cipher_list (int *LIST, int
+ *LIST_LENGTH)
+ Get a list consisting of the IDs of the loaded cipher modules. If
+ LIST is zero, write the number of loaded cipher modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.
+
+\1f
+File: gcrypt.info, Node: Available cipher modes, Next: Working with cipher handles, Prev: Cipher modules, Up: Symmetric cryptography
+
+5.3 Available cipher modes
+==========================
+
+`GCRY_CIPHER_MODE_NONE'
+ No mode specified. This should not be used. The only exception
+ is that if Libgcrypt is not used in FIPS mode and if any debug
+ flag has been set, this mode may be used to bypass the actual
+ encryption.
+
+`GCRY_CIPHER_MODE_ECB'
+ Electronic Codebook mode.
+
+`GCRY_CIPHER_MODE_CFB'
+ Cipher Feedback mode. The shift size equals the block size of the
+ cipher (e.g. for AES it is CFB-128).
+
+`GCRY_CIPHER_MODE_CBC'
+ Cipher Block Chaining mode.
+
+`GCRY_CIPHER_MODE_STREAM'
+ Stream mode, only to be used with stream cipher algorithms.
+
+`GCRY_CIPHER_MODE_OFB'
+ Output Feedback mode.
+
+`GCRY_CIPHER_MODE_CTR'
+ Counter mode.
+
+`GCRY_CIPHER_MODE_AESWRAP'
+ This mode is used to implement the AES-Wrap algorithm according to
+ RFC-3394. It may be used with any 128 bit block length algorithm,
+ however the specs require one of the 3 AES algorithms. These
+ special conditions apply: If `gcry_cipher_setiv' has not been used
+ the standard IV is used; if it has been used the lower 64 bit of
+ the IV are used as the Alternative Initial Value. On encryption
+ the provided output buffer must be 64 bit (8 byte) larger than the
+ input buffer; in-place encryption is still allowed. On decryption
+ the output buffer may be specified 64 bit (8 byte) shorter than
+ then input buffer. As per specs the input length must be at least
+ 128 bits and the length must be a multiple of 64 bits.
+
+
+\1f
+File: gcrypt.info, Node: Working with cipher handles, Next: General cipher functions, Prev: Available cipher modes, Up: Symmetric cryptography
+
+5.4 Working with cipher handles
+===============================
+
+To use a cipher algorithm, you must first allocate an according handle.
+This is to be done using the open function:
+
+ -- Function: gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *HD, int
+ ALGO, int MODE, unsigned int FLAGS)
+ This function creates the context handle required for most of the
+ other cipher functions and returns a handle to it in `hd'. In
+ case of an error, an according error code is returned.
+
+ The ID of algorithm to use must be specified via ALGO. See *Note
+ Available ciphers::, for a list of supported ciphers and the
+ according constants.
+
+ Besides using the constants directly, the function
+ `gcry_cipher_map_name' may be used to convert the textual name of
+ an algorithm into the according numeric ID.
+
+ The cipher mode to use must be specified via MODE. See *Note
+ Available cipher modes::, for a list of supported cipher modes and
+ the according constants. Note that some modes are incompatible
+ with some algorithms - in particular, stream mode
+ (`GCRY_CIPHER_MODE_STREAM') only works with stream ciphers. Any
+ block cipher mode (`GCRY_CIPHER_MODE_ECB', `GCRY_CIPHER_MODE_CBC',
+ `GCRY_CIPHER_MODE_CFB', `GCRY_CIPHER_MODE_OFB' or
+ `GCRY_CIPHER_MODE_CTR') will work with any block cipher algorithm.
+
+ The third argument FLAGS can either be passed as `0' or as the
+ bit-wise OR of the following constants.
+
+ `GCRY_CIPHER_SECURE'
+ Make sure that all operations are allocated in secure memory.
+ This is useful when the key material is highly confidential.
+
+ `GCRY_CIPHER_ENABLE_SYNC'
+ This flag enables the CFB sync mode, which is a special
+ feature of Libgcrypt's CFB mode implementation to allow for
+ OpenPGP's CFB variant. See `gcry_cipher_sync'.
+
+ `GCRY_CIPHER_CBC_CTS'
+ Enable cipher text stealing (CTS) for the CBC mode. Cannot
+ be used simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes
+ it possible to transform data of almost arbitrary size (only
+ limitation is that it must be greater than the algorithm's
+ block size).
+
+ `GCRY_CIPHER_CBC_MAC'
+ Compute CBC-MAC keyed checksums. This is the same as CBC
+ mode, but only output the last block. Cannot be used
+ simultaneous as GCRY_CIPHER_CBC_CTS.
+
+ Use the following function to release an existing handle:
+
+ -- Function: void gcry_cipher_close (gcry_cipher_hd_t H)
+ This function releases the context created by `gcry_cipher_open'.
+ It also zeroises all sensitive information associated with this
+ cipher handle.
+
+ In order to use a handle for performing cryptographic operations, a
+`key' has to be set first:
+
+ -- Function: gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t H,
+ const void *K, size_t L)
+ Set the key K used for encryption or decryption in the context
+ denoted by the handle H. The length L (in bytes) of the key K
+ must match the required length of the algorithm set for this
+ context or be in the allowed range for algorithms with variable
+ key size. The function checks this and returns an error if there
+ is a problem. A caller should always check for an error.
+
+
+ Most crypto modes requires an initialization vector (IV), which
+usually is a non-secret random string acting as a kind of salt value.
+The CTR mode requires a counter, which is also similar to a salt value.
+To set the IV or CTR, use these functions:
+
+ -- Function: gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t H, const
+ void *K, size_t L)
+ Set the initialization vector used for encryption or decryption.
+ The vector is passed as the buffer K of length L bytes and copied
+ to internal data structures. The function checks that the IV
+ matches the requirement of the selected algorithm and mode.
+
+ -- Function: gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t H,
+ const void *C, size_t L)
+ Set the counter vector used for encryption or decryption. The
+ counter is passed as the buffer C of length L bytes and copied to
+ internal data structures. The function checks that the counter
+ matches the requirement of the selected algorithm (i.e., it must be
+ the same size as the block size).
+
+ -- Function: gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t H)
+ Set the given handle's context back to the state it had after the
+ last call to gcry_cipher_setkey and clear the initialization
+ vector.
+
+ Note that gcry_cipher_reset is implemented as a macro.
+
+ The actual encryption and decryption is done by using one of the
+following functions. They may be used as often as required to process
+all the data.
+
+ -- Function: gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t H,
+ unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+ size_t INLEN)
+ `gcry_cipher_encrypt' is used to encrypt the data. This function
+ can either work in place or with two buffers. It uses the cipher
+ context already setup and described by the handle H. There are 2
+ ways to use the function: If IN is passed as `NULL' and INLEN is
+ `0', in-place encryption of the data in OUT or length OUTSIZE
+ takes place. With IN being not `NULL', INLEN bytes are encrypted
+ to the buffer OUT which must have at least a size of INLEN.
+ OUTSIZE must be set to the allocated size of OUT, so that the
+ function can check that there is sufficient space. Note that
+ overlapping buffers are not allowed.
+
+ Depending on the selected algorithms and encryption mode, the
+ length of the buffers must be a multiple of the block size.
+
+ The function returns `0' on success or an error code.
+
+ -- Function: gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t H,
+ unsigned char *out, size_t OUTSIZE, const unsigned char *IN,
+ size_t INLEN)
+ `gcry_cipher_decrypt' is used to decrypt the data. This function
+ can either work in place or with two buffers. It uses the cipher
+ context already setup and described by the handle H. There are 2
+ ways to use the function: If IN is passed as `NULL' and INLEN is
+ `0', in-place decryption of the data in OUT or length OUTSIZE
+ takes place. With IN being not `NULL', INLEN bytes are decrypted
+ to the buffer OUT which must have at least a size of INLEN.
+ OUTSIZE must be set to the allocated size of OUT, so that the
+ function can check that there is sufficient space. Note that
+ overlapping buffers are not allowed.
+
+ Depending on the selected algorithms and encryption mode, the
+ length of the buffers must be a multiple of the block size.
+
+ The function returns `0' on success or an error code.
+
+ OpenPGP (as defined in RFC-2440) requires a special sync operation in
+some places. The following function is used for this:
+
+ -- Function: gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t H)
+ Perform the OpenPGP sync operation on context H. Note that this
+ is a no-op unless the context was created with the flag
+ `GCRY_CIPHER_ENABLE_SYNC'
+
+ Some of the described functions are implemented as macros utilizing a
+catch-all control function. This control function is rarely used
+directly but there is nothing which would inhibit it:
+
+ -- Function: gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t H, int
+ CMD, void *BUFFER, size_t BUFLEN)
+ `gcry_cipher_ctl' controls various aspects of the cipher module and
+ specific cipher contexts. Usually some more specialized functions
+ or macros are used for this purpose. The semantics of the
+ function and its parameters depends on the the command CMD and the
+ passed context handle H. Please see the comments in the source
+ code (`src/global.c') for details.
+
+ -- Function: gcry_error_t gcry_cipher_info (gcry_cipher_hd_t H, int
+ WHAT, void *BUFFER, size_t *NBYTES)
+ `gcry_cipher_info' is used to retrieve various information about a
+ cipher context or the cipher module in general.
+
+ Currently no information is available.
+
+\1f
+File: gcrypt.info, Node: General cipher functions, Prev: Working with cipher handles, Up: Symmetric cryptography
+
+5.5 General cipher functions
+============================
+
+To work with the algorithms, several functions are available to map
+algorithm names to the internal identifiers, as well as ways to
+retrieve information about an algorithm or the current cipher context.
+
+ -- Function: gcry_error_t gcry_cipher_algo_info (int ALGO, int WHAT,
+ void *BUFFER, size_t *NBYTES)
+ This function is used to retrieve information on a specific
+ algorithm. You pass the cipher algorithm ID as ALGO and the type
+ of information requested as WHAT. The result is either returned as
+ the return code of the function or copied to the provided BUFFER
+ whose allocated length must be available in an integer variable
+ with the address passed in NBYTES. This variable will also
+ receive the actual used length of the buffer.
+
+ Here is a list of supported codes for WHAT:
+
+ `GCRYCTL_GET_KEYLEN:'
+ Return the length of the key. If the algorithm supports
+ multiple key lengths, the maximum supported value is
+ returned. The length is returned as number of octets (bytes)
+ and not as number of bits in NBYTES; BUFFER must be zero.
+
+ `GCRYCTL_GET_BLKLEN:'
+ Return the block length of the algorithm. The length is
+ returned as a number of octets in NBYTES; BUFFER must be zero.
+
+ `GCRYCTL_TEST_ALGO:'
+ Returns `0' when the specified algorithm is available for use.
+ BUFFER and NBYTES must be zero.
+
+
+
+ -- Function: const char * gcry_cipher_algo_name (int ALGO)
+ `gcry_cipher_algo_name' returns a string with the name of the
+ cipher algorithm ALGO. If the algorithm is not known or another
+ error occurred, the string `"?"' is returned. This function should
+ not be used to test for the availability of an algorithm.
+
+ -- Function: int gcry_cipher_map_name (const char *NAME)
+ `gcry_cipher_map_name' returns the algorithm identifier for the
+ cipher algorithm described by the string NAME. If this algorithm
+ is not available `0' is returned.
+
+ -- Function: int gcry_cipher_mode_from_oid (const char *STRING)
+ Return the cipher mode associated with an ASN.1 object identifier.
+ The object identifier is expected to be in the IETF-style dotted
+ decimal notation. The function returns `0' for an unknown object
+ identifier or when no mode is associated with it.
+
+\1f
+File: gcrypt.info, Node: Public Key cryptography, Next: Hashing, Prev: Symmetric cryptography, Up: Top
+
+6 Public Key cryptography
+*************************
+
+Public key cryptography, also known as asymmetric cryptography, is an
+easy way for key management and to provide digital signatures.
+Libgcrypt provides two completely different interfaces to public key
+cryptography, this chapter explains the one based on S-expressions.
+
+* Menu:
+
+* Available algorithms:: Algorithms supported by the library.
+* Used S-expressions:: Introduction into the used S-expression.
+* Public key modules:: How to work with public key modules.
+* Cryptographic Functions:: Functions for performing the cryptographic actions.
+* General public-key related Functions:: General functions, not implementing any cryptography.
+
+* AC Interface:: Alternative interface to public key functions.
+
+\1f
+File: gcrypt.info, Node: Available algorithms, Next: Used S-expressions, Up: Public Key cryptography
+
+6.1 Available algorithms
+========================
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well
+as DSA (Digital Signature Algorithm) and Elgamal. The versatile
+interface allows to add more algorithms in the future.
+
+\1f
+File: gcrypt.info, Node: Used S-expressions, Next: Public key modules, Prev: Available algorithms, Up: Public Key cryptography
+
+6.2 Used S-expressions
+======================
+
+Libgcrypt's API for asymmetric cryptography is based on data structures
+called S-expressions (see
+`http://people.csail.mit.edu/rivest/sexp.html') and does not work with
+contexts as most of the other building blocks of Libgcrypt do.
+
+The following information are stored in S-expressions:
+
+ keys
+
+ plain text data
+
+ encrypted data
+
+ signatures
+
+
+To describe how Libgcrypt expect keys, we use examples. Note that words
+in uppercase indicate parameters whereas lowercase words are literals.
+
+ Note that all MPI (multi-precision-integers) values are expected to
+be in `GCRYMPI_FMT_USG' format. An easy way to create S-expressions is
+by using `gcry_sexp_build' which allows to pass a string with
+printf-like escapes to insert MPI values.
+
+* Menu:
+
+* RSA key parameters:: Parameters used with an RSA key.
+* DSA key parameters:: Parameters used with a DSA key.
+* ECC key parameters:: Parameters used with ECC keys.
+
+\1f
+File: gcrypt.info, Node: RSA key parameters, Next: DSA key parameters, Up: Used S-expressions
+
+6.2.1 RSA key parameters
+------------------------
+
+An RSA private key is described by this S-expression:
+
+ (private-key
+ (rsa
+ (n N-MPI)
+ (e E-MPI)
+ (d D-MPI)
+ (p P-MPI)
+ (q Q-MPI)
+ (u U-MPI)))
+
+An RSA public key is described by this S-expression:
+
+ (public-key
+ (rsa
+ (n N-MPI)
+ (e E-MPI)))
+
+N-MPI
+ RSA public modulus n.
+
+E-MPI
+ RSA public exponent e.
+
+D-MPI
+ RSA secret exponent d = e^-1 \bmod (p-1)(q-1).
+
+P-MPI
+ RSA secret prime p.
+
+Q-MPI
+ RSA secret prime q with p < q.
+
+U-MPI
+ Multiplicative inverse u = p^-1 \bmod q.
+
+ For signing and decryption the parameters (p, q, u) are optional but
+greatly improve the performance. Either all of these optional
+parameters must be given or none of them. They are mandatory for
+gcry_pk_testkey.
+
+ Note that OpenSSL uses slighly different parameters: q < p and u =
+q^-1 \bmod p. To use these parameters you will need to swap the values
+and recompute u. Here is example code to do this:
+
+ if (gcry_mpi_cmp (p, q) > 0)
+ {
+ gcry_mpi_swap (p, q);
+ gcry_mpi_invm (u, p, q);
+ }
+
+\1f
+File: gcrypt.info, Node: DSA key parameters, Next: ECC key parameters, Prev: RSA key parameters, Up: Used S-expressions
+
+6.2.2 DSA key parameters
+------------------------
+
+A DSA private key is described by this S-expression:
+
+ (private-key
+ (dsa
+ (p P-MPI)
+ (q Q-MPI)
+ (g G-MPI)
+ (y Y-MPI)
+ (x X-MPI)))
+
+P-MPI
+ DSA prime p.
+
+Q-MPI
+ DSA group order q (which is a prime divisor of p-1).
+
+G-MPI
+ DSA group generator g.
+
+Y-MPI
+ DSA public key value y = g^x \bmod p.
+
+X-MPI
+ DSA secret exponent x.
+
+ The public key is similar with "private-key" replaced by "public-key"
+and no X-MPI.
+
+\1f
+File: gcrypt.info, Node: ECC key parameters, Prev: DSA key parameters, Up: Used S-expressions
+
+6.2.3 ECC key parameters
+------------------------
+
+An ECC private key is described by this S-expression:
+
+ (private-key
+ (ecc
+ (p P-MPI)
+ (a A-MPI)
+ (b B-MPI)
+ (g G-POINT)
+ (n N-MPI)
+ (q Q-POINT)
+ (d D-MPI)))
+
+P-MPI
+ Prime specifying the field GF(p).
+
+A-MPI
+B-MPI
+ The two coefficients of the Weierstrass equation y^2 = x^3 + ax + b
+
+G-POINT
+ Base point g.
+
+N-MPI
+ Order of g
+
+Q-POINT
+ The point representing the public key Q = dP.
+
+D-MPI
+ The private key d
+
+ All point values are encoded in standard format; Libgcrypt does
+currently only support uncompressed points, thus the first byte needs to
+be `0x04'.
+
+ The public key is similar with "private-key" replaced by "public-key"
+and no D-MPI.
+
+ If the domain parameters are well-known, the name of this curve may
+be used. For example
+
+ (private-key
+ (ecc
+ (curve "NIST P-192")
+ (q Q-POINT)
+ (d D-MPI)))
+
+ The `curve' parameter may be given in any case and is used to replace
+missing parameters.
+
+Currently implemented curves are:
+`NIST P-192'
+`1.2.840.10045.3.1.1'
+`prime192v1'
+`secp192r1'
+ The NIST 192 bit curve, its OID, X9.62 and SECP aliases.
+
+`NIST P-224'
+`secp224r1'
+ The NIST 224 bit curve and its SECP alias.
+
+`NIST P-256'
+`1.2.840.10045.3.1.7'
+`prime256v1'
+`secp256r1'
+ The NIST 256 bit curve, its OID, X9.62 and SECP aliases.
+
+`NIST P-384'
+`secp384r1'
+ The NIST 384 bit curve and its SECP alias.
+
+`NIST P-521'
+`secp521r1'
+ The NIST 521 bit curve and its SECP alias.
+
+ As usual the OIDs may optionally be prefixed with the string `OID.'
+or `oid.'.
+
+\1f
+File: gcrypt.info, Node: Public key modules, Next: Cryptographic Functions, Prev: Used S-expressions, Up: Public Key cryptography
+
+6.3 Public key modules
+======================
+
+Libgcrypt makes it possible to load additional `public key modules';
+these public key algorithms can be used just like the algorithms that
+are built into the library directly. For an introduction into
+extension modules, see *Note Modules::.
+
+ -- Data type: gcry_pk_spec_t
+ This is the `module specification structure' needed for registering
+ public key modules, which has to be filled in by the user before it
+ can be used to register a module. It contains the following
+ members:
+
+ `const char *name'
+ The primary name of this algorithm.
+
+ `char **aliases'
+ A list of strings that are `aliases' for the algorithm. The
+ list must be terminated with a NULL element.
+
+ `const char *elements_pkey'
+ String containing the one-letter names of the MPI values
+ contained in a public key.
+
+ `const char *element_skey'
+ String containing the one-letter names of the MPI values
+ contained in a secret key.
+
+ `const char *elements_enc'
+ String containing the one-letter names of the MPI values that
+ are the result of an encryption operation using this
+ algorithm.
+
+ `const char *elements_sig'
+ String containing the one-letter names of the MPI values that
+ are the result of a sign operation using this algorithm.
+
+ `const char *elements_grip'
+ String containing the one-letter names of the MPI values that
+ are to be included in the `key grip'.
+
+ `int use'
+ The bitwise-OR of the following flags, depending on the
+ abilities of the algorithm:
+ `GCRY_PK_USAGE_SIGN'
+ The algorithm supports signing and verifying of data.
+
+ `GCRY_PK_USAGE_ENCR'
+ The algorithm supports the encryption and decryption of
+ data.
+
+ `gcry_pk_generate_t generate'
+ The function responsible for generating a new key pair. See
+ below for a description of this type.
+
+ `gcry_pk_check_secret_key_t check_secret_key'
+ The function responsible for checking the sanity of a
+ provided secret key. See below for a description of this
+ type.
+
+ `gcry_pk_encrypt_t encrypt'
+ The function responsible for encrypting data. See below for a
+ description of this type.
+
+ `gcry_pk_decrypt_t decrypt'
+ The function responsible for decrypting data. See below for a
+ description of this type.
+
+ `gcry_pk_sign_t sign'
+ The function responsible for signing data. See below for a
+ description of this type.
+
+ `gcry_pk_verify_t verify'
+ The function responsible for verifying that the provided
+ signature matches the provided data. See below for a
+ description of this type.
+
+ `gcry_pk_get_nbits_t get_nbits'
+ The function responsible for returning the number of bits of
+ a provided key. See below for a description of this type.
+
+ -- Data type: gcry_pk_generate_t
+ Type for the `generate' function, defined as: gcry_err_code_t
+ (*gcry_pk_generate_t) (int algo, unsigned int nbits, unsigned long
+ use_e, gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+
+ -- Data type: gcry_pk_check_secret_key_t
+ Type for the `check_secret_key' function, defined as:
+ gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+ gcry_mpi_t *skey)
+
+ -- Data type: gcry_pk_encrypt_t
+ Type for the `encrypt' function, defined as: gcry_err_code_t
+ (*gcry_pk_encrypt_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t
+ data, gcry_mpi_t *pkey, int flags)
+
+ -- Data type: gcry_pk_decrypt_t
+ Type for the `decrypt' function, defined as: gcry_err_code_t
+ (*gcry_pk_decrypt_t) (int algo, gcry_mpi_t *result, gcry_mpi_t
+ *data, gcry_mpi_t *skey, int flags)
+
+ -- Data type: gcry_pk_sign_t
+ Type for the `sign' function, defined as: gcry_err_code_t
+ (*gcry_pk_sign_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+ gcry_mpi_t *skey)
+
+ -- Data type: gcry_pk_verify_t
+ Type for the `verify' function, defined as: gcry_err_code_t
+ (*gcry_pk_verify_t) (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
+ gcry_mpi_t *pkey, int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+
+ -- Data type: gcry_pk_get_nbits_t
+ Type for the `get_nbits' function, defined as: unsigned
+ (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey)
+
+ -- Function: gcry_error_t gcry_pk_register (gcry_pk_spec_t *PUBKEY,
+ unsigned int *algorithm_id, gcry_module_t *MODULE)
+ Register a new public key module whose specification can be found
+ in PUBKEY. On success, a new algorithm ID is stored in
+ ALGORITHM_ID and a pointer representing this module is stored in
+ MODULE. Deprecated; the module register interface will be removed
+ in a future version.
+
+
+ -- Function: void gcry_pk_unregister (gcry_module_t MODULE)
+ Unregister the public key module identified by MODULE, which must
+ have been registered with gcry_pk_register.
+
+ -- Function: gcry_error_t gcry_pk_list (int *LIST, int *LIST_LENGTH)
+ Get a list consisting of the IDs of the loaded pubkey modules. If
+ LIST is zero, write the number of loaded pubkey modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less pubkey modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.
+
+\1f
+File: gcrypt.info, Node: Cryptographic Functions, Next: General public-key related Functions, Prev: Public key modules, Up: Public Key cryptography
+
+6.4 Cryptographic Functions
+===========================
+
+Note that we will in future allow to use keys without p,q and u
+specified and may also support other parameters for performance reasons.
+
+Some functions operating on S-expressions support `flags', that
+influence the operation. These flags have to be listed in a
+sub-S-expression named `flags'; the following flags are known:
+
+`pkcs1'
+ Use PKCS#1 block type 2 padding for encryption, block type 1
+ padding for signing.
+
+`oaep'
+ Use RSA-OAEP padding for encryption.
+
+`pss'
+ Use RSA-PSS padding for signing.
+
+`no-blinding'
+ Do not use a technique called `blinding', which is used by default
+ in order to prevent leaking of secret information. Blinding is
+ only implemented by RSA, but it might be implemented by other
+ algorithms in the future as well, when necessary.
+
+Now that we know the key basics, we can carry on and explain how to
+encrypt and decrypt data. In almost all cases the data is a random
+session key which is in turn used for the actual encryption of the real
+data. There are 2 functions to do this:
+
+ -- Function: gcry_error_t gcry_pk_encrypt (gcry_sexp_t *R_CIPH,
+ gcry_sexp_t DATA, gcry_sexp_t PKEY)
+ Obviously a public key must be provided for encryption. It is
+ expected as an appropriate S-expression (see above) in PKEY. The
+ data to be encrypted can either be in the simple old format, which
+ is a very simple S-expression consisting only of one MPI, or it
+ may be a more complex S-expression which also allows to specify
+ flags for operation, like e.g. padding rules.
+
+ If you don't want to let Libgcrypt handle the padding, you must
+ pass an appropriate MPI using this expression for DATA:
+
+ (data
+ (flags raw)
+ (value MPI))
+
+ This has the same semantics as the old style MPI only way. MPI is
+ the actual data, already padded appropriate for your protocol.
+ Most RSA based systems however use PKCS#1 padding and so you can
+ use this S-expression for DATA:
+
+ (data
+ (flags pkcs1)
+ (value BLOCK))
+
+ Here, the "flags" list has the "pkcs1" flag which let the function
+ know that it should provide PKCS#1 block type 2 padding. The
+ actual data to be encrypted is passed as a string of octets in
+ BLOCK. The function checks that this data actually can be used
+ with the given key, does the padding and encrypts it.
+
+ If the function could successfully perform the encryption, the
+ return value will be 0 and a new S-expression with the encrypted
+ result is allocated and assigned to the variable at the address of
+ R_CIPH. The caller is responsible to release this value using
+ `gcry_sexp_release'. In case of an error, an error code is
+ returned and R_CIPH will be set to `NULL'.
+
+ The returned S-expression has this format when used with RSA:
+
+ (enc-val
+ (rsa
+ (a A-MPI)))
+
+ Where A-MPI is an MPI with the result of the RSA operation. When
+ using the Elgamal algorithm, the return value will have this
+ format:
+
+ (enc-val
+ (elg
+ (a A-MPI)
+ (b B-MPI)))
+
+ Where A-MPI and B-MPI are MPIs with the result of the Elgamal
+ encryption operation.
+
+ -- Function: gcry_error_t gcry_pk_decrypt (gcry_sexp_t *R_PLAIN,
+ gcry_sexp_t DATA, gcry_sexp_t SKEY)
+ Obviously a private key must be provided for decryption. It is
+ expected as an appropriate S-expression (see above) in SKEY. The
+ data to be decrypted must match the format of the result as
+ returned by `gcry_pk_encrypt', but should be enlarged with a
+ `flags' element:
+
+ (enc-val
+ (flags)
+ (elg
+ (a A-MPI)
+ (b B-MPI)))
+
+ This function does not remove padding from the data by default. To
+ let Libgcrypt remove padding, give a hint in `flags' telling which
+ padding method was used when encrypting:
+
+ (flags PADDING-METHOD)
+
+ Currently PADDING-METHOD is either `pkcs1' for PKCS#1 block type 2
+ padding, or `oaep' for RSA-OAEP padding.
+
+ The function returns 0 on success or an error code. The variable
+ at the address of R_PLAIN will be set to NULL on error or receive
+ the decrypted value on success. The format of R_PLAIN is a simple
+ S-expression part (i.e. not a valid one) with just one MPI if
+ there was no `flags' element in DATA; if at least an empty `flags'
+ is passed in DATA, the format is:
+
+ (value PLAINTEXT)
+
+ Another operation commonly performed using public key cryptography is
+signing data. In some sense this is even more important than
+encryption because digital signatures are an important instrument for
+key management. Libgcrypt supports digital signatures using 2
+functions, similar to the encryption functions:
+
+ -- Function: gcry_error_t gcry_pk_sign (gcry_sexp_t *R_SIG,
+ gcry_sexp_t DATA, gcry_sexp_t SKEY)
+ This function creates a digital signature for DATA using the
+ private key SKEY and place it into the variable at the address of
+ R_SIG. DATA may either be the simple old style S-expression with
+ just one MPI or a modern and more versatile S-expression which
+ allows to let Libgcrypt handle padding:
+
+ (data
+ (flags pkcs1)
+ (hash HASH-ALGO BLOCK))
+
+ This example requests to sign the data in BLOCK after applying
+ PKCS#1 block type 1 style padding. HASH-ALGO is a string with the
+ hash algorithm to be encoded into the signature, this may be any
+ hash algorithm name as supported by Libgcrypt. Most likely, this
+ will be "sha256" or "sha1". It is obvious that the length of
+ BLOCK must match the size of that message digests; the function
+ checks that this and other constraints are valid.
+
+ If PKCS#1 padding is not required (because the caller does already
+ provide a padded value), either the old format or better the
+ following format should be used:
+
+ (data
+ (flags raw)
+ (value MPI))
+
+ Here, the data to be signed is directly given as an MPI.
+
+ The signature is returned as a newly allocated S-expression in
+ R_SIG using this format for RSA:
+
+ (sig-val
+ (rsa
+ (s S-MPI)))
+
+ Where S-MPI is the result of the RSA sign operation. For DSA the
+ S-expression returned is:
+
+ (sig-val
+ (dsa
+ (r R-MPI)
+ (s S-MPI)))
+
+ Where R-MPI and S-MPI are the result of the DSA sign operation.
+ For Elgamal signing (which is slow, yields large numbers and
+ probably is not as secure as the other algorithms), the same
+ format is used with "elg" replacing "dsa".
+
+The operation most commonly used is definitely the verification of a
+signature. Libgcrypt provides this function:
+
+ -- Function: gcry_error_t gcry_pk_verify (gcry_sexp_t SIG,
+ gcry_sexp_t DATA, gcry_sexp_t PKEY)
+ This is used to check whether the signature SIG matches the DATA.
+ The public key PKEY must be provided to perform this verification.
+ This function is similar in its parameters to `gcry_pk_sign' with
+ the exceptions that the public key is used instead of the private
+ key and that no signature is created but a signature, in a format
+ as created by `gcry_pk_sign', is passed to the function in SIG.
+
+ The result is 0 for success (i.e. the data matches the signature),
+ or an error code where the most relevant code is
+ `GCRYERR_BAD_SIGNATURE' to indicate that the signature does not
+ match the provided data.
+
+
+\1f
+File: gcrypt.info, Node: General public-key related Functions, Next: AC Interface, Prev: Cryptographic Functions, Up: Public Key cryptography
+
+6.5 General public-key related Functions
+========================================
+
+A couple of utility functions are available to retrieve the length of
+the key, map algorithm identifiers and perform sanity checks:
+
+ -- Function: const char * gcry_pk_algo_name (int ALGO)
+ Map the public key algorithm id ALGO to a string representation of
+ the algorithm name. For unknown algorithms this functions returns
+ the string `"?"'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: int gcry_pk_map_name (const char *NAME)
+ Map the algorithm NAME to a public key algorithm Id. Returns 0 if
+ the algorithm name is not known.
+
+ -- Function: int gcry_pk_test_algo (int ALGO)
+ Return 0 if the public key algorithm ALGO is available for use.
+ Note that this is implemented as a macro.
+
+ -- Function: unsigned int gcry_pk_get_nbits (gcry_sexp_t KEY)
+ Return what is commonly referred as the key length for the given
+ public or private in KEY.
+
+ -- Function: unsigned char * gcry_pk_get_keygrip (gcry_sexp_t KEY,
+ unsigned char *ARRAY)
+ Return the so called "keygrip" which is the SHA-1 hash of the
+ public key parameters expressed in a way depended on the
+ algorithm. ARRAY must either provide space for 20 bytes or be
+ `NULL'. In the latter case a newly allocated array of that size is
+ returned. On success a pointer to the newly allocated space or to
+ ARRAY is returned. `NULL' is returned to indicate an error which
+ is most likely an unknown algorithm or one where a "keygrip" has
+ not yet been defined. The function accepts public or secret keys
+ in KEY.
+
+ -- Function: gcry_error_t gcry_pk_testkey (gcry_sexp_t KEY)
+ Return zero if the private key KEY is `sane', an error code
+ otherwise. Note that it is not possible to check the `saneness'
+ of a public key.
+
+
+ -- Function: gcry_error_t gcry_pk_algo_info (int ALGO, int WHAT,
+ void *BUFFER, size_t *NBYTES)
+ Depending on the value of WHAT return various information about
+ the public key algorithm with the id ALGO. Note that the function
+ returns `-1' on error and the actual error code must be retrieved
+ using the function `gcry_errno'. The currently defined values for
+ WHAT are:
+
+ `GCRYCTL_TEST_ALGO:'
+ Return 0 if the specified algorithm is available for use.
+ BUFFER must be `NULL', NBYTES may be passed as `NULL' or
+ point to a variable with the required usage of the algorithm.
+ This may be 0 for "don't care" or the bit-wise OR of these
+ flags:
+
+ `GCRY_PK_USAGE_SIGN'
+ Algorithm is usable for signing.
+
+ `GCRY_PK_USAGE_ENCR'
+ Algorithm is usable for encryption.
+
+ Unless you need to test for the allowed usage, it is in
+ general better to use the macro gcry_pk_test_algo instead.
+
+ `GCRYCTL_GET_ALGO_USAGE:'
+ Return the usage flags for the given algorithm. An invalid
+ algorithm return 0. Disabled algorithms are ignored here
+ because we want to know whether the algorithm is at all
+ capable of a certain usage.
+
+ `GCRYCTL_GET_ALGO_NPKEY'
+ Return the number of elements the public key for algorithm
+ ALGO consist of. Return 0 for an unknown algorithm.
+
+ `GCRYCTL_GET_ALGO_NSKEY'
+ Return the number of elements the private key for algorithm
+ ALGO consist of. Note that this value is always larger than
+ that of the public key. Return 0 for an unknown algorithm.
+
+ `GCRYCTL_GET_ALGO_NSIGN'
+ Return the number of elements a signature created with the
+ algorithm ALGO consists of. Return 0 for an unknown
+ algorithm or for an algorithm not capable of creating
+ signatures.
+
+ `GCRYCTL_GET_ALGO_NENC'
+ Return the number of elements a encrypted message created
+ with the algorithm ALGO consists of. Return 0 for an unknown
+ algorithm or for an algorithm not capable of encryption.
+
+ Please note that parameters not required should be passed as
+ `NULL'.
+
+ -- Function: gcry_error_t gcry_pk_ctl (int CMD, void *BUFFER,
+ size_t BUFLEN)
+ This is a general purpose function to perform certain control
+ operations. CMD controls what is to be done. The return value is
+ 0 for success or an error code. Currently supported values for
+ CMD are:
+
+ `GCRYCTL_DISABLE_ALGO'
+ Disable the algorithm given as an algorithm id in BUFFER.
+ BUFFER must point to an `int' variable with the algorithm id
+ and BUFLEN must have the value `sizeof (int)'.
+
+
+Libgcrypt also provides a function to generate public key pairs:
+
+ -- Function: gcry_error_t gcry_pk_genkey (gcry_sexp_t *R_KEY,
+ gcry_sexp_t PARMS)
+ This function create a new public key pair using information given
+ in the S-expression PARMS and stores the private and the public key
+ in one new S-expression at the address given by R_KEY. In case of
+ an error, R_KEY is set to `NULL'. The return code is 0 for
+ success or an error code otherwise.
+
+ Here is an example for PARMS to create an 2048 bit RSA key:
+
+ (genkey
+ (rsa
+ (nbits 4:2048)))
+
+ To create an Elgamal key, substitute "elg" for "rsa" and to create
+ a DSA key use "dsa". Valid ranges for the key length depend on the
+ algorithms; all commonly used key lengths are supported. Currently
+ supported parameters are:
+
+ `nbits'
+ This is always required to specify the length of the key.
+ The argument is a string with a number in C-notation. The
+ value should be a multiple of 8.
+
+ `curve NAME'
+ For ECC a named curve may be used instead of giving the
+ number of requested bits. This allows to request a specific
+ curve to override a default selection Libgcrypt would have
+ taken if `nbits' has been given. The available names are
+ listed with the description of the ECC public key parameters.
+
+ `rsa-use-e'
+ This is only used with RSA to give a hint for the public
+ exponent. The value will be used as a base to test for a
+ usable exponent. Some values are special:
+
+ `0'
+ Use a secure and fast value. This is currently the
+ number 41.
+
+ `1'
+ Use a value as required by some crypto policies. This
+ is currently the number 65537.
+
+ `2'
+ Reserved
+
+ `> 2'
+ Use the given value.
+
+ If this parameter is not used, Libgcrypt uses for historic
+ reasons 65537.
+
+ `qbits'
+ This is only meanigful for DSA keys. If it is given the DSA
+ key is generated with a Q parameyer of this size. If it is
+ not given or zero Q is deduced from NBITS in this way:
+ `512 <= N <= 1024'
+ Q = 160
+
+ `N = 2048'
+ Q = 224
+
+ `N = 3072'
+ Q = 256
+
+ `N = 7680'
+ Q = 384
+
+ `N = 15360'
+ Q = 512
+ Note that in this case only the values for N, as given in the
+ table, are allowed. When specifying Q all values of N in the
+ range 512 to 15680 are valid as long as they are multiples of
+ 8.
+
+ `transient-key'
+ This is only meaningful for RSA, DSA, ECDSA, and ECDH keys.
+ This is a flag with no value. If given the key is created
+ using a faster and a somewhat less secure random number
+ generator. This flag may be used for keys which are only
+ used for a short time or per-message and do not require full
+ cryptographic strength.
+
+ `domain'
+ This is only meaningful for DLP algorithms. If specified
+ keys are generated with domain parameters taken from this
+ list. The exact format of this parameter depends on the
+ actual algorithm. It is currently only implemented for DSA
+ using this format:
+
+ (genkey
+ (dsa
+ (domain
+ (p P-MPI)
+ (q Q-MPI)
+ (g Q-MPI))))
+
+ `nbits' and `qbits' may not be specified because they are
+ derived from the domain parameters.
+
+ `derive-parms'
+ This is currently only implemented for RSA and DSA keys. It
+ is not allowed to use this together with a `domain'
+ specification. If given, it is used to derive the keys using
+ the given parameters.
+
+ If given for an RSA key the X9.31 key generation algorithm is
+ used even if libgcrypt is not in FIPS mode. If given for a
+ DSA key, the FIPS 186 algorithm is used even if libgcrypt is
+ not in FIPS mode.
+
+ (genkey
+ (rsa
+ (nbits 4:1024)
+ (rsa-use-e 1:3)
+ (derive-parms
+ (Xp1 #1A1916DDB29B4EB7EB6732E128#)
+ (Xp2 #192E8AAC41C576C822D93EA433#)
+ (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D
+ 769D6D76646C7A792E16EBD89FE6FC5B605A6493
+ 39DFC925A86A4C6D150B71B9EEA02D68885F5009
+ B98BD984#)
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+
+ (genkey
+ (dsa
+ (nbits 4:1024)
+ (derive-parms
+ (seed SEED-MPI))))
+
+ `use-x931'
+ Force the use of the ANSI X9.31 key generation algorithm
+ instead of the default algorithm. This flag is only
+ meaningful for RSA and usually not required. Note that this
+ algorithm is implicitly used if either `derive-parms' is
+ given or Libgcrypt is in FIPS mode.
+
+ `use-fips186'
+ Force the use of the FIPS 186 key generation algorithm
+ instead of the default algorithm. This flag is only
+ meaningful for DSA and usually not required. Note that this
+ algorithm is implicitly used if either `derive-parms' is
+ given or Libgcrypt is in FIPS mode. As of now FIPS 186-2 is
+ implemented; after the approval of FIPS 186-3 the code will
+ be changed to implement 186-3.
+
+ `use-fips186-2'
+ Force the use of the FIPS 186-2 key generation algorithm
+ instead of the default algorithm. This algorithm is slighlty
+ different from FIPS 186-3 and allows only 1024 bit keys.
+ This flag is only meaningful for DSA and only required for
+ FIPS testing backward compatibility.
+
+
+ The key pair is returned in a format depending on the algorithm.
+ Both private and public keys are returned in one container and may
+ be accompanied by some miscellaneous information.
+
+ As an example, here is what the Elgamal key generation returns:
+
+ (key-data
+ (public-key
+ (elg
+ (p P-MPI)
+ (g G-MPI)
+ (y Y-MPI)))
+ (private-key
+ (elg
+ (p P-MPI)
+ (g G-MPI)
+ (y Y-MPI)
+ (x X-MPI)))
+ (misc-key-info
+ (pm1-factors N1 N2 ... NN))
+
+ As you can see, some of the information is duplicated, but this
+ provides an easy way to extract either the public or the private
+ key. Note that the order of the elements is not defined, e.g. the
+ private key may be stored before the public key. N1 N2 ... NN is a
+ list of prime numbers used to composite P-MPI; this is in general
+ not a very useful information and only available if the key
+ generation algorithm provides them.
+
+\1f
+File: gcrypt.info, Node: AC Interface, Prev: General public-key related Functions, Up: Public Key cryptography
+
+6.6 Alternative Public Key Interface
+====================================
+
+This section documents the alternative interface to asymmetric
+cryptography (ac) that is not based on S-expressions, but on native C
+data structures. As opposed to the pk interface described in the
+former chapter, this one follows an open/use/close paradigm like other
+building blocks of the library.
+
+ *This interface has a few known problems; most noteworthy an
+inherent tendency to leak memory. It might not be available in
+forthcoming versions of Libgcrypt.*
+
+* Menu:
+
+* Available asymmetric algorithms:: List of algorithms supported by the library.
+* Working with sets of data:: How to work with sets of data.
+* Working with IO objects:: How to work with IO objects.
+* Working with handles:: How to use handles.
+* Working with keys:: How to work with keys.
+* Using cryptographic functions:: How to perform cryptographic operations.
+* Handle-independent functions:: General functions independent of handles.
+
+\1f
+File: gcrypt.info, Node: Available asymmetric algorithms, Next: Working with sets of data, Up: AC Interface
+
+6.6.1 Available asymmetric algorithms
+-------------------------------------
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well
+as DSA (Digital Signature Algorithm) and Elgamal. The versatile
+interface allows to add more algorithms in the future.
+
+ -- Data type: gcry_ac_id_t
+ The following constants are defined for this type:
+
+ `GCRY_AC_RSA'
+ Rivest-Shamir-Adleman
+
+ `GCRY_AC_DSA'
+ Digital Signature Algorithm
+
+ `GCRY_AC_ELG'
+ Elgamal
+
+ `GCRY_AC_ELG_E'
+ Elgamal, encryption only.
+
+\1f
+File: gcrypt.info, Node: Working with sets of data, Next: Working with IO objects, Prev: Available asymmetric algorithms, Up: AC Interface
+
+6.6.2 Working with sets of data
+-------------------------------
+
+In the context of this interface the term `data set' refers to a list
+of `named MPI values' that is used by functions performing
+cryptographic operations; a named MPI value is a an MPI value,
+associated with a label.
+
+ Such data sets are used for representing keys, since keys simply
+consist of a variable amount of numbers. Furthermore some functions
+return data sets to the caller that are to be provided to other
+functions.
+
+ This section documents the data types, symbols and functions that are
+relevant for working with data sets.
+
+ -- Data type: gcry_ac_data_t
+ A single data set.
+
+ The following flags are supported:
+
+`GCRY_AC_FLAG_DEALLOC'
+ Used for storing data in a data set. If given, the data will be
+ released by the library. Note that whenever one of the ac
+ functions is about to release objects because of this flag, the
+ objects are expected to be stored in memory allocated through the
+ Libgcrypt memory management. In other words: gcry_free() is used
+ instead of free().
+
+`GCRY_AC_FLAG_COPY'
+ Used for storing/retrieving data in/from a data set. If given, the
+ library will create copies of the provided/contained data, which
+ will then be given to the user/associated with the data set.
+
+ -- Function: gcry_error_t gcry_ac_data_new (gcry_ac_data_t *DATA)
+ Creates a new, empty data set and stores it in DATA.
+
+ -- Function: void gcry_ac_data_destroy (gcry_ac_data_t DATA)
+ Destroys the data set DATA.
+
+ -- Function: gcry_error_t gcry_ac_data_set (gcry_ac_data_t DATA,
+ unsigned int FLAGS, char *NAME, gcry_mpi_t MPI)
+ Add the value MPI to DATA with the label NAME. If FLAGS contains
+ GCRY_AC_FLAG_COPY, the data set will contain copies of NAME and
+ MPI. If FLAGS contains GCRY_AC_FLAG_DEALLOC or GCRY_AC_FLAG_COPY,
+ the values contained in the data set will be deallocated when they
+ are to be removed from the data set.
+
+ -- Function: gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *DATA_CP,
+ gcry_ac_data_t DATA)
+ Create a copy of the data set DATA and store it in DATA_CP.
+ FIXME: exact semantics undefined.
+
+ -- Function: unsigned int gcry_ac_data_length (gcry_ac_data_t DATA)
+ Returns the number of named MPI values inside of the data set DATA.
+
+ -- Function: gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t DATA,
+ unsigned int FLAGS, char *NAME, gcry_mpi_t *MPI)
+ Store the value labelled with NAME found in DATA in MPI. If FLAGS
+ contains GCRY_AC_FLAG_COPY, store a copy of the MPI value
+ contained in the data set. MPI may be NULL (this might be useful
+ for checking the existence of an MPI with extracting it).
+
+ -- Function: gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t DATA,
+ unsigned int flags, unsigned int INDEX, const char **NAME,
+ gcry_mpi_t *MPI)
+ Stores in NAME and MPI the named MPI value contained in the data
+ set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY,
+ store copies of the values contained in the data set. NAME or MPI
+ may be NULL.
+
+ -- Function: void gcry_ac_data_clear (gcry_ac_data_t DATA)
+ Destroys any values contained in the data set DATA.
+
+ -- Function: gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t DATA,
+ gcry_sexp_t *SEXP, const char **IDENTIFIERS)
+ This function converts the data set DATA into a newly created
+ S-Expression, which is to be stored in SEXP; IDENTIFIERS is a NULL
+ terminated list of C strings, which specifies the structure of the
+ S-Expression.
+
+ Example:
+
+ If IDENTIFIERS is a list of pointers to the strings "foo" and
+ "bar" and if DATA is a data set containing the values "val1 =
+ 0x01" and "val2 = 0x02", then the resulting S-Expression will look
+ like this: (foo (bar ((val1 0x01) (val2 0x02))).
+
+ -- Function: gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *DATA,
+ gcry_sexp_t SEXP, const char **IDENTIFIERS)
+ This function converts the S-Expression SEXP into a newly created
+ data set, which is to be stored in DATA; IDENTIFIERS is a NULL
+ terminated list of C strings, which specifies the structure of the
+ S-Expression. If the list of identifiers does not match the
+ structure of the S-Expression, the function fails.
+
+\1f
+File: gcrypt.info, Node: Working with IO objects, Next: Working with handles, Prev: Working with sets of data, Up: AC Interface
+
+6.6.3 Working with IO objects
+-----------------------------
+
+Note: IO objects are currently only used in the context of message
+encoding/decoding and encryption/signature schemes.
+
+ -- Data type: gcry_ac_io_t
+ `gcry_ac_io_t' is the type to be used for IO objects.
+
+ IO objects provide an uniform IO layer on top of different underlying
+IO mechanisms; either they can be used for providing data to the
+library (mode is GCRY_AC_IO_READABLE) or they can be used for
+retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).
+
+ IO object need to be initialized by calling on of the following
+functions:
+
+ -- Function: void gcry_ac_io_init (gcry_ac_io_t *AC_IO,
+ gcry_ac_io_mode_t MODE, gcry_ac_io_type_t TYPE, ...);
+ Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments. The list of variable arguments to specify depends on
+ the given TYPE.
+
+ -- Function: void gcry_ac_io_init_va (gcry_ac_io_t *AC_IO,
+ gcry_ac_io_mode_t MODE, gcry_ac_io_type_t TYPE, va_list AP);
+ Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments AP. The list of variable arguments to specify depends
+ on the given TYPE.
+
+ The following types of IO objects exist:
+
+`GCRY_AC_IO_STRING'
+ In case of GCRY_AC_IO_READABLE the IO object will provide data
+ from a memory string. Arguments to specify at initialization time:
+ `unsigned char *'
+ Pointer to the beginning of the memory string
+
+ `size_t'
+ Size of the memory string
+ In case of GCRY_AC_IO_WRITABLE the object will store retrieved
+ data in a newly allocated memory string. Arguments to specify at
+ initialization time:
+ `unsigned char **'
+ Pointer to address, at which the pointer to the newly created
+ memory string is to be stored
+
+ `size_t *'
+ Pointer to address, at which the size of the newly created
+ memory string is to be stored
+
+`GCRY_AC_IO_CALLBACK'
+ In case of GCRY_AC_IO_READABLE the object will forward read
+ requests to a provided callback function. Arguments to specify at
+ initialization time:
+ `gcry_ac_data_read_cb_t'
+ Callback function to use
+
+ `void *'
+ Opaque argument to provide to the callback function
+ In case of GCRY_AC_IO_WRITABLE the object will forward write
+ requests to a provided callback function. Arguments to specify at
+ initialization time:
+ `gcry_ac_data_write_cb_t'
+ Callback function to use
+
+ `void *'
+ Opaque argument to provide to the callback function
+
+\1f
+File: gcrypt.info, Node: Working with handles, Next: Working with keys, Prev: Working with IO objects, Up: AC Interface
+
+6.6.4 Working with handles
+--------------------------
+
+In order to use an algorithm, an according handle must be created.
+This is done using the following function:
+
+ -- Function: gcry_error_t gcry_ac_open (gcry_ac_handle_t *HANDLE, int
+ ALGORITHM, int FLAGS)
+ Creates a new handle for the algorithm ALGORITHM and stores it in
+ HANDLE. FLAGS is not used currently.
+
+ ALGORITHM must be a valid algorithm ID, see *Note Available
+ asymmetric algorithms::, for a list of supported algorithms and the
+ according constants. Besides using the listed constants directly,
+ the functions `gcry_pk_name_to_id' may be used to convert the
+ textual name of an algorithm into the according numeric ID.
+
+ -- Function: void gcry_ac_close (gcry_ac_handle_t HANDLE)
+ Destroys the handle HANDLE.
+
+\1f
+File: gcrypt.info, Node: Working with keys, Next: Using cryptographic functions, Prev: Working with handles, Up: AC Interface
+
+6.6.5 Working with keys
+-----------------------
+
+ -- Data type: gcry_ac_key_type_t
+ Defined constants:
+
+ `GCRY_AC_KEY_SECRET'
+ Specifies a secret key.
+
+ `GCRY_AC_KEY_PUBLIC'
+ Specifies a public key.
+
+ -- Data type: gcry_ac_key_t
+ This type represents a single `key', either a secret one or a
+ public one.
+
+ -- Data type: gcry_ac_key_pair_t
+ This type represents a `key pair' containing a secret and a public
+ key.
+
+ Key data structures can be created in two different ways; a new key
+pair can be generated, resulting in ready-to-use key. Alternatively a
+key can be initialized from a given data set.
+
+ -- Function: gcry_error_t gcry_ac_key_init (gcry_ac_key_t *KEY,
+ gcry_ac_handle_t HANDLE, gcry_ac_key_type_t TYPE,
+ gcry_ac_data_t DATA)
+ Creates a new key of type TYPE, consisting of the MPI values
+ contained in the data set DATA and stores it in KEY.
+
+ -- Function: gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t
+ HANDLE, unsigned int NBITS, void *KEY_SPEC,
+ gcry_ac_key_pair_t *KEY_PAIR, gcry_mpi_t **MISC_DATA)
+ Generates a new key pair via the handle HANDLE of NBITS bits and
+ stores it in KEY_PAIR.
+
+ In case non-standard settings are wanted, a pointer to a structure
+ of type `gcry_ac_key_spec_<algorithm>_t', matching the selected
+ algorithm, can be given as KEY_SPEC. MISC_DATA is not used yet.
+ Such a structure does only exist for RSA. A description of the
+ members of the supported structures follows.
+
+ `gcry_ac_key_spec_rsa_t'
+
+ `gcry_mpi_t e'
+ Generate the key pair using a special `e'. The value of
+ `e' has the following meanings:
+ `= 0'
+ Let Libgcrypt decide what exponent should be used.
+
+ `= 1'
+ Request the use of a "secure" exponent; this is
+ required by some specification to be 65537.
+
+ `> 2'
+ Try starting at this value until a working exponent
+ is found. Note that the current implementation
+ leaks some information about the private key
+ because the incrementation used is not randomized.
+ Thus, this function will be changed in the future
+ to return a random exponent of the given size.
+
+ Example code:
+ {
+ gcry_ac_key_pair_t key_pair;
+ gcry_ac_key_spec_rsa_t rsa_spec;
+
+ rsa_spec.e = gcry_mpi_new (0);
+ gcry_mpi_set_ui (rsa_spec.e, 1);
+
+ err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
+ assert (! err);
+
+ err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec,
+ &key_pair, NULL);
+ assert (! err);
+ }
+
+ -- Function: gcry_ac_key_t gcry_ac_key_pair_extract
+ (gcry_ac_key_pair_t KEY_PAIR, gcry_ac_key_type_t WHICH)
+ Returns the key of type WHICH out of the key pair KEY_PAIR.
+
+ -- Function: void gcry_ac_key_destroy (gcry_ac_key_t KEY)
+ Destroys the key KEY.
+
+ -- Function: void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t
+ KEY_PAIR)
+ Destroys the key pair KEY_PAIR.
+
+ -- Function: gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t KEY)
+ Returns the data set contained in the key KEY.
+
+ -- Function: gcry_error_t gcry_ac_key_test (gcry_ac_handle_t HANDLE,
+ gcry_ac_key_t KEY)
+ Verifies that the private key KEY is sane via HANDLE.
+
+ -- Function: gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t
+ HANDLE, gcry_ac_key_t KEY, unsigned int *NBITS)
+ Stores the number of bits of the key KEY in NBITS via HANDLE.
+
+ -- Function: gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t
+ HANDLE, gcry_ac_key_t KEY, unsigned char *KEY_GRIP)
+ Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+ HANDLE.
+
+\1f
+File: gcrypt.info, Node: Using cryptographic functions, Next: Handle-independent functions, Prev: Working with keys, Up: AC Interface
+
+6.6.6 Using cryptographic functions
+-----------------------------------
+
+The following flags might be relevant:
+
+`GCRY_AC_FLAG_NO_BLINDING'
+ Disable any blinding, which might be supported by the chosen
+ algorithm; blinding is the default.
+
+ There exist two kinds of cryptographic functions available through
+the ac interface: primitives, and high-level functions.
+
+ Primitives deal with MPIs (data sets) directly; what they provide is
+direct access to the cryptographic operations provided by an algorithm
+implementation.
+
+ High-level functions deal with octet strings, according to a
+specified "scheme". Schemes make use of "encoding methods", which are
+responsible for converting the provided octet strings into MPIs, which
+are then forwared to the cryptographic primitives. Since schemes are
+to be used for a special purpose in order to achieve a particular
+security goal, there exist "encryption schemes" and "signature
+schemes". Encoding methods can be used seperately or implicitly
+through schemes.
+
+ What follows is a description of the cryptographic primitives.
+
+ -- Function: gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t
+ HANDLE, unsigned int FLAGS, gcry_ac_key_t KEY, gcry_mpi_t
+ DATA_PLAIN, gcry_ac_data_t *DATA_ENCRYPTED)
+ Encrypts the plain text MPI value DATA_PLAIN with the key public
+ KEY under the control of the flags FLAGS and stores the resulting
+ data set into DATA_ENCRYPTED.
+
+ -- Function: gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t
+ HANDLE, unsigned int FLAGS, gcry_ac_key_t KEY, gcry_mpi_t
+ *DATA_PLAIN, gcry_ac_data_t DATA_ENCRYPTED)
+ Decrypts the encrypted data contained in the data set
+ DATA_ENCRYPTED with the secret key KEY under the control of the
+ flags FLAGS and stores the resulting plain text MPI value in
+ DATA_PLAIN.
+
+ -- Function: gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t HANDLE,
+ gcry_ac_key_t KEY, gcry_mpi_t DATA, gcry_ac_data_t
+ *DATA_SIGNATURE)
+ Signs the data contained in DATA with the secret key KEY and
+ stores the resulting signature in the data set DATA_SIGNATURE.
+
+ -- Function: gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t
+ HANDLE, gcry_ac_key_t KEY, gcry_mpi_t DATA, gcry_ac_data_t
+ DATA_SIGNATURE)
+ Verifies that the signature contained in the data set
+ DATA_SIGNATURE is indeed the result of signing the data contained
+ in DATA with the secret key belonging to the public key KEY.
+
+ What follows is a description of the high-level functions.
+
+ The type "gcry_ac_em_t" is used for specifying encoding methods; the
+following methods are supported:
+
+`GCRY_AC_EME_PKCS_V1_5'
+ PKCS-V1_5 Encoding Method for Encryption. Options must be provided
+ through a pointer to a correctly initialized object of type
+ gcry_ac_eme_pkcs_v1_5_t.
+
+`GCRY_AC_EMSA_PKCS_V1_5'
+ PKCS-V1_5 Encoding Method for Signatures with Appendix. Options
+ must be provided through a pointer to a correctly initialized
+ object of type gcry_ac_emsa_pkcs_v1_5_t.
+
+ Option structure types:
+
+`gcry_ac_eme_pkcs_v1_5_t'
+
+ `gcry_ac_key_t key'
+
+ `gcry_ac_handle_t handle'
+
+`gcry_ac_emsa_pkcs_v1_5_t'
+
+ `gcry_md_algo_t md'
+
+ `size_t em_n'
+
+ Encoding methods can be used directly through the following
+functions:
+
+ -- Function: gcry_error_t gcry_ac_data_encode (gcry_ac_em_t METHOD,
+ unsigned int FLAGS, void *OPTIONS, unsigned char *M, size_t
+ M_N, unsigned char **EM, size_t *EM_N)
+ Encodes the message contained in M of size M_N according to
+ METHOD, FLAGS and OPTIONS. The newly created encoded message is
+ stored in EM and EM_N.
+
+ -- Function: gcry_error_t gcry_ac_data_decode (gcry_ac_em_t METHOD,
+ unsigned int FLAGS, void *OPTIONS, unsigned char *EM, size_t
+ EM_N, unsigned char **M, size_t *M_N)
+ Decodes the message contained in EM of size EM_N according to
+ METHOD, FLAGS and OPTIONS. The newly created decoded message is
+ stored in M and M_N.
+
+ The type "gcry_ac_scheme_t" is used for specifying schemes; the
+following schemes are supported:
+
+`GCRY_AC_ES_PKCS_V1_5'
+ PKCS-V1_5 Encryption Scheme. No options can be provided.
+
+`GCRY_AC_SSA_PKCS_V1_5'
+ PKCS-V1_5 Signature Scheme (with Appendix). Options can be
+ provided through a pointer to a correctly initialized object of
+ type gcry_ac_ssa_pkcs_v1_5_t.
+
+ Option structure types:
+
+`gcry_ac_ssa_pkcs_v1_5_t'
+
+ `gcry_md_algo_t md'
+
+ The functions implementing schemes:
+
+ -- Function: gcry_error_t gcry_ac_data_encrypt_scheme
+ (gcry_ac_handle_t HANDLE, gcry_ac_scheme_t SCHEME, unsigned
+ int FLAGS, void *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t
+ *IO_MESSAGE, gcry_ac_io_t *IO_CIPHER)
+ Encrypts the plain text readable from IO_MESSAGE through HANDLE
+ with the public key KEY according to SCHEME, FLAGS and OPTS. If
+ OPTS is not NULL, it has to be a pointer to a structure specific
+ to the chosen scheme (gcry_ac_es_*_t). The encrypted message is
+ written to IO_CIPHER.
+
+ -- Function: gcry_error_t gcry_ac_data_decrypt_scheme
+ (gcry_ac_handle_t HANDLE, gcry_ac_scheme_t SCHEME, unsigned
+ int FLAGS, void *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t
+ *IO_CIPHER, gcry_ac_io_t *IO_MESSAGE)
+ Decrypts the cipher text readable from IO_CIPHER through HANDLE
+ with the secret key KEY according to SCHEME, FLAGS and OPTS. If
+ OPTS is not NULL, it has to be a pointer to a structure specific
+ to the chosen scheme (gcry_ac_es_*_t). The decrypted message is
+ written to IO_MESSAGE.
+
+ -- Function: gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t
+ HANDLE, gcry_ac_scheme_t SCHEME, unsigned int FLAGS, void
+ *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t *IO_MESSAGE,
+ gcry_ac_io_t *IO_SIGNATURE)
+ Signs the message readable from IO_MESSAGE through HANDLE with the
+ secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is
+ not NULL, it has to be a pointer to a structure specific to the
+ chosen scheme (gcry_ac_ssa_*_t). The signature is written to
+ IO_SIGNATURE.
+
+ -- Function: gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t
+ HANDLE, gcry_ac_scheme_t SCHEME, unsigned int FLAGS, void
+ *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t *IO_MESSAGE,
+ gcry_ac_io_t *IO_SIGNATURE)
+ Verifies through HANDLE that the signature readable from
+ IO_SIGNATURE is indeed the result of signing the message readable
+ from IO_MESSAGE with the secret key belonging to the public key
+ KEY according to SCHEME and OPTS. If OPTS is not NULL, it has to
+ be an anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
+ scheme.
+
+\1f
+File: gcrypt.info, Node: Handle-independent functions, Prev: Using cryptographic functions, Up: AC Interface
+
+6.6.7 Handle-independent functions
+----------------------------------
+
+These two functions are deprecated; do not use them for new code.
+
+ -- Function: gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t ALGORITHM,
+ const char **NAME)
+ Stores the textual representation of the algorithm whose id is
+ given in ALGORITHM in NAME. Deprecated; use `gcry_pk_algo_name'.
+
+ -- Function: gcry_error_t gcry_ac_name_to_id (const char *NAME,
+ gcry_ac_id_t *ALGORITHM)
+ Stores the numeric ID of the algorithm whose textual
+ representation is contained in NAME in ALGORITHM. Deprecated; use
+ `gcry_pk_map_name'.
+
+\1f
+File: gcrypt.info, Node: Hashing, Next: Key Derivation, Prev: Public Key cryptography, Up: Top
+
+7 Hashing
+*********
+
+Libgcrypt provides an easy and consistent to use interface for hashing.
+Hashing is buffered and several hash algorithms can be updated at once.
+It is possible to compute a MAC using the same routines. The
+programming model follows an open/process/close paradigm and is in that
+similar to other building blocks provided by Libgcrypt.
+
+ For convenience reasons, a few cyclic redundancy check value
+operations are also supported.
+
+* Menu:
+
+* Available hash algorithms:: List of hash algorithms supported by the library.
+* Hash algorithm modules:: How to work with hash algorithm modules.
+* Working with hash algorithms:: List of functions related to hashing.
+
+\1f
+File: gcrypt.info, Node: Available hash algorithms, Next: Hash algorithm modules, Up: Hashing
+
+7.1 Available hash algorithms
+=============================
+
+`GCRY_MD_NONE'
+ This is not a real algorithm but used by some functions as an error
+ return value. This constant is guaranteed to have the value `0'.
+
+`GCRY_MD_SHA1'
+ This is the SHA-1 algorithm which yields a message digest of 20
+ bytes. Note that SHA-1 begins to show some weaknesses and it is
+ suggested to fade out its use if strong cryptographic properties
+ are required.
+
+`GCRY_MD_RMD160'
+ This is the 160 bit version of the RIPE message digest
+ (RIPE-MD-160). Like SHA-1 it also yields a digest of 20 bytes.
+ This algorithm share a lot of design properties with SHA-1 and
+ thus it is advisable not to use it for new protocols.
+
+`GCRY_MD_MD5'
+ This is the well known MD5 algorithm, which yields a message
+ digest of 16 bytes. Note that the MD5 algorithm has severe
+ weaknesses, for example it is easy to compute two messages
+ yielding the same hash (collision attack). The use of this
+ algorithm is only justified for non-cryptographic application.
+
+`GCRY_MD_MD4'
+ This is the MD4 algorithm, which yields a message digest of 16
+ bytes. This algorithms ha severe weaknesses and should not be
+ used.
+
+`GCRY_MD_MD2'
+ This is an reserved identifier for MD-2; there is no
+ implementation yet. This algorithm has severe weaknesses and
+ should not be used.
+
+`GCRY_MD_TIGER'
+ This is the TIGER/192 algorithm which yields a message digest of 24
+ bytes. Actually this is a variant of TIGER with a different output
+ print order as used by GnuPG up to version 1.3.2.
+
+`GCRY_MD_TIGER1'
+ This is the TIGER variant as used by the NESSIE project. It uses
+ the most commonly used output print order.
+
+`GCRY_MD_TIGER2'
+ This is another variant of TIGER with a different padding scheme.
+
+`GCRY_MD_HAVAL'
+ This is an reserved value for the HAVAL algorithm with 5 passes
+ and 160 bit. It yields a message digest of 20 bytes. Note that
+ there is no implementation yet available.
+
+`GCRY_MD_SHA224'
+ This is the SHA-224 algorithm which yields a message digest of 28
+ bytes. See Change Notice 1 for FIPS 180-2 for the specification.
+
+`GCRY_MD_SHA256'
+ This is the SHA-256 algorithm which yields a message digest of 32
+ bytes. See FIPS 180-2 for the specification.
+
+`GCRY_MD_SHA384'
+ This is the SHA-384 algorithm which yields a message digest of 48
+ bytes. See FIPS 180-2 for the specification.
+
+`GCRY_MD_SHA512'
+ This is the SHA-384 algorithm which yields a message digest of 64
+ bytes. See FIPS 180-2 for the specification.
+
+`GCRY_MD_CRC32'
+ This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It
+ yields an output of 4 bytes. Note that this is not a hash
+ algorithm in the cryptographic sense.
+
+`GCRY_MD_CRC32_RFC1510'
+ This is the above cyclic redundancy check function, as modified by
+ RFC 1510. It yields an output of 4 bytes. Note that this is not
+ a hash algorithm in the cryptographic sense.
+
+`GCRY_MD_CRC24_RFC2440'
+ This is the OpenPGP cyclic redundancy check function. It yields an
+ output of 3 bytes. Note that this is not a hash algorithm in the
+ cryptographic sense.
+
+`GCRY_MD_WHIRLPOOL'
+ This is the Whirlpool algorithm which yields a message digest of 64
+ bytes.
+
+
+\1f
+File: gcrypt.info, Node: Hash algorithm modules, Next: Working with hash algorithms, Prev: Available hash algorithms, Up: Hashing
+
+7.2 Hash algorithm modules
+==========================
+
+Libgcrypt makes it possible to load additional `message digest
+modules'; these digests can be used just like the message digest
+algorithms that are built into the library directly. For an
+introduction into extension modules, see *Note Modules::.
+
+ -- Data type: gcry_md_spec_t
+ This is the `module specification structure' needed for registering
+ message digest modules, which has to be filled in by the user
+ before it can be used to register a module. It contains the
+ following members:
+
+ `const char *name'
+ The primary name of this algorithm.
+
+ `unsigned char *asnoid'
+ Array of bytes that form the ASN OID.
+
+ `int asnlen'
+ Length of bytes in `asnoid'.
+
+ `gcry_md_oid_spec_t *oids'
+ A list of OIDs that are to be associated with the algorithm.
+ The list's last element must have it's `oid' member set to
+ NULL. See below for an explanation of this type. See below
+ for an explanation of this type.
+
+ `int mdlen'
+ Length of the message digest algorithm. See below for an
+ explanation of this type.
+
+ `gcry_md_init_t init'
+ The function responsible for initializing a handle. See
+ below for an explanation of this type.
+
+ `gcry_md_write_t write'
+ The function responsible for writing data into a message
+ digest context. See below for an explanation of this type.
+
+ `gcry_md_final_t final'
+ The function responsible for `finalizing' a message digest
+ context. See below for an explanation of this type.
+
+ `gcry_md_read_t read'
+ The function responsible for reading out a message digest
+ result. See below for an explanation of this type.
+
+ `size_t contextsize'
+ The size of the algorithm-specific `context', that should be
+ allocated for each handle.
+
+ -- Data type: gcry_md_oid_spec_t
+ This type is used for associating a user-provided algorithm
+ implementation with certain OIDs. It contains the following
+ members:
+
+ `const char *oidstring'
+ Textual representation of the OID.
+
+ -- Data type: gcry_md_init_t
+ Type for the `init' function, defined as: void (*gcry_md_init_t)
+ (void *c)
+
+ -- Data type: gcry_md_write_t
+ Type for the `write' function, defined as: void (*gcry_md_write_t)
+ (void *c, unsigned char *buf, size_t nbytes)
+
+ -- Data type: gcry_md_final_t
+ Type for the `final' function, defined as: void (*gcry_md_final_t)
+ (void *c)
+
+ -- Data type: gcry_md_read_t
+ Type for the `read' function, defined as: unsigned char
+ *(*gcry_md_read_t) (void *c)
+
+ -- Function: gcry_error_t gcry_md_register (gcry_md_spec_t *DIGEST,
+ unsigned int *algorithm_id, gcry_module_t *MODULE)
+ Register a new digest module whose specification can be found in
+ DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representing this module is stored in MODULE.
+ Deprecated; the module register interface will be removed in a
+ future version.
+
+ -- Function: void gcry_md_unregister (gcry_module_t MODULE)
+ Unregister the digest identified by MODULE, which must have been
+ registered with gcry_md_register.
+
+ -- Function: gcry_error_t gcry_md_list (int *LIST, int *LIST_LENGTH)
+ Get a list consisting of the IDs of the loaded message digest
+ modules. If LIST is zero, write the number of loaded message
+ digest modules to LIST_LENGTH and return. If LIST is non-zero,
+ the first *LIST_LENGTH algorithm IDs are stored in LIST, which
+ must be of according size. In case there are less message digests
+ modules than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+ number.
+
+\1f
+File: gcrypt.info, Node: Working with hash algorithms, Prev: Hash algorithm modules, Up: Hashing
+
+7.3 Working with hash algorithms
+================================
+
+To use most of these function it is necessary to create a context; this
+is done using:
+
+ -- Function: gcry_error_t gcry_md_open (gcry_md_hd_t *HD, int ALGO,
+ unsigned int FLAGS)
+ Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of constants described below. ALGO may be
+ given as `0' if the algorithms to use are later set using
+ `gcry_md_enable'. HD is guaranteed to either receive a valid
+ handle or NULL.
+
+ For a list of supported algorithms, see *Note Available hash
+ algorithms::.
+
+ The flags allowed for MODE are:
+
+ `GCRY_MD_FLAG_SECURE'
+ Allocate all buffers and the resulting digest in "secure
+ memory". Use this is the hashed data is highly confidential.
+
+ `GCRY_MD_FLAG_HMAC'
+ Turn the algorithm into a HMAC message authentication
+ algorithm. This only works if just one algorithm is enabled
+ for the handle. Note that the function `gcry_md_setkey' must
+ be used to set the MAC key. The size of the MAC is equal to
+ the message digest of the underlying hash algorithm. If you
+ want CBC message authentication codes based on a cipher, see
+ *Note Working with cipher handles::.
+
+
+ You may use the function `gcry_md_is_enabled' to later check
+ whether an algorithm has been enabled.
+
+
+ If you want to calculate several hash algorithms at the same time,
+you have to use the following function right after the `gcry_md_open':
+
+ -- Function: gcry_error_t gcry_md_enable (gcry_md_hd_t H, int ALGO)
+ Add the message digest algorithm ALGO to the digest object
+ described by handle H. Duplicated enabling of algorithms is
+ detected and ignored.
+
+ If the flag `GCRY_MD_FLAG_HMAC' was used, the key for the MAC must
+be set using the function:
+
+ -- Function: gcry_error_t gcry_md_setkey (gcry_md_hd_t H, const void
+ *KEY, size_t KEYLEN)
+ For use with the HMAC feature, set the MAC key to the value of KEY
+ of length KEYLEN bytes. There is no restriction on the length of
+ the key.
+
+ After you are done with the hash calculation, you should release the
+resources by using:
+
+ -- Function: void gcry_md_close (gcry_md_hd_t H)
+ Release all resources of hash context H. H should not be used
+ after a call to this function. A `NULL' passed as H is ignored.
+ The function also zeroises all sensitive information associated
+ with this handle.
+
+
+ Often you have to do several hash operations using the same
+algorithm. To avoid the overhead of creating and releasing context, a
+reset function is provided:
+
+ -- Function: void gcry_md_reset (gcry_md_hd_t H)
+ Reset the current context to its initial state. This is
+ effectively identical to a close followed by an open and enabling
+ all currently active algorithms.
+
+ Often it is necessary to start hashing some data and then continue to
+hash different data. To avoid hashing the same data several times
+(which might not even be possible if the data is received from a pipe),
+a snapshot of the current hash context can be taken and turned into a
+new context:
+
+ -- Function: gcry_error_t gcry_md_copy (gcry_md_hd_t *HANDLE_DST,
+ gcry_md_hd_t HANDLE_SRC)
+ Create a new digest object as an exact copy of the object
+ described by handle HANDLE_SRC and store it in HANDLE_DST. The
+ context is not reset and you can continue to hash data using this
+ context and independently using the original context.
+
+ Now that we have prepared everything to calculate hashes, it is time
+to see how it is actually done. There are two ways for this, one to
+update the hash with a block of memory and one macro to update the hash
+by just one character. Both methods can be used on the same hash
+context.
+
+ -- Function: void gcry_md_write (gcry_md_hd_t H, const void *BUFFER,
+ size_t LENGTH)
+ Pass LENGTH bytes of the data in BUFFER to the digest object with
+ handle H to update the digest values. This function should be used
+ for large blocks of data.
+
+ -- Function: void gcry_md_putc (gcry_md_hd_t H, int C)
+ Pass the byte in C to the digest object with handle H to update
+ the digest value. This is an efficient function, implemented as a
+ macro to buffer the data before an actual update.
+
+ The semantics of the hash functions do not provide for reading out
+intermediate message digests because the calculation must be finalized
+first. This finalization may for example include the number of bytes
+hashed in the message digest or some padding.
+
+ -- Function: void gcry_md_final (gcry_md_hd_t H)
+ Finalize the message digest calculation. This is not really needed
+ because `gcry_md_read' does this implicitly. After this has been
+ done no further updates (by means of `gcry_md_write' or
+ `gcry_md_putc' are allowed. Only the first call to this function
+ has an effect. It is implemented as a macro.
+
+ The way to read out the calculated message digest is by using the
+function:
+
+ -- Function: unsigned char * gcry_md_read (gcry_md_hd_t H, int ALGO)
+ `gcry_md_read' returns the message digest after finalizing the
+ calculation. This function may be used as often as required but
+ it will always return the same value for one handle. The returned
+ message digest is allocated within the message context and
+ therefore valid until the handle is released or reseted (using
+ `gcry_md_close' or `gcry_md_reset'. ALGO may be given as 0 to
+ return the only enabled message digest or it may specify one of
+ the enabled algorithms. The function does return `NULL' if the
+ requested algorithm has not been enabled.
+
+ Because it is often necessary to get the message digest of one block
+of memory, a fast convenience function is available for this task:
+
+ -- Function: void gcry_md_hash_buffer (int ALGO, void *DIGEST, const
+ void *BUFFER, size_t LENGTH);
+ `gcry_md_hash_buffer' is a shortcut function to calculate a message
+ digest of a buffer. This function does not require a context and
+ immediately returns the message digest of the LENGTH bytes at
+ BUFFER. DIGEST must be allocated by the caller, large enough to
+ hold the message digest yielded by the the specified algorithm
+ ALGO. This required size may be obtained by using the function
+ `gcry_md_get_algo_dlen'.
+
+ Note that this function will abort the process if an unavailable
+ algorithm is used.
+
+ Hash algorithms are identified by internal algorithm numbers (see
+`gcry_md_open' for a list). However, in most applications they are
+used by names, so two functions are available to map between string
+representations and hash algorithm identifiers.
+
+ -- Function: const char * gcry_md_algo_name (int ALGO)
+ Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns the
+ string `"?"'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: int gcry_md_map_name (const char *NAME)
+ Map the algorithm with NAME to a digest algorithm identifier.
+ Returns 0 if the algorithm name is not known. Names representing
+ ASN.1 object identifiers are recognized if the IETF dotted format
+ is used and the OID is prefixed with either "`oid.'" or "`OID.'".
+ For a list of supported OIDs, see the source code at
+ `cipher/md.c'. This function should not be used to test for the
+ availability of an algorithm.
+
+ -- Function: gcry_error_t gcry_md_get_asnoid (int ALGO, void *BUFFER,
+ size_t *LENGTH)
+ Return an DER encoded ASN.1 OID for the algorithm ALGO in the user
+ allocated BUFFER. LENGTH must point to variable with the available
+ size of BUFFER and receives after return the actual size of the
+ returned OID. The returned error code may be `GPG_ERR_TOO_SHORT'
+ if the provided buffer is to short to receive the OID; it is
+ possible to call the function with `NULL' for BUFFER to have it
+ only return the required size. The function returns 0 on success.
+
+
+ To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+ -- Function: gcry_error_t gcry_md_test_algo (int ALGO)
+ The macro returns 0 if the algorithm ALGO is available for use.
+
+ If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+ -- Function: unsigned int gcry_md_get_algo_dlen (int ALGO)
+ Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. This is often used prior to `gcry_md_read' to allocate
+ sufficient memory for the digest.
+
+ In some situations it might be hard to remember the algorithm used
+for the ongoing hashing. The following function might be used to get
+that information:
+
+ -- Function: int gcry_md_get_algo (gcry_md_hd_t H)
+ Retrieve the algorithm used with the handle H. Note that this
+ does not work reliable if more than one algorithm is enabled in H.
+
+ The following macro might also be useful:
+
+ -- Function: int gcry_md_is_secure (gcry_md_hd_t H)
+ This function returns true when the digest object H is allocated
+ in "secure memory"; i.e. H was created with the
+ `GCRY_MD_FLAG_SECURE'.
+
+ -- Function: int gcry_md_is_enabled (gcry_md_hd_t H, int ALGO)
+ This function returns true when the algorithm ALGO has been
+ enabled for the digest object H.
+
+ Tracking bugs related to hashing is often a cumbersome task which
+requires to add a lot of printf statements into the code. Libgcrypt
+provides an easy way to avoid this. The actual data hashed can be
+written to files on request.
+
+ -- Function: void gcry_md_debug (gcry_md_hd_t H, const char *SUFFIX)
+ Enable debugging for the digest object with handle H. This
+ creates create files named `dbgmd-<n>.<string>' while doing the
+ actual hashing. SUFFIX is the string part in the filename. The
+ number is a counter incremented for each new hashing. The data in
+ the file is the raw data as passed to `gcry_md_write' or
+ `gcry_md_putc'. If `NULL' is used for SUFFIX, the debugging is
+ stopped and the file closed. This is only rarely required because
+ `gcry_md_close' implicitly stops debugging.
+
+ The following two deprecated macros are used for debugging by old
+code. They shopuld be replaced by `gcry_md_debug'.
+
+ -- Function: void gcry_md_start_debug (gcry_md_hd_t H, const char
+ *SUFFIX)
+ Enable debugging for the digest object with handle H. This
+ creates create files named `dbgmd-<n>.<string>' while doing the
+ actual hashing. SUFFIX is the string part in the filename. The
+ number is a counter incremented for each new hashing. The data in
+ the file is the raw data as passed to `gcry_md_write' or
+ `gcry_md_putc'.
+
+ -- Function: void gcry_md_stop_debug (gcry_md_hd_t H, int RESERVED)
+ Stop debugging on handle H. RESERVED should be specified as 0.
+ This function is usually not required because `gcry_md_close' does
+ implicitly stop debugging.
+
+\1f
+File: gcrypt.info, Node: Key Derivation, Next: Random Numbers, Prev: Hashing, Up: Top
+
+8 Key Derivation
+****************
+
+Libgcypt provides a general purpose function to derive keys from
+strings.
+
+ -- Function: gpg_error_t gcry_kdf_derive ( const void *PASSPHRASE,
+ size_t PASSPHRASELEN, int ALGO, int SUBALGO,
+ const void *SALT, size_t SALTLEN, unsigned long ITERATIONS,
+ size_t KEYSIZE, void *KEYBUFFER )
+ Derive a key from a passphrase. KEYSIZE gives the requested size
+ of the keys in octets. KEYBUFFER is a caller provided buffer
+ filled on success with the derived key. The input passphrase is
+ taken from PASSPHRASE which is an arbitrary memory buffer of
+ PASSPHRASELEN octets. ALGO specifies the KDF algorithm to use;
+ see below. SUBALGO specifies an algorithm used internally by the
+ KDF algorithms; this is usually a hash algorithm but certain KDF
+ algorithms may use it differently. SALT is a salt of length
+ SALTLEN octets, as needed by most KDF algorithms. ITERATIONS is a
+ positive integer parameter to most KDFs.
+
+ On success 0 is returned; on failure an error code.
+
+ Currently supported KDFs (parameter ALGO):
+
+ `GCRY_KDF_SIMPLE_S2K'
+ The OpenPGP simple S2K algorithm (cf. RFC4880). Its use is
+ strongly deprecated. SALT and ITERATIONS are not needed and
+ may be passed as `NULL'/`0'.
+
+ `GCRY_KDF_SALTED_S2K'
+ The OpenPGP salted S2K algorithm (cf. RFC4880). Usually not
+ used. ITERATIONS is not needed and may be passed as `0'.
+ SALTLEN must be given as 8.
+
+ `GCRY_KDF_ITERSALTED_S2K'
+ The OpenPGP iterated+salted S2K algorithm (cf. RFC4880).
+ This is the default for most OpenPGP applications. SALTLEN
+ must be given as 8. Note that OpenPGP defines a special
+ encoding of the ITERATIONS; however this function takes the
+ plain decoded iteration count.
+
+ `GCRY_KDF_PBKDF2'
+ The PKCS#5 Passphrase Based Key Derivation Function number 2.
+
+
+\1f
+File: gcrypt.info, Node: Random Numbers, Next: S-expressions, Prev: Key Derivation, Up: Top
+
+9 Random Numbers
+****************
+
+* Menu:
+
+* Quality of random numbers:: Libgcrypt uses different quality levels.
+* Retrieving random numbers:: How to retrieve random numbers.
+
+\1f
+File: gcrypt.info, Node: Quality of random numbers, Next: Retrieving random numbers, Up: Random Numbers
+
+9.1 Quality of random numbers
+=============================
+
+Libgcypt offers random numbers of different quality levels:
+
+ -- Data type: gcry_random_level_t
+ The constants for the random quality levels are of this enum type.
+
+`GCRY_WEAK_RANDOM'
+ For all functions, except for `gcry_mpi_randomize', this level maps
+ to GCRY_STRONG_RANDOM. If you do not want this, consider using
+ `gcry_create_nonce'.
+
+`GCRY_STRONG_RANDOM'
+ Use this level for session keys and similar purposes.
+
+`GCRY_VERY_STRONG_RANDOM'
+ Use this level for long term key material.
+
+\1f
+File: gcrypt.info, Node: Retrieving random numbers, Prev: Quality of random numbers, Up: Random Numbers
+
+9.2 Retrieving random numbers
+=============================
+
+ -- Function: void gcry_randomize (unsigned char *BUFFER, size_t
+ LENGTH, enum gcry_random_level LEVEL)
+ Fill BUFFER with LENGTH random bytes using a random quality as
+ defined by LEVEL.
+
+ -- Function: void * gcry_random_bytes (size_t NBYTES, enum
+ gcry_random_level LEVEL)
+ Convenience function to allocate a memory block consisting of
+ NBYTES fresh random bytes using a random quality as defined by
+ LEVEL.
+
+ -- Function: void * gcry_random_bytes_secure (size_t NBYTES, enum
+ gcry_random_level LEVEL)
+ Convenience function to allocate a memory block consisting of
+ NBYTES fresh random bytes using a random quality as defined by
+ LEVEL. This function differs from `gcry_random_bytes' in that the
+ returned buffer is allocated in a "secure" area of the memory.
+
+ -- Function: void gcry_create_nonce (unsigned char *BUFFER, size_t
+ LENGTH)
+ Fill BUFFER with LENGTH unpredictable bytes. This is commonly
+ called a nonce and may also be used for initialization vectors and
+ padding. This is an extra function nearly independent of the
+ other random function for 3 reasons: It better protects the
+ regular random generator's internal state, provides better
+ performance and does not drain the precious entropy pool.
+
+
+\1f
+File: gcrypt.info, Node: S-expressions, Next: MPI library, Prev: Random Numbers, Up: Top
+
+10 S-expressions
+****************
+
+S-expressions are used by the public key functions to pass complex data
+structures around. These LISP like objects are used by some
+cryptographic protocols (cf. RFC-2692) and Libgcrypt provides functions
+to parse and construct them. For detailed information, see `Ron
+Rivest, code and description of S-expressions,
+`http://theory.lcs.mit.edu/~rivest/sexp.html''.
+
+* Menu:
+
+* Data types for S-expressions:: Data types related with S-expressions.
+* Working with S-expressions:: How to work with S-expressions.
+
+\1f
+File: gcrypt.info, Node: Data types for S-expressions, Next: Working with S-expressions, Up: S-expressions
+
+10.1 Data types for S-expressions
+=================================
+
+ -- Data type: gcry_sexp_t
+ The `gcry_sexp_t' type describes an object with the Libgcrypt
+ internal representation of an S-expression.
+
+\1f
+File: gcrypt.info, Node: Working with S-expressions, Prev: Data types for S-expressions, Up: S-expressions
+
+10.2 Working with S-expressions
+===============================
+
+There are several functions to create an Libgcrypt S-expression object
+from its external representation or from a string template. There is
+also a function to convert the internal representation back into one of
+the external formats:
+
+ -- Function: gcry_error_t gcry_sexp_new (gcry_sexp_t *R_SEXP,
+ const void *BUFFER, size_t LENGTH, int AUTODETECT)
+ This is the generic function to create an new S-expression object
+ from its external representation in BUFFER of LENGTH bytes. On
+ success the result is stored at the address given by R_SEXP. With
+ AUTODETECT set to 0, the data in BUFFER is expected to be in
+ canonized format, with AUTODETECT set to 1 the parses any of the
+ defined external formats. If BUFFER does not hold a valid
+ S-expression an error code is returned and R_SEXP set to `NULL'.
+ Note that the caller is responsible for releasing the newly
+ allocated S-expression using `gcry_sexp_release'.
+
+ -- Function: gcry_error_t gcry_sexp_create (gcry_sexp_t *R_SEXP,
+ void *BUFFER, size_t LENGTH, int AUTODETECT,
+ void (*FREEFNC)(void*))
+ This function is identical to `gcry_sexp_new' but has an extra
+ argument FREEFNC, which, when not set to `NULL', is expected to be
+ a function to release the BUFFER; most likely the standard `free'
+ function is used for this argument. This has the effect of
+ transferring the ownership of BUFFER to the created object in
+ R_SEXP. The advantage of using this function is that Libgcrypt
+ might decide to directly use the provided buffer and thus avoid
+ extra copying.
+
+ -- Function: gcry_error_t gcry_sexp_sscan (gcry_sexp_t *R_SEXP,
+ size_t *ERROFF, const char *BUFFER, size_t LENGTH)
+ This is another variant of the above functions. It behaves nearly
+ identical but provides an ERROFF argument which will receive the
+ offset into the buffer where the parsing stopped on error.
+
+ -- Function: gcry_error_t gcry_sexp_build (gcry_sexp_t *R_SEXP,
+ size_t *ERROFF, const char *FORMAT, ...)
+ This function creates an internal S-expression from the string
+ template FORMAT and stores it at the address of R_SEXP. If there
+ is a parsing error, the function returns an appropriate error code
+ and stores the offset into FORMAT where the parsing stopped in
+ ERROFF. The function supports a couple of printf-like formatting
+ characters and expects arguments for some of these escape
+ sequences right after FORMAT. The following format characters are
+ defined:
+
+ `%m'
+ The next argument is expected to be of type `gcry_mpi_t' and
+ a copy of its value is inserted into the resulting
+ S-expression. The MPI is stored as a signed integer.
+
+ `%M'
+ The next argument is expected to be of type `gcry_mpi_t' and
+ a copy of its value is inserted into the resulting
+ S-expression. The MPI is stored as an unsigned integer.
+
+ `%s'
+ The next argument is expected to be of type `char *' and that
+ string is inserted into the resulting S-expression.
+
+ `%d'
+ The next argument is expected to be of type `int' and its
+ value is inserted into the resulting S-expression.
+
+ `%u'
+ The next argument is expected to be of type `unsigned int' and
+ its value is inserted into the resulting S-expression.
+
+ `%b'
+ The next argument is expected to be of type `int' directly
+ followed by an argument of type `char *'. This represents a
+ buffer of given length to be inserted into the resulting
+ S-expression.
+
+ `%S'
+ The next argument is expected to be of type `gcry_sexp_t' and
+ a copy of that S-expression is embedded in the resulting
+ S-expression. The argument needs to be a regular
+ S-expression, starting with a parenthesis.
+
+
+ No other format characters are defined and would return an error.
+ Note that the format character `%%' does not exists, because a
+ percent sign is not a valid character in an S-expression.
+
+ -- Function: void gcry_sexp_release (gcry_sexp_t SEXP)
+ Release the S-expression object SEXP. If the S-expression is
+ stored in secure memory it explicitly zeroises that memory; note
+ that this is done in addition to the zeroisation always done when
+ freeing secure memory.
+
+The next 2 functions are used to convert the internal representation
+back into a regular external S-expression format and to show the
+structure for debugging.
+
+ -- Function: size_t gcry_sexp_sprint (gcry_sexp_t SEXP, int MODE,
+ char *BUFFER, size_t MAXLENGTH)
+ Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. MAXLENGTH must be set to the allocated length
+ of BUFFER. The function returns the actual length of valid bytes
+ put into BUFFER or 0 if the provided buffer is too short. Passing
+ `NULL' for BUFFER returns the required length for BUFFER. For
+ convenience reasons an extra byte with value 0 is appended to the
+ buffer.
+
+ The following formats are supported:
+
+ `GCRYSEXP_FMT_DEFAULT'
+ Returns a convenient external S-expression representation.
+
+ `GCRYSEXP_FMT_CANON'
+ Return the S-expression in canonical format.
+
+ `GCRYSEXP_FMT_BASE64'
+ Not currently supported.
+
+ `GCRYSEXP_FMT_ADVANCED'
+ Returns the S-expression in advanced format.
+
+ -- Function: void gcry_sexp_dump (gcry_sexp_t SEXP)
+ Dumps SEXP in a format suitable for debugging to Libgcrypt's
+ logging stream.
+
+Often canonical encoding is used in the external representation. The
+following function can be used to check for valid encoding and to learn
+the length of the S-expression"
+
+ -- Function: size_t gcry_sexp_canon_len (const unsigned char *BUFFER,
+ size_t LENGTH, size_t *ERROFF, int *ERRCODE)
+ Scan the canonical encoded BUFFER with implicit length values and
+ return the actual length this S-expression uses. For a valid
+ S-expression it should never return 0. If LENGTH is not 0, the
+ maximum length to scan is given; this can be used for syntax
+ checks of data passed from outside. ERRCODE and ERROFF may both be
+ passed as `NULL'.
+
+
+There are functions to parse S-expressions and retrieve elements:
+
+ -- Function: gcry_sexp_t gcry_sexp_find_token (const gcry_sexp_t LIST,
+ const char *TOKEN, size_t TOKLEN)
+ Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ `NULL' when not found.
+
+ -- Function: int gcry_sexp_length (const gcry_sexp_t LIST)
+ Return the length of the LIST. For a valid S-expression this
+ should be at least 1.
+
+ -- Function: gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t LIST,
+ int NUMBER)
+ Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, `NULL' is returned.
+
+ -- Function: gcry_sexp_t gcry_sexp_car (const gcry_sexp_t LIST)
+ Create and return a new S-expression from the first element in
+ LIST; this called the "type" and should always exist and be a
+ string. `NULL' is returned in case of a problem.
+
+ -- Function: gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t LIST)
+ Create and return a new list form all elements except for the
+ first one. Note that this function may return an invalid
+ S-expression because it is not guaranteed, that the type exists
+ and is a string. However, for parsing a complex S-expression it
+ might be useful for intermediate lists. Returns `NULL' on error.
+
+ -- Function: const char * gcry_sexp_nth_data (const gcry_sexp_t LIST,
+ int NUMBER, size_t *DATALEN)
+ This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, `NULL' is returned.
+ *Caution:* The returned pointer is valid as long as LIST is not
+ modified or released.
+
+ Here is an example on how to extract and print the surname (Meier)
+ from the S-expression `(Name Otto Meier (address Burgplatz 3))':
+
+ size_t len;
+ const char *name;
+
+ name = gcry_sexp_nth_data (list, 2, &len);
+ printf ("my name is %.*s\n", (int)len, name);
+
+ -- Function: char * gcry_sexp_nth_string (gcry_sexp_t LIST, int NUMBER)
+ This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release this returned value using `gcry_free'. If there is no
+ data at the given index, the index represents a list or the value
+ can't be converted to a string, `NULL' is returned.
+
+ -- Function: gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t LIST,
+ int NUMBER, int MPIFMT)
+ This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using `gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, `NULL' is returned. If you use
+ this function to parse results of a public key function, you most
+ likely want to use `GCRYMPI_FMT_USG'.
+
+\1f
+File: gcrypt.info, Node: MPI library, Next: Prime numbers, Prev: S-expressions, Up: Top
+
+11 MPI library
+**************
+
+* Menu:
+
+* Data types:: MPI related data types.
+* Basic functions:: First steps with MPI numbers.
+* MPI formats:: External representation of MPIs.
+* Calculations:: Performing MPI calculations.
+* Comparisons:: How to compare MPI values.
+* Bit manipulations:: How to access single bits of MPI values.
+* Miscellaneous:: Miscellaneous MPI functions.
+
+ Public key cryptography is based on mathematics with large numbers.
+To implement the public key functions, a library for handling these
+large numbers is required. Because of the general usefulness of such a
+library, its interface is exposed by Libgcrypt. In the context of
+Libgcrypt and in most other applications, these large numbers are
+called MPIs (multi-precision-integers).
+
+\1f
+File: gcrypt.info, Node: Data types, Next: Basic functions, Up: MPI library
+
+11.1 Data types
+===============
+
+ -- Data type: gcry_mpi_t
+ This type represents an object to hold an MPI.
+
+\1f
+File: gcrypt.info, Node: Basic functions, Next: MPI formats, Prev: Data types, Up: MPI library
+
+11.2 Basic functions
+====================
+
+To work with MPIs, storage must be allocated and released for the
+numbers. This can be done with one of these functions:
+
+ -- Function: gcry_mpi_t gcry_mpi_new (unsigned int NBITS)
+ Allocate a new MPI object, initialize it to 0 and initially
+ allocate enough memory for a number of at least NBITS. This
+ pre-allocation is only a small performance issue and not actually
+ necessary because Libgcrypt automatically re-allocates the
+ required memory.
+
+ -- Function: gcry_mpi_t gcry_mpi_snew (unsigned int NBITS)
+ This is identical to `gcry_mpi_new' but allocates the MPI in the so
+ called "secure memory" which in turn will take care that all
+ derived values will also be stored in this "secure memory". Use
+ this for highly confidential data like private key parameters.
+
+ -- Function: gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t A)
+ Create a new MPI as the exact copy of A.
+
+ -- Function: void gcry_mpi_release (gcry_mpi_t A)
+ Release the MPI A and free all associated resources. Passing
+ `NULL' is allowed and ignored. When a MPI stored in the "secure
+ memory" is released, that memory gets wiped out immediately.
+
+The simplest operations are used to assign a new value to an MPI:
+
+ -- Function: gcry_mpi_t gcry_mpi_set (gcry_mpi_t W, const gcry_mpi_t U)
+ Assign the value of U to W and return W. If `NULL' is passed for
+ W, a new MPI is allocated, set to the value of U and returned.
+
+ -- Function: gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t W, unsigned long U)
+ Assign the value of U to W and return W. If `NULL' is passed for
+ W, a new MPI is allocated, set to the value of U and returned.
+ This function takes an `unsigned int' as type for U and thus it is
+ only possible to set W to small values (usually up to the word
+ size of the CPU).
+
+ -- Function: void gcry_mpi_swap (gcry_mpi_t A, gcry_mpi_t B)
+ Swap the values of A and B.
+
+\1f
+File: gcrypt.info, Node: MPI formats, Next: Calculations, Prev: Basic functions, Up: MPI library
+
+11.3 MPI formats
+================
+
+The following functions are used to convert between an external
+representation of an MPI and the internal one of Libgcrypt.
+
+ -- Function: gcry_error_t gcry_mpi_scan (gcry_mpi_t *R_MPI,
+ enum gcry_mpi_format FORMAT, const unsigned char *BUFFER,
+ size_t BUFLEN, size_t *NSCANNED)
+ Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly created MPI returned which
+ will be stored at the address of R_MPI. For certain formats the
+ length argument is not required and should be passed as `0'.
+ After a successful operation the variable NSCANNED receives the
+ number of bytes actually scanned unless NSCANNED was given as
+ `NULL'. FORMAT describes the format of the MPI as stored in BUFFER:
+
+ `GCRYMPI_FMT_STD'
+ 2-complement stored without a length header.
+
+ `GCRYMPI_FMT_PGP'
+ As used by OpenPGP (only defined as unsigned). This is
+ basically `GCRYMPI_FMT_STD' with a 2 byte big endian length
+ header.
+
+ `GCRYMPI_FMT_SSH'
+ As used in the Secure Shell protocol. This is
+ `GCRYMPI_FMT_STD' with a 4 byte big endian header.
+
+ `GCRYMPI_FMT_HEX'
+ Stored as a C style string with each byte of the MPI encoded
+ as 2 hex digits. When using this format, BUFLEN must be zero.
+
+ `GCRYMPI_FMT_USG'
+ Simple unsigned integer.
+
+ Note that all of the above formats store the integer in big-endian
+ format (MSB first).
+
+ -- Function: gcry_error_t gcry_mpi_print (enum gcry_mpi_format FORMAT,
+ unsigned char *BUFFER, size_t BUFLEN, size_t *NWRITTEN,
+ const gcry_mpi_t A)
+ Convert the MPI A into an external representation described by
+ FORMAT (see above) and store it in the provided BUFFER which has a
+ usable length of at least the BUFLEN bytes. If NWRITTEN is not
+ NULL, it will receive the number of bytes actually stored in
+ BUFFER after a successful operation.
+
+ -- Function: gcry_error_t gcry_mpi_aprint
+ (enum gcry_mpi_format FORMAT, unsigned char **BUFFER,
+ size_t *NBYTES, const gcry_mpi_t A)
+ Convert the MPI A into an external representation described by
+ FORMAT (see above) and store it in a newly allocated buffer which
+ address will be stored in the variable BUFFER points to. The
+ number of bytes stored in this buffer will be stored in the
+ variable NBYTES points to, unless NBYTES is `NULL'.
+
+ -- Function: void gcry_mpi_dump (const gcry_mpi_t A)
+ Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ `NULL' for A.
+
+\1f
+File: gcrypt.info, Node: Calculations, Next: Comparisons, Prev: MPI formats, Up: MPI library
+
+11.4 Calculations
+=================
+
+Basic arithmetic operations:
+
+ -- Function: void gcry_mpi_add (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+ W = U + V.
+
+ -- Function: void gcry_mpi_add_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+ W = U + V. Note that V is an unsigned integer.
+
+ -- Function: void gcry_mpi_addm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+ W = U + V \bmod M.
+
+ -- Function: void gcry_mpi_sub (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+ W = U - V.
+
+ -- Function: void gcry_mpi_sub_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+ W = U - V. V is an unsigned integer.
+
+ -- Function: void gcry_mpi_subm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+ W = U - V \bmod M.
+
+ -- Function: void gcry_mpi_mul (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V)
+ W = U * V.
+
+ -- Function: void gcry_mpi_mul_ui (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long V)
+ W = U * V. V is an unsigned integer.
+
+ -- Function: void gcry_mpi_mulm (gcry_mpi_t W, gcry_mpi_t U,
+ gcry_mpi_t V, gcry_mpi_t M)
+ W = U * V \bmod M.
+
+ -- Function: void gcry_mpi_mul_2exp (gcry_mpi_t W, gcry_mpi_t U,
+ unsigned long E)
+ W = U * 2^e.
+
+ -- Function: void gcry_mpi_div (gcry_mpi_t Q, gcry_mpi_t R,
+ gcry_mpi_t DIVIDEND, gcry_mpi_t DIVISOR, int ROUND)
+ Q = DIVIDEND / DIVISOR, R = DIVIDEND \bmod DIVISOR. Q and R may
+ be passed as `NULL'. ROUND should be negative or 0.
+
+ -- Function: void gcry_mpi_mod (gcry_mpi_t R, gcry_mpi_t DIVIDEND,
+ gcry_mpi_t DIVISOR)
+ R = DIVIDEND \bmod DIVISOR.
+
+ -- Function: void gcry_mpi_powm (gcry_mpi_t W, const gcry_mpi_t B,
+ const gcry_mpi_t E, const gcry_mpi_t M)
+ W = B^e \bmod M.
+
+ -- Function: int gcry_mpi_gcd (gcry_mpi_t G, gcry_mpi_t A,
+ gcry_mpi_t B)
+ Set G to the greatest common divisor of A and B. Return true if
+ the G is 1.
+
+ -- Function: int gcry_mpi_invm (gcry_mpi_t X, gcry_mpi_t A,
+ gcry_mpi_t M)
+ Set X to the multiplicative inverse of A \bmod M. Return true if
+ the inverse exists.
+
+\1f
+File: gcrypt.info, Node: Comparisons, Next: Bit manipulations, Prev: Calculations, Up: MPI library
+
+11.5 Comparisons
+================
+
+The next 2 functions are used to compare MPIs:
+
+ -- Function: int gcry_mpi_cmp (const gcry_mpi_t U, const gcry_mpi_t V)
+ Compare the multi-precision-integers number U and V returning 0
+ for equality, a positive value for U > V and a negative for U < V.
+ If both numbers are opaque values (cf, gcry_mpi_set_opaque) the
+ comparison is done by checking the bit sizes using memcmp. If
+ only one number is an opaque value, the opaque value is less than
+ the other number.
+
+ -- Function: int gcry_mpi_cmp_ui (const gcry_mpi_t U, unsigned long V)
+ Compare the multi-precision-integers number U with the unsigned
+ integer V returning 0 for equality, a positive value for U > V and
+ a negative for U < V.
+
+\1f
+File: gcrypt.info, Node: Bit manipulations, Next: Miscellaneous, Prev: Comparisons, Up: MPI library
+
+11.6 Bit manipulations
+======================
+
+There are a couple of functions to get information on arbitrary bits in
+an MPI and to set or clear them:
+
+ -- Function: unsigned int gcry_mpi_get_nbits (gcry_mpi_t A)
+ Return the number of bits required to represent A.
+
+ -- Function: int gcry_mpi_test_bit (gcry_mpi_t A, unsigned int N)
+ Return true if bit number N (counting from 0) is set in A.
+
+ -- Function: void gcry_mpi_set_bit (gcry_mpi_t A, unsigned int N)
+ Set bit number N in A.
+
+ -- Function: void gcry_mpi_clear_bit (gcry_mpi_t A, unsigned int N)
+ Clear bit number N in A.
+
+ -- Function: void gcry_mpi_set_highbit (gcry_mpi_t A, unsigned int N)
+ Set bit number N in A and clear all bits greater than N.
+
+ -- Function: void gcry_mpi_clear_highbit (gcry_mpi_t A, unsigned int N)
+ Clear bit number N in A and all bits greater than N.
+
+ -- Function: void gcry_mpi_rshift (gcry_mpi_t X, gcry_mpi_t A,
+ unsigned int N)
+ Shift the value of A by N bits to the right and store the result
+ in X.
+
+ -- Function: void gcry_mpi_lshift (gcry_mpi_t X, gcry_mpi_t A,
+ unsigned int N)
+ Shift the value of A by N bits to the left and store the result in
+ X.
+
+\1f
+File: gcrypt.info, Node: Miscellaneous, Prev: Bit manipulations, Up: MPI library
+
+11.7 Miscellaneous
+==================
+
+ -- Function: gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t A, void *P,
+ unsigned int NBITS)
+ Store NBITS of the value P points to in A and mark A as an opaque
+ value (i.e. an value that can't be used for any math calculation
+ and is only used to store an arbitrary bit pattern in A).
+
+ WARNING: Never use an opaque MPI for actual math operations. The
+ only valid functions are gcry_mpi_get_opaque and gcry_mpi_release.
+ Use gcry_mpi_scan to convert a string of arbitrary bytes into an
+ MPI.
+
+
+ -- Function: void * gcry_mpi_get_opaque (gcry_mpi_t A,
+ unsigned int *NBITS)
+ Return a pointer to an opaque value stored in A and return its
+ size in NBITS. Note that the returned pointer is still owned by A
+ and that the function should never be used for an non-opaque MPI.
+
+ -- Function: void gcry_mpi_set_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+ Set the FLAG for the MPI A. Currently only the flag
+ `GCRYMPI_FLAG_SECURE' is allowed to convert A into an MPI stored
+ in "secure memory".
+
+ -- Function: void gcry_mpi_clear_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+ Clear FLAG for the multi-precision-integers A. Note that this
+ function is currently useless as no flags are allowed.
+
+ -- Function: int gcry_mpi_get_flag (gcry_mpi_t A,
+ enum gcry_mpi_flag FLAG)
+ Return true when the FLAG is set for A.
+
+ -- Function: void gcry_mpi_randomize (gcry_mpi_t W,
+ unsigned int NBITS, enum gcry_random_level LEVEL)
+ Set the multi-precision-integers W to a random value of NBITS,
+ using random data quality of level LEVEL. In case NBITS is not a
+ multiple of a byte, NBITS is rounded up to the next byte boundary.
+ When using a LEVEL of `GCRY_WEAK_RANDOM' this function makes use of
+ `gcry_create_nonce'.
+
+\1f
+File: gcrypt.info, Node: Prime numbers, Next: Utilities, Prev: MPI library, Up: Top
+
+12 Prime numbers
+****************
+
+* Menu:
+
+* Generation:: Generation of new prime numbers.
+* Checking:: Checking if a given number is prime.
+
+\1f
+File: gcrypt.info, Node: Generation, Next: Checking, Up: Prime numbers
+
+12.1 Generation
+===============
+
+ -- Function: gcry_error_t gcry_prime_generate (gcry_mpi_t
+ *PRIME,unsigned int PRIME_BITS, unsigned int FACTOR_BITS,
+ gcry_mpi_t **FACTORS, gcry_prime_check_func_t CB_FUNC, void
+ *CB_ARG, gcry_random_level_t RANDOM_LEVEL, unsigned int FLAGS)
+ Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (PRIME - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, `NULL'-terminated array holding the
+ prime factors and store it in FACTORS. FLAGS might be used to
+ influence the prime number generation process.
+
+ -- Function: gcry_error_t gcry_prime_group_generator (gcry_mpi_t *R_G,
+ gcry_mpi_t PRIME, gcry_mpi_t *FACTORS, gcry_mpi_t START_G)
+ Find a generator for PRIME where the factorization of (PRIME-1) is
+ in the `NULL' terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ the start for the search.
+
+ -- Function: void gcry_prime_release_factors (gcry_mpi_t *FACTORS)
+ Convenience function to release the FACTORS array.
+
+\1f
+File: gcrypt.info, Node: Checking, Prev: Generation, Up: Prime numbers
+
+12.2 Checking
+=============
+
+ -- Function: gcry_error_t gcry_prime_check (gcry_mpi_t P, unsigned int
+ FLAGS)
+ Check wether the number P is prime. Returns zero in case P is
+ indeed a prime, returns `GPG_ERR_NO_PRIME' in case P is not a
+ prime and a different error code in case something went horribly
+ wrong.
+
+\1f
+File: gcrypt.info, Node: Utilities, Next: Architecture, Prev: Prime numbers, Up: Top
+
+13 Utilities
+************
+
+* Menu:
+
+* Memory allocation:: Functions related with memory allocation.
+
+\1f
+File: gcrypt.info, Node: Memory allocation, Up: Utilities
+
+13.1 Memory allocation
+======================
+
+ -- Function: void * gcry_malloc (size_t N)
+ This function tries to allocate N bytes of memory. On success it
+ returns a pointer to the memory area, in an out-of-core condition,
+ it returns NULL.
+
+ -- Function: void * gcry_malloc_secure (size_t N)
+ Like `gcry_malloc', but uses secure memory.
+
+ -- Function: void * gcry_calloc (size_t N, size_t M)
+ This function allocates a cleared block of memory (i.e.
+ initialized with zero bytes) long enough to contain a vector of N
+ elements, each of size M bytes. On success it returns a pointer
+ to the memory block; in an out-of-core condition, it returns NULL.
+
+ -- Function: void * gcry_calloc_secure (size_t N, size_t M)
+ Like `gcry_calloc', but uses secure memory.
+
+ -- Function: void * gcry_realloc (void *P, size_t N)
+ This function tries to resize the memory area pointed to by P to N
+ bytes. On success it returns a pointer to the new memory area, in
+ an out-of-core condition, it returns NULL. Depending on whether
+ the memory pointed to by P is secure memory or not, gcry_realloc
+ tries to use secure memory as well.
+
+ -- Function: void gcry_free (void *P)
+ Release the memory area pointed to by P.
+
+\1f
+File: gcrypt.info, Node: Architecture, Next: Self-Tests, Prev: Utilities, Up: Top
+
+14 Architecture
+***************
+
+This chapter describes the internal architecture of Libgcrypt.
+
+ Libgcrypt is a function library written in ISO C-90. Any compliant
+compiler should be able to build Libgcrypt as long as the target is
+either a POSIX platform or compatible to the API used by Windows NT.
+Provisions have been take so that the library can be directly used from
+C++ applications; however building with a C++ compiler is not supported.
+
+ Building Libgcrypt is done by using the common `./configure && make'
+approach. The configure command is included in the source distribution
+and as a portable shell script it works on any Unix-alike system. The
+result of running the configure script are a C header file
+(`config.h'), customized Makefiles, the setup of symbolic links and a
+few other things. After that the make tool builds and optionally
+installs the library and the documentation. See the files `INSTALL'
+and `README' in the source distribution on how to do this.
+
+ Libgcrypt is developed using a Subversion(1) repository. Although
+all released versions are tagged in this repository, they should not be
+used to build production versions of Libgcrypt. Instead released
+tarballs should be used. These tarballs are available from several
+places with the master copy at <ftp://ftp.gnupg.org/gcrypt/libgcrypt/>.
+Announcements of new releases are posted to the
+<gnupg-announce@gnupg.org> mailing list(2).
+
+ \0\b[image src="libgcrypt-modules.png" alt="Libgcrypt subsystems"\0\b]
+Figure 14.1: Libgcrypt subsystems
+
+ Libgcrypt consists of several subsystems (*note Figure 14.1:
+fig:subsystems.) and all these subsystems provide a public API; this
+includes the helper subsystems like the one for S-expressions. The API
+style depends on the subsystem; in general an open-use-close approach
+is implemented. The open returns a handle to a context used for all
+further operations on this handle, several functions may then be used
+on this handle and a final close function releases all resources
+associated with the handle.
+
+* Menu:
+
+* Public-Key Subsystem Architecture:: About public keys.
+* Symmetric Encryption Subsystem Architecture:: About standard ciphers.
+* Hashing and MACing Subsystem Architecture:: About hashing.
+* Multi-Precision-Integer Subsystem Architecture:: About big integers.
+* Prime-Number-Generator Subsystem Architecture:: About prime numbers.
+* Random-Number Subsystem Architecture:: About random stuff.
+
+ ---------- Footnotes ----------
+
+ (1) A version control system available for many platforms
+
+ (2) See `http://www.gnupg.org/documentation/mailing-lists.en.html'
+for details.
+
+\1f
+File: gcrypt.info, Node: Public-Key Subsystem Architecture, Next: Symmetric Encryption Subsystem Architecture, Up: Architecture
+
+14.1 Public-Key Architecture
+============================
+
+Libgcrypt implements two interfaces for public key cryptography: The
+standard interface is PK interface using functions in the `gcry_pk_'
+name space. The AC interface in an alternative one which is now
+deprecated and will not be further described. The AC interface is also
+disabled in FIPS mode.
+
+ Because public key cryptography is almost always used to process
+small amounts of data (hash values or session keys), the interface is
+not implemented using the open-use-close paradigm, but with single
+self-contained functions. Due to the wide variety of parameters
+required by different algorithms S-expressions, as flexible way to
+convey these parameters, are used. There is a set of helper functions
+to work with these S-expressions.
+
+ Aside of functions to register new algorithms, map algorithms names
+to algorithms identifiers and to lookup properties of a key, the
+following main functions are available:
+
+`gcry_pk_encrypt'
+ Encrypt data using a public key.
+
+`gcry_pk_decrypt'
+ Decrypt data using a private key.
+
+`gcry_pk_sign'
+ Sign data using a private key.
+
+`gcry_pk_verify'
+ Verify that a signature matches the data.
+
+`gcry_pk_testkey'
+ Perform a consistency over a public or private key.
+
+`gcry_pk_genkey'
+ Create a new public/private key pair.
+
+
+ With the help of the module registration system all these functions
+lookup the module implementing the algorithm and pass the actual work
+to that module. The parsing of the S-expression input and the
+construction of S-expression for the return values is done by the high
+level code (`cipher/pubkey.c'). Thus the internal interface between
+the algorithm modules and the high level functions passes data in a
+custom format. The interface to the modules is published
+(`gcrypt-modules.h') so that it can used to register external
+implementations of algorithms with Libgcrypt. However, for some
+algorithms this module interface is to limited and thus for the
+internal modules an extra interface is sometimes used to convey more
+information.
+
+ By default Libgcrypt uses a blinding technique for RSA decryption to
+mitigate real world timing attacks over a network: Instead of using the
+RSA decryption directly, a blinded value y = x r^e \bmod n is decrypted
+and the unblinded value x' = y' r^-1 \bmod n returned. The blinding
+value r is a random value with the size of the modulus n and generated
+with `GCRY_WEAK_RANDOM' random level.
+
+ The algorithm used for RSA and DSA key generation depends on whether
+Libgcrypt is operated in standard or in FIPS mode. In standard mode an
+algorithm based on the Lim-Lee prime number generator is used. In FIPS
+mode RSA keys are generated as specified in ANSI X9.31 (1998) and DSA
+keys as specified in FIPS 186-2.
+
+\1f
+File: gcrypt.info, Node: Symmetric Encryption Subsystem Architecture, Next: Hashing and MACing Subsystem Architecture, Prev: Public-Key Subsystem Architecture, Up: Architecture
+
+14.2 Symmetric Encryption Subsystem Architecture
+================================================
+
+The interface to work with symmetric encryption algorithms is made up
+of functions from the `gcry_cipher_' name space. The implementation
+follows the open-use-close paradigm and uses registered algorithm
+modules for the actual work. Unless a module implements optimized
+cipher mode implementations, the high level code (`cipher/cipher.c')
+implements the modes and calls the core algorithm functions to process
+each block.
+
+ The most important functions are:
+
+`gcry_cipher_open'
+ Create a new instance to encrypt or decrypt using a specified
+ algorithm and mode.
+
+`gcry_cipher_close'
+ Release an instance.
+
+`gcry_cipher_setkey'
+ Set a key to be used for encryption or decryption.
+
+`gcry_cipher_setiv'
+ Set an initialization vector to be used for encryption or
+ decryption.
+
+`gcry_cipher_encrypt'
+`gcry_cipher_decrypt'
+ Encrypt or decrypt data. These functions may be called with
+ arbitrary amounts of data and as often as needed to encrypt or
+ decrypt all data.
+
+
+ There are also functions to query properties of algorithms or
+context, like block length, key length, map names or to enable features
+like padding methods.
+
+\1f
+File: gcrypt.info, Node: Hashing and MACing Subsystem Architecture, Next: Multi-Precision-Integer Subsystem Architecture, Prev: Symmetric Encryption Subsystem Architecture, Up: Architecture
+
+14.3 Hashing and MACing Subsystem Architecture
+==============================================
+
+The interface to work with message digests and CRC algorithms is made
+up of functions from the `gcry_md_' name space. The implementation
+follows the open-use-close paradigm and uses registered algorithm
+modules for the actual work. Although CRC algorithms are not
+considered cryptographic hash algorithms, they share enough properties
+so that it makes sense to handle them in the same way. It is possible
+to use several algorithms at once with one context and thus compute
+them all on the same data.
+
+ The most important functions are:
+
+`gcry_md_open'
+ Create a new message digest instance and optionally enable one
+ algorithm. A flag may be used to turn the message digest algorithm
+ into a HMAC algorithm.
+
+`gcry_md_enable'
+ Enable an additional algorithm for the instance.
+
+`gcry_md_setkey'
+ Set the key for the MAC.
+
+`gcry_md_write'
+ Pass more data for computing the message digest to an instance.
+
+`gcry_md_putc'
+ Buffered version of `gcry_md_write' implemented as a macro.
+
+`gcry_md_read'
+ Finalize the computation of the message digest or HMAC and return
+ the result.
+
+`gcry_md_close'
+ Release an instance
+
+`gcry_md_hash_buffer'
+ Convenience function to directly compute a message digest over a
+ memory buffer without the need to create an instance first.
+
+
+ There are also functions to query properties of algorithms or the
+instance, like enabled algorithms, digest length, map algorithm names.
+it is also possible to reset an instance or to copy the current state
+of an instance at any time. Debug functions to write the hashed data
+to files are available as well.
+
+\1f
+File: gcrypt.info, Node: Multi-Precision-Integer Subsystem Architecture, Next: Prime-Number-Generator Subsystem Architecture, Prev: Hashing and MACing Subsystem Architecture, Up: Architecture
+
+14.4 Multi-Precision-Integer Subsystem Architecture
+===================================================
+
+The implementation of Libgcrypt's big integer computation code is based
+on an old release of GNU Multi-Precision Library (GMP). The decision
+not to use the GMP library directly was due to stalled development at
+that time and due to security requirements which could not be provided
+by the code in GMP. As GMP does, Libgcrypt provides high performance
+assembler implementations of low level code for several CPUS to gain
+much better performance than with a generic C implementation.
+
+Major features of Libgcrypt's multi-precision-integer code compared to
+GMP are:
+
+ * Avoidance of stack based allocations to allow protection against
+ swapping out of sensitive data and for easy zeroing of sensitive
+ intermediate results.
+
+ * Optional use of secure memory and tracking of its use so that
+ results are also put into secure memory.
+
+ * MPIs are identified by a handle (implemented as a pointer) to give
+ better control over allocations and to augment them with extra
+ properties like opaque data.
+
+ * Removal of unnecessary code to reduce complexity.
+
+ * Functions specialized for public key cryptography.
+
+
+\1f
+File: gcrypt.info, Node: Prime-Number-Generator Subsystem Architecture, Next: Random-Number Subsystem Architecture, Prev: Multi-Precision-Integer Subsystem Architecture, Up: Architecture
+
+14.5 Prime-Number-Generator Subsystem Architecture
+==================================================
+
+Libgcrypt provides an interface to its prime number generator. These
+functions make use of the internal prime number generator which is
+required for the generation for public key key pairs. The plain prime
+checking function is exported as well.
+
+ The generation of random prime numbers is based on the Lim and Lee
+algorithm to create practically save primes.(1) This algorithm creates
+a pool of smaller primes, select a few of them to create candidate
+primes of the form 2 * p_0 * p_1 * ... * p_n + 1, tests the candidate
+for primality and permutates the pool until a prime has been found. It
+is possible to clamp one of the small primes to a certain size to help
+DSA style algorithms. Because most of the small primes in the pool are
+not used for the resulting prime number, they are saved for later use
+(see `save_pool_prime' and `get_pool_prime' in `cipher/primegen.c').
+The prime generator optionally supports the finding of an appropriate
+generator.
+
+The primality test works in three steps:
+
+ 1. The standard sieve algorithm using the primes up to 4999 is used
+ as a quick first check.
+
+ 2. A Fermat test filters out almost all non-primes.
+
+ 3. A 5 round Rabin-Miller test is finally used. The first round uses
+ a witness of 2, whereas the next rounds use a random witness.
+
+
+ To support the generation of RSA and DSA keys in FIPS mode according
+to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
+generation functions: `_gcry_derive_x931_prime' and
+`_gcry_generate_fips186_2_prime'. These functions are internal and not
+available through the public API.
+
+ ---------- Footnotes ----------
+
+ (1) Chae Hoon Lim and Pil Joong Lee. A key recovery attack on
+discrete log-based shemes using a prime order subgroup. In Burton S.
+Kaliski Jr., editor, Advances in Cryptology: Crypto '97, pages
+249-263, Berlin / Heidelberg / New York, 1997. Springer-Verlag.
+Described on page 260.
+
+\1f
+File: gcrypt.info, Node: Random-Number Subsystem Architecture, Prev: Prime-Number-Generator Subsystem Architecture, Up: Architecture
+
+14.6 Random-Number Subsystem Architecture
+=========================================
+
+Libgcrypt provides 3 levels or random quality: The level
+`GCRY_VERY_STRONG_RANDOM' usually used for key generation, the level
+`GCRY_STRONG_RANDOM' for all other strong random requirements and the
+function `gcry_create_nonce' which is used for weaker usages like
+nonces. There is also a level `GCRY_WEAK_RANDOM' which in general maps
+to `GCRY_STRONG_RANDOM' except when used with the function
+`gcry_mpi_randomize', where it randomizes an multi-precision-integer
+using the `gcry_create_nonce' function.
+
+There are two distinct random generators available:
+
+ * The Continuously Seeded Pseudo Random Number Generator (CSPRNG),
+ which is based on the classic GnuPG derived big pool
+ implementation. Implemented in `random/random-csprng.c' and used
+ by default.
+
+ * A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key.
+ Implemented in `random/random-fips.c' and used if Libgcrypt is in
+ FIPS mode.
+
+Both generators make use of so-called entropy gathering modules:
+
+rndlinux
+ Uses the operating system provided `/dev/random' and
+ `/dev/urandom' devices.
+
+rndunix
+ Runs several operating system commands to collect entropy from
+ sources like virtual machine and process statistics. It is a kind
+ of poor-man's `/dev/random' implementation. It is not available in
+ FIPS mode.
+
+rndegd
+ Uses the operating system provided Entropy Gathering Daemon (EGD).
+ The EGD basically uses the same algorithms as rndunix does.
+ However as a system daemon it keeps on running and thus can serve
+ several processes requiring entropy input and does not waste
+ collected entropy if the application does not need all the
+ collected entropy. It is not available in FIPS mode.
+
+rndw32
+ Targeted for the Microsoft Windows OS. It uses certain properties
+ of that system and is the only gathering module available for that
+ OS.
+
+rndhw
+ Extra module to collect additional entropy by utilizing a hardware
+ random number generator. As of now the only supported hardware
+ RNG is the Padlock engine of VIA (Centaur) CPUs. It is not
+ available in FIPS mode.
+
+
+* Menu:
+
+* CSPRNG Description:: Description of the CSPRNG.
+* FIPS PRNG Description:: Description of the FIPS X9.31 PRNG.
+
+\1f
+File: gcrypt.info, Node: CSPRNG Description, Next: FIPS PRNG Description, Up: Random-Number Subsystem Architecture
+
+14.6.1 Description of the CSPRNG
+--------------------------------
+
+This random number generator is loosely modelled after the one
+described in Peter Gutmann's paper: "Software Generation of Practically
+Strong Random Numbers".(1)
+
+ A pool of 600 bytes is used and mixed using the core RIPE-MD160 hash
+transform function. Several extra features are used to make the robust
+against a wide variety of attacks and to protect against failures of
+subsystems. The state of the generator may be saved to a file and
+initially seed form a file.
+
+ Depending on how Libgcrypt was build the generator is able to select
+the best working entropy gathering module. It makes use of the slow
+and fast collection methods and requires the pool to initially seeded
+form the slow gatherer or a seed file. An entropy estimation is used
+to mix in enough data from the gather modules before returning the
+actual random output. Process fork detection and protection is
+implemented.
+
+ The implementation of the nonce generator (for `gcry_create_nonce')
+is a straightforward repeated hash design: A 28 byte buffer is
+initially seeded with the PID and the time in seconds in the first 20
+bytes and with 8 bytes of random taken from the `GCRY_STRONG_RANDOM'
+generator. Random numbers are then created by hashing all the 28 bytes
+with SHA-1 and saving that again in the first 20 bytes. The hash is
+also returned as result.
+
+ ---------- Footnotes ----------
+
+ (1) Also described in chapter 6 of his book "Cryptographic Security
+Architecture", New York, 2004, ISBN 0-387-95387-6.
+
+\1f
+File: gcrypt.info, Node: FIPS PRNG Description, Prev: CSPRNG Description, Up: Random-Number Subsystem Architecture
+
+14.6.2 Description of the FIPS X9.31 PRNG
+-----------------------------------------
+
+The core of this deterministic random number generator is implemented
+according to the document "NIST-Recommended Random Number Generator
+Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
+Algorithms", dated 2005-01-31. This implementation uses the AES
+variant.
+
+ The generator is based on contexts to utilize the same core functions
+for all random levels as required by the high-level interface. All
+random generators return their data in 128 bit blocks. If the caller
+requests less bits, the extra bits are not used. The key for each
+generator is only set once at the first time a generator context is
+used. The seed value is set along with the key and again after 1000
+output blocks.
+
+ On Unix like systems the `GCRY_VERY_STRONG_RANDOM' and
+`GCRY_STRONG_RANDOM' generators are keyed and seeded using the rndlinux
+module with the `/dev/radnom' device. Thus these generators may block
+until the OS kernel has collected enough entropy. When used with
+Microsoft Windows the rndw32 module is used instead.
+
+ The generator used for `gcry_create_nonce' is keyed and seeded from
+the `GCRY_STRONG_RANDOM' generator. Thus is may also block if the
+`GCRY_STRONG_RANDOM' generator has not yet been used before and thus
+gets initialized on the first use by `gcry_create_nonce'. This special
+treatment is justified by the weaker requirements for a nonce generator
+and to save precious kernel entropy for use by the "real" random
+generators.
+
+ A self-test facility uses a separate context to check the
+functionality of the core X9.31 functions using a known answers test.
+During runtime each output block is compared to the previous one to
+detect a stucked generator.
+
+ The DT value for the generator is made up of the current time down to
+microseconds (if available) and a free running 64 bit counter. When
+used with the test context the DT value is taken from the context and
+incremented on each use.
+
+\1f
+File: gcrypt.info, Node: Self-Tests, Next: FIPS Mode, Prev: Architecture, Up: Top
+
+Appendix A Description of the Self-Tests
+****************************************
+
+In addition to the build time regression test suite, Libgcrypt
+implements self-tests to be performed at runtime. Which self-tests are
+actually used depends on the mode Libgcrypt is used in. In standard
+mode a limited set of self-tests is run at the time an algorithm is
+first used. Note that not all algorithms feature a self-test in
+standard mode. The `GCRYCTL_SELFTEST' control command may be used to
+run all implemented self-tests at any time; this will even run more
+tests than those run in FIPS mode.
+
+ If any of the self-tests fails, the library immediately returns an
+error code to the caller. If Libgcrypt is in FIPS mode the self-tests
+will be performed within the "Self-Test" state and any failure puts the
+library into the "Error" state.
+
+A.1 Power-Up Tests
+==================
+
+Power-up tests are only performed if Libgcrypt is in FIPS mode.
+
+A.1.1 Symmetric Cipher Algorithm Power-Up Tests
+-----------------------------------------------
+
+The following symmetric encryption algorithm tests are run during
+power-up:
+
+3DES
+ To test the 3DES 3-key EDE encryption in ECB mode these tests are
+ run:
+ 1. A known answer test is run on a 64 bit test vector processed
+ by 64 rounds of Single-DES block encryption and decryption
+ using a key changed with each round.
+
+ 2. A known answer test is run on a 64 bit test vector processed
+ by 16 rounds of 2-key and 3-key Triple-DES block encryption
+ and decryptions using a key changed with each round.
+
+ 3. 10 known answer tests using 3-key Triple-DES EDE encryption,
+ comparing the ciphertext to the known value, then running a
+ decryption and comparing it to the initial plaintext.
+ (`cipher/des.c:selftest')
+
+AES-128
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_128')
+
+AES-192
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_192')
+
+AES-256
+ A known answer tests is run using one test vector and one test key
+ with AES in ECB mode. (`cipher/rijndael.c:selftest_basic_256')
+
+A.1.2 Hash Algorithm Power-Up Tests
+-----------------------------------
+
+The following hash algorithm tests are run during power-up:
+
+SHA-1
+ A known answer test using the string `"abc"' is run.
+ (`cipher/sha1.c:selftests_sha1')
+
+SHA-224
+ A known answer test using the string `"abc"' is run.
+ (`cipher/sha256.c:selftests_sha224')
+
+SHA-256
+ A known answer test using the string `"abc"' is run.
+ (`cipher/sha256.c:selftests_sha256')
+
+SHA-384
+ A known answer test using the string `"abc"' is run.
+ (`cipher/sha512.c:selftests_sha384')
+
+SHA-512
+ A known answer test using the string `"abc"' is run.
+ (`cipher/sha512.c:selftests_sha512')
+
+A.1.3 MAC Algorithm Power-Up Tests
+----------------------------------
+
+The following MAC algorithm tests are run during power-up:
+
+HMAC SHA-1
+ A known answer test using 9 byte of data and a 64 byte key is run.
+ (`cipher/hmac-tests.c:selftests_sha1')
+
+HMAC SHA-224
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ (`cipher/hmac-tests.c:selftests_sha224')
+
+HMAC SHA-256
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ (`cipher/hmac-tests.c:selftests_sha256')
+
+HMAC SHA-384
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ (`cipher/hmac-tests.c:selftests_sha384')
+
+HMAC SHA-512
+ A known answer test using 28 byte of data and a 4 byte key is run.
+ (`cipher/hmac-tests.c:selftests_sha512')
+
+A.1.4 Random Number Power-Up Test
+---------------------------------
+
+The DRNG is tested during power-up this way:
+
+ 1. Requesting one block of random using the public interface to check
+ general working and the duplicated block detection.
+
+ 2. 3 know answer tests using pre-defined keys, seed and initial DT
+ values. For each test 3 blocks of 16 bytes are requested and
+ compared to the expected result. The DT value is incremented for
+ each block.
+
+A.1.5 Public Key Algorithm Power-Up Tests
+-----------------------------------------
+
+The public key algorithms are tested during power-up:
+
+RSA
+ A pre-defined 1024 bit RSA key is used and these tests are run in
+ turn:
+ 1. Conversion of S-expression to internal format.
+ (`cipher/rsa.c:selftests_rsa')
+
+ 2. Private key consistency check. (`cipher/rsa.c:selftests_rsa')
+
+ 3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+ SHA-1. The result is verified using the public key against
+ the original data and against modified data.
+ (`cipher/rsa.c:selftest_sign_1024')
+
+ 4. A 1000 bit random value is encrypted and checked that it does
+ not match the orginal random value. The encrtypted result is
+ then decrypted and checked that it macthes the original
+ random value. (`cipher/rsa.c:selftest_encr_1024')
+
+DSA
+ A pre-defined 1024 bit DSA key is used and these tests are run in
+ turn:
+ 1. Conversion of S-expression to internal format.
+ (`cipher/dsa.c:selftests_dsa')
+
+ 2. Private key consistency check. (`cipher/dsa.c:selftests_dsa')
+
+ 3. A pre-defined 20 byte value is signed with PKCS#1 padding for
+ SHA-1. The result is verified using the public key against
+ the original data and against modified data.
+ (`cipher/dsa.c:selftest_sign_1024')
+
+A.1.6 Integrity Power-Up Tests
+------------------------------
+
+The integrity of the Libgcrypt is tested during power-up but only if
+checking has been enabled at build time. The check works by computing
+a HMAC SHA-256 checksum over the file used to load Libgcrypt into
+memory. That checksum is compared against a checksum stored in a file
+of the same name but with a single dot as a prefix and a suffix of
+`.hmac'.
+
+A.1.7 Critical Functions Power-Up Tests
+---------------------------------------
+
+The 3DES weak key detection is tested during power-up by calling the
+detection function with keys taken from a table listening all weak
+keys. The table itself is protected using a SHA-1 hash.
+(`cipher/des.c:selftest')
+
+A.2 Conditional Tests
+=====================
+
+The conditional tests are performed if a certain contidion is met.
+This may occur at any time; the library does not necessary enter the
+"Self-Test" state to run these tests but will transit to the "Error"
+state if a test failed.
+
+A.2.1 Key-Pair Generation Tests
+-------------------------------
+
+After an asymmetric key-pair has been generated, Libgcrypt runs a
+pair-wise consistency tests on the generated key. On failure the
+generated key is not used, an error code is returned and, if in FIPS
+mode, the library is put into the "Error" state.
+
+RSA
+ The test uses a random number 64 bits less the size of the modulus
+ as plaintext and runs an encryption and decryption operation in
+ turn. The encrypted value is checked to not match the plaintext
+ and the result of the decryption is checked to match the plaintext.
+
+ A new random number of the same size is generated, signed and
+ verified to test the correctness of the signing operation. As a
+ second signing test, the signature is modified by incrementing its
+ value and then verified with the expected result that the
+ verification fails. (`cipher/rsa.c:test_keys')
+
+DSA
+ The test uses a random number of the size of the Q parameter to
+ create a signature and then checks that the signature verifies.
+ As a second signing test, the data is modified by incrementing its
+ value and then verified against the signature with the expected
+ result that the verification fails. (`cipher/dsa.c:test_keys')
+
+A.2.2 Software Load Tests
+-------------------------
+
+Loading of extra modules into libgcrypt is disabled in FIPS mode and
+thus no tests are implemented. (`cipher/cipher.c:_gcry_cipher_register',
+`cipher/md.c:_gcry_md_register', `cipher/pubkey.c:_gcry_pk_register')
+
+A.2.3 Manual Key Entry Tests
+----------------------------
+
+A manual key entry feature is not implemented in Libgcrypt.
+
+A.2.4 Continuous RNG Tests
+--------------------------
+
+The continuous random number test is only used in FIPS mode. The RNG
+generates blocks of 128 bit size; the first block generated per context
+is saved in the context and another block is generated to be returned
+to the caller. Each block is compared against the saved block and then
+stored in the context. If a duplicated block is detected an error is
+signaled and the library is put into the "Fatal-Error" state.
+(`random/random-fips.c:x931_aes_driver')
+
+A.3 Application Requested Tests
+===============================
+
+The application may requests tests at any time by means of the
+`GCRYCTL_SELFTEST' control command. Note that using these tests is not
+FIPS conform: Although Libgcrypt rejects all application requests for
+services while running self-tests, it does not ensure that no other
+operations of Libgcrypt are still being executed. Thus, in FIPS mode
+an application requesting self-tests needs to power-cycle Libgcrypt
+instead.
+
+ When self-tests are requested, Libgcrypt runs all the tests it does
+during power-up as well as a few extra checks as described below.
+
+A.3.1 Symmetric Cipher Algorithm Tests
+--------------------------------------
+
+The following symmetric encryption algorithm tests are run in addition
+to the power-up tests:
+
+AES-128
+ A known answer tests with test vectors taken from NIST SP800-38a
+ and using the high level functions is run for block modes CFB and
+ OFB.
+
+
+A.3.2 Hash Algorithm Tests
+--------------------------
+
+The following hash algorithm tests are run in addition to the power-up
+tests:
+
+SHA-1
+SHA-224
+SHA-256
+ 1. A known answer test using a 56 byte string is run.
+
+ 2. A known answer test using a string of one million letters "a"
+ is run.
+ (`cipher/sha1.c:selftests_sha1',
+ `cipher/sha256.c:selftests_sha224',
+ `cipher/sha256.c:selftests_sha256')
+
+SHA-384
+
+SHA-512
+ 1. A known answer test using a 112 byte string is run.
+
+ 2. A known answer test using a string of one million letters "a"
+ is run.
+ (`cipher/sha512.c:selftests_sha384',
+ `cipher/sha512.c:selftests_sha512')
+
+A.3.3 MAC Algorithm Tests
+-------------------------
+
+The following MAC algorithm tests are run in addition to the power-up
+tests:
+
+HMAC SHA-1
+ 1. A known answer test using 9 byte of data and a 20 byte key is
+ run.
+
+ 2. A known answer test using 9 byte of data and a 100 byte key
+ is run.
+
+ 3. A known answer test using 9 byte of data and a 49 byte key is
+ run.
+ (`cipher/hmac-tests.c:selftests_sha1')
+
+HMAC SHA-224
+HMAC SHA-256
+HMAC SHA-384
+HMAC SHA-512
+ 1. A known answer test using 9 byte of data and a 20 byte key is
+ run.
+
+ 2. A known answer test using 50 byte of data and a 20 byte key
+ is run.
+
+ 3. A known answer test using 50 byte of data and a 26 byte key
+ is run.
+
+ 4. A known answer test using 54 byte of data and a 131 byte key
+ is run.
+
+ 5. A known answer test using 152 byte of data and a 131 byte key
+ is run.
+ (`cipher/hmac-tests.c:selftests_sha224',
+ `cipher/hmac-tests.c:selftests_sha256',
+ `cipher/hmac-tests.c:selftests_sha384',
+ `cipher/hmac-tests.c:selftests_sha512')
+
+\1f
+File: gcrypt.info, Node: FIPS Mode, Next: Library Copying, Prev: Self-Tests, Up: Top
+
+Appendix B Description of the FIPS Mode
+***************************************
+
+This appendix gives detailed information pertaining to the FIPS mode.
+In particular, the changes to the standard mode and the finite state
+machine are described. The self-tests required in this mode are
+described in the appendix on self-tests.
+
+B.1 Restrictions in FIPS Mode
+=============================
+
+If Libgcrypt is used in FIPS mode these restrictions are effective:
+
+ * The cryptographic algorithms are restricted to this list:
+
+ GCRY_CIPHER_3DES
+ 3 key EDE Triple-DES symmetric encryption.
+
+ GCRY_CIPHER_AES128
+ AES 128 bit symmetric encryption.
+
+ GCRY_CIPHER_AES192
+ AES 192 bit symmetric encryption.
+
+ GCRY_CIPHER_AES256
+ AES 256 bit symmetric encryption.
+
+ GCRY_MD_SHA1
+ SHA-1 message digest.
+
+ GCRY_MD_SHA224
+ SHA-224 message digest.
+
+ GCRY_MD_SHA256
+ SHA-256 message digest.
+
+ GCRY_MD_SHA384
+ SHA-384 message digest.
+
+ GCRY_MD_SHA512
+ SHA-512 message digest.
+
+ GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-1 message digest.
+
+ GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-224 message digest.
+
+ GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-256 message digest.
+
+ GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-384 message digest.
+
+ GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
+ HMAC using a SHA-512 message digest.
+
+ GCRY_PK_RSA
+ RSA encryption and signing.
+
+ GCRY_PK_DSA
+ DSA signing.
+
+ Note that the CRC algorithms are not considered cryptographic
+ algorithms and thus are in addition available.
+
+ * RSA key generation refuses to create a key with a keysize of less
+ than 1024 bits.
+
+ * DSA key generation refuses to create a key with a keysize other
+ than 1024 bits.
+
+ * The `transient-key' flag for RSA and DSA key generation is ignored.
+
+ * Support for the VIA Padlock engine is disabled.
+
+ * FIPS mode may only be used on systems with a /dev/random device.
+ Switching into FIPS mode on other systems will fail at runtime.
+
+ * Saving and loading a random seed file is ignored.
+
+ * An X9.31 style random number generator is used in place of the
+ large-pool-CSPRNG generator.
+
+ * The command `GCRYCTL_ENABLE_QUICK_RANDOM' is ignored.
+
+ * The Alternative Public Key Interface (`gcry_ac_xxx') is not
+ supported and all API calls return an error.
+
+ * Registration of external modules is not supported.
+
+ * Message digest debugging is disabled.
+
+ * All debug output related to cryptographic data is suppressed.
+
+ * On-the-fly self-tests are not performed, instead self-tests are run
+ before entering operational state.
+
+ * The function `gcry_set_allocation_handler' may not be used. If it
+ is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
+ enabled, in which case Libgcrypt will enter the error state.
+
+ * The digest algorithm MD5 may not be used. If it is used Libgcrypt
+ disables FIPS mode unless Enforced FIPS mode is enabled, in which
+ case Libgcrypt will enter the error state.
+
+ * In Enforced FIPS mode the command `GCRYCTL_DISABLE_SECMEM' is
+ ignored. In standard FIPS mode it disables FIPS mode.
+
+ * A handler set by `gcry_set_outofcore_handler' is ignored.
+
+ * A handler set by `gcry_set_fatalerror_handler' is ignored.
+
+
+ Note that when we speak about disabling FIPS mode, it merely means
+that the function `gcry_fips_mode_active' returns false; it does not
+mean that any non FIPS algorithms are allowed.
+
+B.2 FIPS Finite State Machine
+=============================
+
+The FIPS mode of libgcrypt implements a finite state machine (FSM) using
+8 states (*note tbl:fips-states::) and checks at runtime that only valid
+transitions (*note tbl:fips-state-transitions::) may happen.
+
+ \0\b[image src="fips-fsm.png" alt="FIPS FSM Diagram"\0\b]
+Figure B.1: FIPS mode state diagram
+
+States used by the FIPS FSM:
+Power-Off
+ Libgcrypt is not runtime linked to another application. This
+ usually means that the library is not loaded into main memory.
+ This state is documentation only.
+
+Power-On
+ Libgcrypt is loaded into memory and API calls may be made.
+ Compiler introducted constructor functions may be run. Note that
+ Libgcrypt does not implement any arbitrary constructor functions
+ to be called by the operating system
+
+Init
+ The Libgcrypt initialization functions are performed and the
+ library has not yet run any self-test.
+
+Self-Test
+ Libgcrypt is performing self-tests.
+
+Operational
+ Libgcrypt is in the operational state and all interfaces may be
+ used.
+
+Error
+ Libgrypt is in the error state. When calling any FIPS relevant
+ interfaces they either return an error (`GPG_ERR_NOT_OPERATIONAL')
+ or put Libgcrypt into the Fatal-Error state and won't return.
+
+Fatal-Error
+ Libgcrypt is in a non-recoverable error state and will
+ automatically transit into the Shutdown state.
+
+Shutdown
+ Libgcrypt is about to be terminated and removed from the memory.
+ The application may at this point still runing cleanup handlers.
+
+
+Table B.1: FIPS mode states
+
+The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
+`1'
+ Power-Off to Power-On is implicitly done by the OS loading
+ Libgcrypt as a shared library and having it linked to an
+ application.
+
+`2'
+ Power-On to Init is triggered by the application calling the
+ Libgcrypt intialization function `gcry_check_version'.
+
+`3'
+ Init to Self-Test is either triggred by a dedicated API call or
+ implicit by invoking a libgrypt service conrolled by the FSM.
+
+`4'
+ Self-Test to Operational is triggered after all self-tests passed
+ successfully.
+
+`5'
+ Operational to Shutdown is an artifical state without any direct
+ action in Libgcrypt. When reaching the Shutdown state the library
+ is deinitialized and can't return to any other state again.
+
+`6'
+ Shutdown to Power-off is the process of removing Libgcrypt from the
+ computer's memory. For obvious reasons the Power-Off state can't
+ be represented within Libgcrypt and thus this transition is for
+ documentation only.
+
+`7'
+ Operational to Error is triggered if Libgcrypt detected an
+ application error which can't be returned to the caller but still
+ allows Libgcrypt to properly run. In the Error state all FIPS
+ relevant interfaces return an error code.
+
+`8'
+ Error to Shutdown is similar to the Operational to Shutdown
+ transition (5).
+
+`9'
+ Error to Fatal-Error is triggred if Libgrypt detects an fatal error
+ while already being in Error state.
+
+`10'
+ Fatal-Error to Shutdown is automatically entered by Libgcrypt
+ after having reported the error.
+
+`11'
+ Power-On to Shutdown is an artifical state to document that
+ Libgcrypt has not ye been initializaed but the process is about to
+ terminate.
+
+`12'
+ Power-On to Fatal-Error will be triggerd if certain Libgcrypt
+ functions are used without having reached the Init state.
+
+`13'
+ Self-Test to Fatal-Error is triggred by severe errors in Libgcrypt
+ while running self-tests.
+
+`14'
+ Self-Test to Error is triggred by a failed self-test.
+
+`15'
+ Operational to Fatal-Error is triggered if Libcrypt encountered a
+ non-recoverable error.
+
+`16'
+ Operational to Self-Test is triggred if the application requested
+ to run the self-tests again.
+
+`17'
+ Error to Self-Test is triggered if the application has requested
+ to run self-tests to get to get back into operational state after
+ an error.
+
+`18'
+ Init to Error is triggered by errors in the initialization code.
+
+`19'
+ Init to Fatal-Error is triggered by non-recoverable errors in the
+ initialization code.
+
+`20'
+ Error to Error is triggered by errors while already in the Error
+ state.
+
+
+Table B.2: FIPS mode state transitions
+
+B.3 FIPS Miscellaneous Information
+==================================
+
+Libgcrypt does not do any key management on itself; the application
+needs to care about it. Keys which are passed to Libgcrypt should be
+allocated in secure memory as available with the functions
+`gcry_malloc_secure' and `gcry_calloc_secure'. By calling `gcry_free'
+on this memory, the memory and thus the keys are overwritten with zero
+bytes before releasing the memory.
+
+ For use with the random number generator, Libgcrypt generates 3
+internal keys which are stored in the encryption contexts used by the
+RNG. These keys are stored in secure memory for the lifetime of the
+process. Application are required to use `GCRYCTL_TERM_SECMEM' before
+process termination. This will zero out the entire secure memory and
+thus also the encryption contexts with these keys.
+
+\1f
+File: gcrypt.info, Node: Library Copying, Next: Copying, Prev: FIPS Mode, Up: Top
+
+GNU Lesser General Public License
+*********************************
+
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 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 Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence the
+ version number 2.1.]
+
+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 Lesser General Public License, applies to some
+specially designated software--typically libraries--of the Free
+Software Foundation and other authors who decide to use it. You can use
+it too, but we suggest you first think carefully about whether this
+license or the ordinary General Public License is the better strategy to
+use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of it
+in new free programs; and that you are informed that you can do these
+things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+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 other code 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.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know that
+what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and is
+quite different from the ordinary General Public License. We use this
+license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does _Less_ to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of free
+software. For example, permission to use the GNU C Library in non-free
+programs enables many more people to use the whole GNU operating
+system, as well as its variant, the GNU/Linux operating system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run that
+program using a modified version of the Library.
+
+ 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, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 0. This License Agreement applies to any software library or other
+ program which contains a notice placed by the copyright holder or
+ other authorized party saying it may be distributed under the
+ terms of this Lesser 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 combine 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. Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run
+ time a copy of the library already present on the user's
+ computer system, rather than copying library functions into
+ the executable, and (2) will operate properly with a modified
+ version of the library, if the user installs one, as long as
+ the modified version is interface-compatible with the version
+ that the work was made with.
+
+ c. 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.
+
+ d. 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.
+
+ e. 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 materials to be 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 with 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 Lesser 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
+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 AN 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 Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser 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!
+
+\1f
+File: gcrypt.info, Node: Copying, Next: Figures and Tables, Prev: Library Copying, Up: Top
+
+GNU General Public License
+**************************
+
+ Version 2, June 1991
+
+ Copyright (C) 1989, 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.
+
+Preamble
+========
+
+The licenses for most software are designed to take away your freedom
+to share and change it. By contrast, the GNU General Public License is
+intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, 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 software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software,
+and (2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+ 1. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program",
+ below, refers to any such program or work, and a "work based on
+ the Program" means either the Program or any derivative work under
+ copyright law: that is to say, a work containing the Program or a
+ portion of it, either verbatim or with modifications and/or
+ translated into another language. (Hereinafter, translation is
+ included without limitation in the term "modification".) Each
+ licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are
+ not covered by this License; they are outside its scope. The act
+ of running the Program is not restricted, and the output from the
+ Program is covered only if its contents constitute a work based on
+ the Program (independent of having been made by running the
+ Program). Whether that is true depends on what the Program does.
+
+ 2. You may copy and distribute verbatim copies of the Program's
+ 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 give any other recipients of the Program a copy of
+ this License along with the Program.
+
+ 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.
+
+ 3. You may modify your copy or copies of the Program or any portion
+ of it, thus forming a work based on the Program, 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. You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b. You must cause any work that you distribute or publish, that
+ in whole or in part contains or is derived from the Program
+ or any part thereof, to be licensed as a whole at no charge
+ to all third parties under the terms of this License.
+
+ c. If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display
+ an announcement including an appropriate copyright notice and
+ a notice that there is no warranty (or else, saying that you
+ provide a warranty) and that users may redistribute the
+ program under these conditions, and telling the user how to
+ view a copy of this License. (Exception: if the Program
+ itself is interactive but does not normally print such an
+ announcement, your work based on the Program is not required
+ to print an announcement.)
+
+ These requirements apply to the modified work as a whole. If
+ identifiable sections of that work are not derived from the
+ Program, 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 Program, 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 Program.
+
+ In addition, mere aggregation of another work not based on the
+ Program with the Program (or with a work based on the Program) on
+ a volume of a storage or distribution medium does not bring the
+ other work under the scope of this License.
+
+ 4. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms
+ of Sections 1 and 2 above provided that you also do one of the
+ following:
+
+ a. 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; or,
+
+ b. Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a
+ medium customarily used for software interchange; or,
+
+ c. Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with
+ such an offer, in accord with Subsection b above.)
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, 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 executable.
+ 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.
+
+ If distribution of executable or 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 counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 5. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program 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.
+
+ 6. 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 Program or its derivative works. These actions
+ are prohibited by law if you do not accept this License.
+ Therefore, by modifying or distributing the Program (or any work
+ based on the Program), you indicate your acceptance of this
+ License to do so, and all its terms and conditions for copying,
+ distributing or modifying the Program or works based on it.
+
+ 7. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program
+ 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.
+
+ 8. 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
+ Program at all. For example, if a patent license would not permit
+ royalty-free redistribution of the Program 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 Program.
+
+ 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.
+
+ 9. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces,
+ the original copyright holder who places the Program 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.
+
+ 10. The Free Software Foundation may publish revised and/or new
+ versions of the 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
+ Program 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 Program
+ does not specify a version number of this License, you may choose
+ any version ever published by the Free Software Foundation.
+
+ 11. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, 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
+ 12. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+ WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
+ LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
+ SERVICING, REPAIR OR CORRECTION.
+
+ 13. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY
+ OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+How to Apply These Terms to Your New Programs
+=============================================
+
+If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+ To do so, attach the following notices to the program. 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 PROGRAM'S NAME AND AN IDEA OF WHAT IT DOES.
+ Copyright (C) 19YY NAME OF AUTHOR
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; 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.
+
+ If the program is interactive, make it output a short notice like
+this when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19YY NAME OF AUTHOR
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+ type `show w'. This is free software, and you are welcome
+ to redistribute it under certain conditions; type `show c'
+ for details.
+
+ The hypothetical commands `show w' and `show c' should show the
+appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than `show w' and `show
+c'; they could even be mouse-clicks or menu items--whatever suits your
+program.
+
+ You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the program,
+if necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright
+ interest in the program `Gnomovision'
+ (which makes passes at compilers) written
+ by James Hacker.
+
+ SIGNATURE OF TY COON, 1 April 1989
+ Ty Coon, President of Vice
+
+ This General Public License does not permit incorporating your
+program into proprietary programs. If your program is a subroutine
+library, you may consider it more useful to permit linking proprietary
+applications with the library. If this is what you want to do, use the
+GNU Library General Public License instead of this License.
+
+\1f
+File: gcrypt.info, Node: Figures and Tables, Next: Concept Index, Prev: Copying, Up: Top
+
+List of Figures and Tables
+**************************
+
+* Menu:
+
+* Figure 14.1: Libgcrypt subsystems: fig:subsystems.
+* Figure B.1: FIPS mode state ...: fig:fips-fsm.
+
+* Menu:
+
+* Table B.1: FIPS mode states: tbl:fips-states.
+* Table B.2: FIPS mode state ...: tbl:fips-state-transitions.
+
+\1f
+File: gcrypt.info, Node: Concept Index, Next: Function and Data Index, Prev: Figures and Tables, Up: Top
+
+Concept Index
+*************
+
+\0\b[index\0\b]
+* Menu:
+
+* 3DES: Available ciphers. (line 16)
+* Advanced Encryption Standard: Available ciphers. (line 37)
+* AES: Available ciphers. (line 37)
+* AES-Wrap mode: Available cipher modes.
+ (line 32)
+* Arcfour: Available ciphers. (line 54)
+* Blowfish: Available ciphers. (line 24)
+* Camellia: Available ciphers. (line 81)
+* CAST5: Available ciphers. (line 21)
+* CBC, Cipher Block Chaining mode: Available cipher modes.
+ (line 20)
+* CBC-MAC: Working with cipher handles.
+ (line 52)
+* CFB, Cipher Feedback mode: Available cipher modes.
+ (line 16)
+* cipher text stealing: Working with cipher handles.
+ (line 45)
+* CRC32: Available hash algorithms.
+ (line 6)
+* CTR, Counter mode: Available cipher modes.
+ (line 29)
+* DES: Available ciphers. (line 59)
+* DES-EDE: Available ciphers. (line 16)
+* Digital Encryption Standard: Available ciphers. (line 16)
+* ECB, Electronic Codebook mode: Available cipher modes.
+ (line 13)
+* Enforced FIPS mode: Enabling FIPS mode. (line 30)
+* error codes: Error Values. (line 6)
+* error codes, list of <1>: Error Codes. (line 6)
+* error codes, list of: Error Sources. (line 6)
+* error codes, printing of: Error Strings. (line 6)
+* error sources: Error Values. (line 6)
+* error sources, printing of: Error Strings. (line 6)
+* error strings: Error Strings. (line 6)
+* error values: Error Values. (line 6)
+* error values, printing of: Error Strings. (line 6)
+* FIPS 140: Enabling FIPS mode. (line 6)
+* FIPS 186 <1>: Public-Key Subsystem Architecture.
+ (line 63)
+* FIPS 186: General public-key related Functions.
+ (line 257)
+* FIPS mode: Enabling FIPS mode. (line 6)
+* GPL, GNU General Public License: Copying. (line 6)
+* HAVAL: Available hash algorithms.
+ (line 6)
+* HMAC: Working with hash algorithms.
+ (line 27)
+* IDEA: Available ciphers. (line 11)
+* LGPL, GNU Lesser General Public License: Library Copying. (line 6)
+* MD2, MD4, MD5: Available hash algorithms.
+ (line 6)
+* OFB, Output Feedback mode: Available cipher modes.
+ (line 26)
+* RC2: Available ciphers. (line 71)
+* RC4: Available ciphers. (line 54)
+* rfc-2268: Available ciphers. (line 71)
+* Rijndael: Available ciphers. (line 37)
+* RIPE-MD-160: Available hash algorithms.
+ (line 6)
+* Seed (cipher): Available ciphers. (line 76)
+* Serpent: Available ciphers. (line 67)
+* SHA-1: Available hash algorithms.
+ (line 6)
+* SHA-224, SHA-256, SHA-384, SHA-512: Available hash algorithms.
+ (line 6)
+* sync mode (OpenPGP): Working with cipher handles.
+ (line 40)
+* TIGER, TIGER1, TIGER2: Available hash algorithms.
+ (line 6)
+* Triple-DES: Available ciphers. (line 16)
+* Twofish: Available ciphers. (line 48)
+* Whirlpool: Available hash algorithms.
+ (line 6)
+* X9.31 <1>: Public-Key Subsystem Architecture.
+ (line 63)
+* X9.31: General public-key related Functions.
+ (line 250)
+
+\1f
+File: gcrypt.info, Node: Function and Data Index, Prev: Concept Index, Up: Top
+
+Function and Data Index
+***********************
+
+\0\b[index\0\b]
+* Menu:
+
+* AM_PATH_LIBGCRYPT: Building sources using Automake.
+ (line 13)
+* gcry_ac_close: Working with handles.
+ (line 21)
+* gcry_ac_data_clear: Working with sets of data.
+ (line 75)
+* gcry_ac_data_copy: Working with sets of data.
+ (line 53)
+* gcry_ac_data_decode: Using cryptographic functions.
+ (line 100)
+* gcry_ac_data_decrypt: Using cryptographic functions.
+ (line 40)
+* gcry_ac_data_decrypt_scheme: Using cryptographic functions.
+ (line 137)
+* gcry_ac_data_destroy: Working with sets of data.
+ (line 41)
+* gcry_ac_data_encode: Using cryptographic functions.
+ (line 93)
+* gcry_ac_data_encrypt: Using cryptographic functions.
+ (line 33)
+* gcry_ac_data_encrypt_scheme: Using cryptographic functions.
+ (line 127)
+* gcry_ac_data_from_sexp: Working with sets of data.
+ (line 93)
+* gcry_ac_data_get_index: Working with sets of data.
+ (line 69)
+* gcry_ac_data_get_name: Working with sets of data.
+ (line 61)
+* gcry_ac_data_length: Working with sets of data.
+ (line 57)
+* gcry_ac_data_new: Working with sets of data.
+ (line 38)
+* gcry_ac_data_set: Working with sets of data.
+ (line 45)
+* gcry_ac_data_sign: Using cryptographic functions.
+ (line 48)
+* gcry_ac_data_sign_scheme: Using cryptographic functions.
+ (line 147)
+* gcry_ac_data_t: Working with sets of data.
+ (line 20)
+* gcry_ac_data_to_sexp: Working with sets of data.
+ (line 79)
+* gcry_ac_data_verify: Using cryptographic functions.
+ (line 54)
+* gcry_ac_data_verify_scheme: Using cryptographic functions.
+ (line 157)
+* gcry_ac_id_t: Available asymmetric algorithms.
+ (line 11)
+* gcry_ac_id_to_name: Handle-independent functions.
+ (line 10)
+* gcry_ac_io_init: Working with IO objects.
+ (line 22)
+* gcry_ac_io_init_va: Working with IO objects.
+ (line 28)
+* gcry_ac_io_t: Working with IO objects.
+ (line 10)
+* gcry_ac_key_data_get: Working with keys. (line 93)
+* gcry_ac_key_destroy: Working with keys. (line 86)
+* gcry_ac_key_get_grip: Working with keys. (line 105)
+* gcry_ac_key_get_nbits: Working with keys. (line 101)
+* gcry_ac_key_init: Working with keys. (line 30)
+* gcry_ac_key_pair_destroy: Working with keys. (line 90)
+* gcry_ac_key_pair_extract: Working with keys. (line 83)
+* gcry_ac_key_pair_generate: Working with keys. (line 36)
+* gcry_ac_key_pair_t: Working with keys. (line 20)
+* gcry_ac_key_t: Working with keys. (line 16)
+* gcry_ac_key_test: Working with keys. (line 97)
+* gcry_ac_key_type_t: Working with keys. (line 7)
+* gcry_ac_name_to_id: Handle-independent functions.
+ (line 15)
+* gcry_ac_open: Working with handles.
+ (line 11)
+* gcry_calloc: Memory allocation. (line 15)
+* gcry_calloc_secure: Memory allocation. (line 21)
+* gcry_check_version: Initializing the library.
+ (line 17)
+* gcry_cipher_algo_info: General cipher functions.
+ (line 12)
+* gcry_cipher_algo_name: General cipher functions.
+ (line 39)
+* gcry_cipher_close: Working with cipher handles.
+ (line 59)
+* gcry_cipher_ctl: Working with cipher handles.
+ (line 159)
+* gcry_cipher_decrypt: Working with cipher handles.
+ (line 129)
+* gcry_cipher_decrypt_t: Cipher modules. (line 80)
+* gcry_cipher_encrypt: Working with cipher handles.
+ (line 110)
+* gcry_cipher_encrypt_t: Cipher modules. (line 75)
+* gcry_cipher_info: Working with cipher handles.
+ (line 168)
+* gcry_cipher_list: Cipher modules. (line 108)
+* gcry_cipher_map_name: General cipher functions.
+ (line 45)
+* gcry_cipher_mode_from_oid: General cipher functions.
+ (line 50)
+* gcry_cipher_oid_spec_t: Cipher modules. (line 60)
+* gcry_cipher_open: Working with cipher handles.
+ (line 11)
+* gcry_cipher_register: Cipher modules. (line 96)
+* gcry_cipher_reset: Working with cipher handles.
+ (line 97)
+* gcry_cipher_setctr: Working with cipher handles.
+ (line 90)
+* gcry_cipher_setiv: Working with cipher handles.
+ (line 83)
+* gcry_cipher_setkey: Working with cipher handles.
+ (line 68)
+* gcry_cipher_setkey_t: Cipher modules. (line 70)
+* gcry_cipher_spec_t: Cipher modules. (line 12)
+* gcry_cipher_stdecrypt_t: Cipher modules. (line 90)
+* gcry_cipher_stencrypt_t: Cipher modules. (line 85)
+* gcry_cipher_sync: Working with cipher handles.
+ (line 149)
+* gcry_cipher_unregister: Cipher modules. (line 103)
+* gcry_control: Controlling the library.
+ (line 7)
+* gcry_create_nonce: Retrieving random numbers.
+ (line 26)
+* gcry_err_code: Error Values. (line 43)
+* gcry_err_code_from_errno: Error Values. (line 95)
+* gcry_err_code_t: Error Values. (line 7)
+* gcry_err_code_to_errno: Error Values. (line 100)
+* gcry_err_make: Error Values. (line 57)
+* gcry_err_make_from_errno: Error Values. (line 81)
+* gcry_err_source: Error Values. (line 49)
+* gcry_err_source_t: Error Values. (line 14)
+* gcry_error: Error Values. (line 64)
+* gcry_error_from_errno: Error Values. (line 86)
+* gcry_error_t: Error Values. (line 25)
+* gcry_fips_mode_active: Controlling the library.
+ (line 221)
+* gcry_free: Memory allocation. (line 31)
+* gcry_handler_alloc_t: Allocation handler. (line 12)
+* gcry_handler_error_t: Error handler. (line 27)
+* gcry_handler_free_t: Allocation handler. (line 24)
+* gcry_handler_log_t: Logging handler. (line 7)
+* gcry_handler_no_mem_t: Error handler. (line 11)
+* gcry_handler_progress_t: Progress handler. (line 10)
+* gcry_handler_realloc_t: Allocation handler. (line 20)
+* gcry_handler_secure_check_t: Allocation handler. (line 16)
+* gcry_kdf_derive: Key Derivation. (line 13)
+* gcry_malloc: Memory allocation. (line 7)
+* gcry_malloc_secure: Memory allocation. (line 12)
+* gcry_md_algo_name: Working with hash algorithms.
+ (line 154)
+* gcry_md_close: Working with hash algorithms.
+ (line 61)
+* gcry_md_copy: Working with hash algorithms.
+ (line 84)
+* gcry_md_debug: Working with hash algorithms.
+ (line 218)
+* gcry_md_enable: Working with hash algorithms.
+ (line 44)
+* gcry_md_final: Working with hash algorithms.
+ (line 112)
+* gcry_md_final_t: Hash algorithm modules.
+ (line 73)
+* gcry_md_get_algo: Working with hash algorithms.
+ (line 198)
+* gcry_md_get_algo_dlen: Working with hash algorithms.
+ (line 189)
+* gcry_md_get_asnoid: Working with hash algorithms.
+ (line 170)
+* gcry_md_hash_buffer: Working with hash algorithms.
+ (line 137)
+* gcry_md_init_t: Hash algorithm modules.
+ (line 65)
+* gcry_md_is_enabled: Working with hash algorithms.
+ (line 209)
+* gcry_md_is_secure: Working with hash algorithms.
+ (line 204)
+* gcry_md_list: Hash algorithm modules.
+ (line 93)
+* gcry_md_map_name: Working with hash algorithms.
+ (line 160)
+* gcry_md_oid_spec_t: Hash algorithm modules.
+ (line 57)
+* gcry_md_open: Working with hash algorithms.
+ (line 11)
+* gcry_md_putc: Working with hash algorithms.
+ (line 102)
+* gcry_md_read: Working with hash algorithms.
+ (line 122)
+* gcry_md_read_t: Hash algorithm modules.
+ (line 77)
+* gcry_md_register: Hash algorithm modules.
+ (line 82)
+* gcry_md_reset: Working with hash algorithms.
+ (line 72)
+* gcry_md_setkey: Working with hash algorithms.
+ (line 53)
+* gcry_md_spec_t: Hash algorithm modules.
+ (line 12)
+* gcry_md_start_debug: Working with hash algorithms.
+ (line 232)
+* gcry_md_stop_debug: Working with hash algorithms.
+ (line 240)
+* gcry_md_test_algo: Working with hash algorithms.
+ (line 183)
+* gcry_md_unregister: Hash algorithm modules.
+ (line 89)
+* gcry_md_write: Working with hash algorithms.
+ (line 97)
+* gcry_md_write_t: Hash algorithm modules.
+ (line 69)
+* gcry_module_t: Modules. (line 10)
+* gcry_mpi_add: Calculations. (line 10)
+* gcry_mpi_add_ui: Calculations. (line 14)
+* gcry_mpi_addm: Calculations. (line 18)
+* gcry_mpi_aprint: MPI formats. (line 54)
+* gcry_mpi_clear_bit: Bit manipulations. (line 19)
+* gcry_mpi_clear_flag: Miscellaneous. (line 32)
+* gcry_mpi_clear_highbit: Bit manipulations. (line 25)
+* gcry_mpi_cmp: Comparisons. (line 9)
+* gcry_mpi_cmp_ui: Comparisons. (line 17)
+* gcry_mpi_copy: Basic functions. (line 23)
+* gcry_mpi_div: Calculations. (line 50)
+* gcry_mpi_dump: MPI formats. (line 61)
+* gcry_mpi_gcd: Calculations. (line 63)
+* gcry_mpi_get_flag: Miscellaneous. (line 37)
+* gcry_mpi_get_nbits: Bit manipulations. (line 10)
+* gcry_mpi_get_opaque: Miscellaneous. (line 20)
+* gcry_mpi_invm: Calculations. (line 68)
+* gcry_mpi_lshift: Bit manipulations. (line 34)
+* gcry_mpi_mod: Calculations. (line 55)
+* gcry_mpi_mul: Calculations. (line 34)
+* gcry_mpi_mul_2exp: Calculations. (line 46)
+* gcry_mpi_mul_ui: Calculations. (line 38)
+* gcry_mpi_mulm: Calculations. (line 42)
+* gcry_mpi_new: Basic functions. (line 10)
+* gcry_mpi_powm: Calculations. (line 59)
+* gcry_mpi_print: MPI formats. (line 45)
+* gcry_mpi_randomize: Miscellaneous. (line 41)
+* gcry_mpi_release: Basic functions. (line 26)
+* gcry_mpi_rshift: Bit manipulations. (line 29)
+* gcry_mpi_scan: MPI formats. (line 12)
+* gcry_mpi_set: Basic functions. (line 33)
+* gcry_mpi_set_bit: Bit manipulations. (line 16)
+* gcry_mpi_set_flag: Miscellaneous. (line 26)
+* gcry_mpi_set_highbit: Bit manipulations. (line 22)
+* gcry_mpi_set_opaque: Miscellaneous. (line 8)
+* gcry_mpi_set_ui: Basic functions. (line 37)
+* gcry_mpi_snew: Basic functions. (line 17)
+* gcry_mpi_sub: Calculations. (line 22)
+* gcry_mpi_sub_ui: Calculations. (line 26)
+* gcry_mpi_subm: Calculations. (line 30)
+* gcry_mpi_swap: Basic functions. (line 44)
+* gcry_mpi_t: Data types. (line 7)
+* gcry_mpi_test_bit: Bit manipulations. (line 13)
+* gcry_pk_algo_info: General public-key related Functions.
+ (line 47)
+* gcry_pk_algo_name: General public-key related Functions.
+ (line 10)
+* gcry_pk_check_secret_key_t: Public key modules. (line 91)
+* gcry_pk_ctl: General public-key related Functions.
+ (line 100)
+* gcry_pk_decrypt: Cryptographic Functions.
+ (line 92)
+* gcry_pk_decrypt_t: Public key modules. (line 101)
+* gcry_pk_encrypt: Cryptographic Functions.
+ (line 36)
+* gcry_pk_encrypt_t: Public key modules. (line 96)
+* gcry_pk_generate_t: Public key modules. (line 86)
+* gcry_pk_genkey: General public-key related Functions.
+ (line 115)
+* gcry_pk_get_keygrip: General public-key related Functions.
+ (line 29)
+* gcry_pk_get_nbits: General public-key related Functions.
+ (line 24)
+* gcry_pk_get_nbits_t: Public key modules. (line 116)
+* gcry_pk_list: Public key modules. (line 133)
+* gcry_pk_map_name: General public-key related Functions.
+ (line 16)
+* gcry_pk_register: Public key modules. (line 121)
+* gcry_pk_sign: Cryptographic Functions.
+ (line 130)
+* gcry_pk_sign_t: Public key modules. (line 106)
+* gcry_pk_spec_t: Public key modules. (line 12)
+* gcry_pk_test_algo: General public-key related Functions.
+ (line 20)
+* gcry_pk_testkey: General public-key related Functions.
+ (line 40)
+* gcry_pk_unregister: Public key modules. (line 129)
+* gcry_pk_verify: Cryptographic Functions.
+ (line 183)
+* gcry_pk_verify_t: Public key modules. (line 111)
+* gcry_prime_check: Checking. (line 8)
+* gcry_prime_generate: Generation. (line 10)
+* gcry_prime_group_generator: Generation. (line 19)
+* gcry_prime_release_factors: Generation. (line 25)
+* gcry_random_bytes: Retrieving random numbers.
+ (line 13)
+* gcry_random_bytes_secure: Retrieving random numbers.
+ (line 19)
+* gcry_random_level_t: Quality of random numbers.
+ (line 9)
+* gcry_randomize: Retrieving random numbers.
+ (line 8)
+* gcry_realloc: Memory allocation. (line 24)
+* gcry_set_allocation_handler: Allocation handler. (line 34)
+* gcry_set_fatalerror_handler: Error handler. (line 32)
+* gcry_set_log_handler: Logging handler. (line 12)
+* gcry_set_outofcore_handler: Error handler. (line 16)
+* gcry_set_progress_handler: Progress handler. (line 21)
+* gcry_sexp_build: Working with S-expressions.
+ (line 43)
+* gcry_sexp_canon_len: Working with S-expressions.
+ (line 135)
+* gcry_sexp_car: Working with S-expressions.
+ (line 164)
+* gcry_sexp_cdr: Working with S-expressions.
+ (line 169)
+* gcry_sexp_create: Working with S-expressions.
+ (line 26)
+* gcry_sexp_dump: Working with S-expressions.
+ (line 126)
+* gcry_sexp_find_token: Working with S-expressions.
+ (line 147)
+* gcry_sexp_length: Working with S-expressions.
+ (line 154)
+* gcry_sexp_new: Working with S-expressions.
+ (line 13)
+* gcry_sexp_nth: Working with S-expressions.
+ (line 159)
+* gcry_sexp_nth_data: Working with S-expressions.
+ (line 177)
+* gcry_sexp_nth_mpi: Working with S-expressions.
+ (line 202)
+* gcry_sexp_nth_string: Working with S-expressions.
+ (line 194)
+* gcry_sexp_release: Working with S-expressions.
+ (line 92)
+* gcry_sexp_sprint: Working with S-expressions.
+ (line 103)
+* gcry_sexp_sscan: Working with S-expressions.
+ (line 37)
+* gcry_sexp_t: Data types for S-expressions.
+ (line 7)
+* gcry_strerror: Error Strings. (line 7)
+* gcry_strsource: Error Strings. (line 13)
+
+
--- /dev/null
+\input texinfo @c -*- Texinfo -*-
+@c %**start of header
+@setfilename gcrypt.info
+@include version.texi
+@settitle The Libgcrypt Reference Manual
+@c Unify some of the indices.
+@syncodeindex tp fn
+@syncodeindex pg fn
+@c %**end of header
+@copying
+This manual is for Libgcrypt
+(version @value{VERSION}, @value{UPDATED}),
+which is GNU's library of cryptographic building blocks.
+
+Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2 of the License, or (at your
+option) any later version. The text of the license can be found in the
+section entitled ``GNU General Public License''.
+@end quotation
+@end copying
+
+@dircategory GNU Libraries
+@direntry
+* libgcrypt: (gcrypt). Cryptographic function library.
+@end direntry
+
+
+
+@c
+@c Titlepage
+@c
+@setchapternewpage odd
+@titlepage
+@title The Libgcrypt Reference Manual
+@subtitle Version @value{VERSION}
+@subtitle @value{UPDATED}
+@author Werner Koch (@email{wk@@gnupg.org})
+@author Moritz Schulte (@email{mo@@g10code.com})
+
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@ifnothtml
+@summarycontents
+@contents
+@page
+@end ifnothtml
+
+
+@ifnottex
+@node Top
+@top The Libgcrypt Library
+@insertcopying
+@end ifnottex
+
+
+@menu
+* Introduction:: What is Libgcrypt.
+* Preparation:: What you should do before using the library.
+* Generalities:: General library functions and data types.
+* Handler Functions:: Working with handler functions.
+* Symmetric cryptography:: How to use symmetric cryptography.
+* Public Key cryptography:: How to use public key cryptography.
+* Hashing:: How to use hash and MAC algorithms.
+* Key Derivation:: How to derive keys from strings
+* Random Numbers:: How to work with random numbers.
+* S-expressions:: How to manage S-expressions.
+* MPI library:: How to work with multi-precision-integers.
+* Prime numbers:: How to use the Prime number related functions.
+* Utilities:: Utility functions.
+* Architecture:: How Libgcrypt works internally.
+
+Appendices
+
+* Self-Tests:: Description of the self-tests.
+* FIPS Mode:: Description of the FIPS mode.
+* Library Copying:: The GNU Lesser General Public License
+ says how you can copy and share Libgcrypt.
+* Copying:: The GNU General Public License says how you
+ can copy and share some parts of Libgcrypt.
+
+Indices
+
+* Figures and Tables:: Index of figures and tables.
+* Concept Index:: Index of concepts and programs.
+* Function and Data Index:: Index of functions, variables and data types.
+
+@end menu
+
+@ifhtml
+@page
+@summarycontents
+@contents
+@end ifhtml
+
+
+@c **********************************************************
+@c ******************* Introduction ***********************
+@c **********************************************************
+@node Introduction
+@chapter Introduction
+
+Libgcrypt is a library providing cryptographic building blocks.
+
+@menu
+* Getting Started:: How to use this manual.
+* Features:: A glance at Libgcrypt's features.
+* Overview:: Overview about the library.
+@end menu
+
+@node Getting Started
+@section Getting Started
+
+This manual documents the Libgcrypt library application programming
+interface (API). All functions and data types provided by the library
+are explained.
+
+@noindent
+The reader is assumed to possess basic knowledge about applied
+cryptography.
+
+This manual can be used in several ways. If read from the beginning
+to the end, it gives a good introduction into the library and how it
+can be used in an application. Forward references are included where
+necessary. Later on, the manual can be used as a reference manual to
+get just the information needed about any particular interface of the
+library. Experienced programmers might want to start looking at the
+examples at the end of the manual, and then only read up those parts
+of the interface which are unclear.
+
+
+@node Features
+@section Features
+
+Libgcrypt might have a couple of advantages over other libraries doing
+a similar job.
+
+@table @asis
+@item It's Free Software
+Anybody can use, modify, and redistribute it under the terms of the GNU
+Lesser General Public License (@pxref{Library Copying}). Note, that
+some parts (which are in general not needed by applications) are subject
+to the terms of the GNU General Public License (@pxref{Copying}); please
+see the README file of the distribution for of list of these parts.
+
+@item It encapsulates the low level cryptography
+Libgcrypt provides a high level interface to cryptographic
+building blocks using an extensible and flexible API.
+
+@end table
+
+@node Overview
+@section Overview
+
+@noindent
+The Libgcrypt library is fully thread-safe, where it makes
+sense to be thread-safe. Not thread-safe are some cryptographic
+functions that modify a certain context stored in handles. If the
+user really intents to use such functions from different threads on
+the same handle, he has to take care of the serialization of such
+functions himself. If not described otherwise, every function is
+thread-safe.
+
+Libgcrypt depends on the library `libgpg-error', which
+contains common error handling related code for GnuPG components.
+
+@c **********************************************************
+@c ******************* Preparation ************************
+@c **********************************************************
+@node Preparation
+@chapter Preparation
+
+To use Libgcrypt, you have to perform some changes to your
+sources and the build system. The necessary changes are small and
+explained in the following sections. At the end of this chapter, it
+is described how the library is initialized, and how the requirements
+of the library are verified.
+
+@menu
+* Header:: What header file you need to include.
+* Building sources:: How to build sources using the library.
+* Building sources using Automake:: How to build sources with the help of Automake.
+* Initializing the library:: How to initialize the library.
+* Multi-Threading:: How Libgcrypt can be used in a MT environment.
+* Enabling FIPS mode:: How to enable the FIPS mode.
+@end menu
+
+
+@node Header
+@section Header
+
+All interfaces (data types and functions) of the library are defined
+in the header file @file{gcrypt.h}. You must include this in all source
+files using the library, either directly or through some other header
+file, like this:
+
+@example
+#include <gcrypt.h>
+@end example
+
+The name space of Libgcrypt is @code{gcry_*} for function
+and type names and @code{GCRY*} for other symbols. In addition the
+same name prefixes with one prepended underscore are reserved for
+internal use and should never be used by an application. Note that
+Libgcrypt uses libgpg-error, which uses @code{gpg_*} as
+name space for function and type names and @code{GPG_*} for other
+symbols, including all the error codes.
+
+@noindent
+Certain parts of gcrypt.h may be excluded by defining these macros:
+
+@table @code
+@item GCRYPT_NO_MPI_MACROS
+Do not define the shorthand macros @code{mpi_*} for @code{gcry_mpi_*}.
+
+@item GCRYPT_NO_DEPRECATED
+Do not include definitions for deprecated features. This is useful to
+make sure that no deprecated features are used.
+@end table
+
+@node Building sources
+@section Building sources
+
+If you want to compile a source file including the `gcrypt.h' header
+file, you must make sure that the compiler can find it in the
+directory hierarchy. This is accomplished by adding the path to the
+directory in which the header file is located to the compilers include
+file search path (via the @option{-I} option).
+
+However, the path to the include file is determined at the time the
+source is configured. To solve this problem, Libgcrypt ships with a small
+helper program @command{libgcrypt-config} that knows the path to the
+include file and other configuration options. The options that need
+to be added to the compiler invocation at compile time are output by
+the @option{--cflags} option to @command{libgcrypt-config}. The following
+example shows how it can be used at the command line:
+
+@example
+gcc -c foo.c `libgcrypt-config --cflags`
+@end example
+
+Adding the output of @samp{libgcrypt-config --cflags} to the compilers
+command line will ensure that the compiler can find the Libgcrypt header
+file.
+
+A similar problem occurs when linking the program with the library.
+Again, the compiler has to find the library files. For this to work,
+the path to the library files has to be added to the library search path
+(via the @option{-L} option). For this, the option @option{--libs} to
+@command{libgcrypt-config} can be used. For convenience, this option
+also outputs all other options that are required to link the program
+with the Libgcrypt libraries (in particular, the @samp{-lgcrypt}
+option). The example shows how to link @file{foo.o} with the Libgcrypt
+library to a program @command{foo}.
+
+@example
+gcc -o foo foo.o `libgcrypt-config --libs`
+@end example
+
+Of course you can also combine both examples to a single command by
+specifying both options to @command{libgcrypt-config}:
+
+@example
+gcc -o foo foo.c `libgcrypt-config --cflags --libs`
+@end example
+
+@node Building sources using Automake
+@section Building sources using Automake
+
+It is much easier if you use GNU Automake instead of writing your own
+Makefiles. If you do that, you do not have to worry about finding and
+invoking the @command{libgcrypt-config} script at all.
+Libgcrypt provides an extension to Automake that does all
+the work for you.
+
+@c A simple macro for optional variables.
+@macro ovar{varname}
+@r{[}@var{\varname\}@r{]}
+@end macro
+@defmac AM_PATH_LIBGCRYPT (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found})
+Check whether Libgcrypt (at least version
+@var{minimum-version}, if given) exists on the host system. If it is
+found, execute @var{action-if-found}, otherwise do
+@var{action-if-not-found}, if given.
+
+Additionally, the function defines @code{LIBGCRYPT_CFLAGS} to the
+flags needed for compilation of the program to find the
+@file{gcrypt.h} header file, and @code{LIBGCRYPT_LIBS} to the linker
+flags needed to link the program to the Libgcrypt library.
+@end defmac
+
+You can use the defined Autoconf variables like this in your
+@file{Makefile.am}:
+
+@example
+AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
+LDADD = $(LIBGCRYPT_LIBS)
+@end example
+
+@node Initializing the library
+@section Initializing the library
+
+Before the library can be used, it must initialize itself. This is
+achieved by invoking the function @code{gcry_check_version} described
+below.
+
+Also, it is often desirable to check that the version of
+Libgcrypt used is indeed one which fits all requirements.
+Even with binary compatibility, new features may have been introduced,
+but due to problem with the dynamic linker an old version may actually
+be used. So you may want to check that the version is okay right
+after program startup.
+
+@deftypefun {const char *} gcry_check_version (const char *@var{req_version})
+
+The function @code{gcry_check_version} initializes some subsystems used
+by Libgcrypt and must be invoked before any other function in the
+library, with the exception of the @code{GCRYCTL_SET_THREAD_CBS} command
+(called via the @code{gcry_control} function).
+@xref{Multi-Threading}.
+
+Furthermore, this function returns the version number of the library.
+It can also verify that the version number is higher than a certain
+required version number @var{req_version}, if this value is not a null
+pointer.
+@end deftypefun
+
+Libgcrypt uses a concept known as secure memory, which is a region of
+memory set aside for storing sensitive data. Because such memory is a
+scarce resource, it needs to be setup in advanced to a fixed size.
+Further, most operating systems have special requirements on how that
+secure memory can be used. For example, it might be required to install
+an application as ``setuid(root)'' to allow allocating such memory.
+Libgcrypt requires a sequence of initialization steps to make sure that
+this works correctly. The following examples show the necessary steps.
+
+If you don't have a need for secure memory, for example if your
+application does not use secret keys or other confidential data or it
+runs in a controlled environment where key material floating around in
+memory is not a problem, you should initialize Libgcrypt this way:
+
+@example
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are intialized. */
+ if (!gcry_check_version (GCRYPT_VERSION))
+ @{
+ fputs ("libgcrypt version mismatch\n", stderr);
+ exit (2);
+ @}
+
+ /* Disable secure memory. */
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+@end example
+
+
+If you have to protect your keys or other information in memory against
+being swapped out to disk and to enable an automatic overwrite of used
+and freed memory, you need to initialize Libgcrypt this way:
+
+@example
+ /* Version check should be the very first call because it
+ makes sure that important subsystems are intialized. */
+ if (!gcry_check_version (GCRYPT_VERSION))
+ @{
+ fputs ("libgcrypt version mismatch\n", stderr);
+ exit (2);
+ @}
+
+@anchor{sample-use-suspend-secmem}
+ /* We don't want to see any warnings, e.g. because we have not yet
+ parsed program options which might be used to suppress such
+ warnings. */
+ gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. Note that the
+ process might still be running with increased privileges and that
+ the secure memory has not been intialized. */
+
+ /* Allocate a pool of 16k secure memory. This make the secure memory
+ available and also drops privileges where needed. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+@anchor{sample-use-resume-secmem}
+ /* It is now okay to let Libgcrypt complain when there was/is
+ a problem with the secure memory. */
+ gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
+
+ /* ... If required, other initialization goes here. */
+
+ /* Tell Libgcrypt that initialization has completed. */
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+@end example
+
+It is important that these initialization steps are not done by a
+library but by the actual application. A library using Libgcrypt might
+want to check for finished initialization using:
+
+@example
+ if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
+ @{
+ fputs ("libgcrypt has not been initialized\n", stderr);
+ abort ();
+ @}
+@end example
+
+Instead of terminating the process, the library may instead print a
+warning and try to initialize Libgcrypt itself. See also the section on
+multi-threading below for more pitfalls.
+
+
+
+@node Multi-Threading
+@section Multi-Threading
+
+As mentioned earlier, the Libgcrypt library is
+thread-safe if you adhere to the following requirements:
+
+@itemize @bullet
+@item
+If your application is multi-threaded, you must set the thread support
+callbacks with the @code{GCRYCTL_SET_THREAD_CBS} command
+@strong{before} any other function in the library.
+
+This is easy enough if you are indeed writing an application using
+Libgcrypt. It is rather problematic if you are writing a library
+instead. Here are some tips what to do if you are writing a library:
+
+If your library requires a certain thread package, just initialize
+Libgcrypt to use this thread package. If your library supports multiple
+thread packages, but needs to be configured, you will have to
+implement a way to determine which thread package the application
+wants to use with your library anyway. Then configure Libgcrypt to use
+this thread package.
+
+If your library is fully reentrant without any special support by a
+thread package, then you are lucky indeed. Unfortunately, this does
+not relieve you from doing either of the two above, or use a third
+option. The third option is to let the application initialize Libgcrypt
+for you. Then you are not using Libgcrypt transparently, though.
+
+As if this was not difficult enough, a conflict may arise if two
+libraries try to initialize Libgcrypt independently of each others, and
+both such libraries are then linked into the same application. To
+make it a bit simpler for you, this will probably work, but only if
+both libraries have the same requirement for the thread package. This
+is currently only supported for the non-threaded case, GNU Pth and
+pthread.
+
+If you use pthread and your applications forks and does not directly
+call exec (even calling stdio functions), all kind of problems may
+occur. Future versions of Libgcrypt will try to cleanup using
+pthread_atfork but even that may lead to problems. This is a common
+problem with almost all applications using pthread and fork.
+
+Note that future versions of Libgcrypt will drop this flexible thread
+support and instead only support the platforms standard thread
+implementation.
+
+
+@item
+The function @code{gcry_check_version} must be called before any other
+function in the library, except the @code{GCRYCTL_SET_THREAD_CBS}
+command (called via the @code{gcry_control} function), because it
+initializes the thread support subsystem in Libgcrypt. To
+achieve this in multi-threaded programs, you must synchronize the
+memory with respect to other threads that also want to use
+Libgcrypt. For this, it is sufficient to call
+@code{gcry_check_version} before creating the other threads using
+Libgcrypt@footnote{At least this is true for POSIX threads,
+as @code{pthread_create} is a function that synchronizes memory with
+respects to other threads. There are many functions which have this
+property, a complete list can be found in POSIX, IEEE Std 1003.1-2003,
+Base Definitions, Issue 6, in the definition of the term ``Memory
+Synchronization''. For other thread packages, more relaxed or more
+strict rules may apply.}.
+
+@item
+Just like the function @code{gpg_strerror}, the function
+@code{gcry_strerror} is not thread safe. You have to use
+@code{gpg_strerror_r} instead.
+
+@end itemize
+
+
+Libgcrypt contains convenient macros, which define the
+necessary thread callbacks for PThread and for GNU Pth:
+
+@table @code
+@item GCRY_THREAD_OPTION_PTH_IMPL
+
+This macro defines the following (static) symbols:
+@code{gcry_pth_init}, @code{gcry_pth_mutex_init},
+@code{gcry_pth_mutex_destroy}, @code{gcry_pth_mutex_lock},
+@code{gcry_pth_mutex_unlock}, @code{gcry_pth_read},
+@code{gcry_pth_write}, @code{gcry_pth_select},
+@code{gcry_pth_waitpid}, @code{gcry_pth_accept},
+@code{gcry_pth_connect}, @code{gcry_threads_pth}.
+
+After including this macro, @code{gcry_control()} shall be used with a
+command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the
+thread callback structure named ``gcry_threads_pth''. Example:
+
+@smallexample
+ ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+@end smallexample
+
+
+@item GCRY_THREAD_OPTION_PTHREAD_IMPL
+
+This macro defines the following (static) symbols:
+@code{gcry_pthread_mutex_init}, @code{gcry_pthread_mutex_destroy},
+@code{gcry_pthread_mutex_lock}, @code{gcry_pthread_mutex_unlock},
+@code{gcry_threads_pthread}.
+
+After including this macro, @code{gcry_control()} shall be used with a
+command of @code{GCRYCTL_SET_THREAD_CBS} in order to register the
+thread callback structure named ``gcry_threads_pthread''. Example:
+
+@smallexample
+ ret = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
+@end smallexample
+
+
+@end table
+
+Note that these macros need to be terminated with a semicolon. Keep
+in mind that these are convenient macros for C programmers; C++
+programmers might have to wrap these macros in an ``extern C'' body.
+
+
+@node Enabling FIPS mode
+@section How to enable the FIPS mode
+@cindex FIPS mode
+@cindex FIPS 140
+
+Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not
+necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the
+NIST database at @url{http://csrc.nist.gov/groups/STM/cmvp/} to see what
+versions of Libgcrypt are approved.
+
+Because FIPS 140 has certain restrictions on the use of cryptography
+which are not always wanted, Libgcrypt needs to be put into FIPS mode
+explicitly. Three alternative mechanisms are provided to switch
+Libgcrypt into this mode:
+
+@itemize
+@item
+If the file @file{/proc/sys/crypto/fips_enabled} exists and contains a
+numeric value other than @code{0}, Libgcrypt is put into FIPS mode at
+initialization time. Obviously this works only on systems with a
+@code{proc} file system (i.e. GNU/Linux).
+
+@item
+If the file @file{/etc/gcrypt/fips_enabled} exists, Libgcrypt is put
+into FIPS mode at initialization time. Note that this filename is
+hardwired and does not depend on any configuration options.
+
+@item
+If the application requests FIPS mode using the control command
+@code{GCRYCTL_FORCE_FIPS_MODE}. This must be done prior to any
+initialization (i.e. before @code{gcry_check_version}).
+
+@end itemize
+
+@cindex Enforced FIPS mode
+
+In addition to the standard FIPS mode, Libgcrypt may also be put into
+an Enforced FIPS mode by writing a non-zero value into the file
+@file{/etc/gcrypt/fips_enabled}. The Enforced FIPS mode helps to
+detect applications which don't fulfill all requirements for using
+Libgcrypt in FIPS mode (@pxref{FIPS Mode}).
+
+Once Libgcrypt has been put into FIPS mode, it is not possible to
+switch back to standard mode without terminating the process first.
+If the logging verbosity level of Libgcrypt has been set to at least
+2, the state transitions and the self-tests are logged.
+
+
+
+@c **********************************************************
+@c ******************* General ****************************
+@c **********************************************************
+@node Generalities
+@chapter Generalities
+
+@menu
+* Controlling the library:: Controlling Libgcrypt's behavior.
+* Modules:: Description of extension modules.
+* Error Handling:: Error codes and such.
+@end menu
+
+@node Controlling the library
+@section Controlling the library
+
+@deftypefun gcry_error_t gcry_control (enum gcry_ctl_cmds @var{cmd}, ...)
+
+This function can be used to influence the general behavior of
+Libgcrypt in several ways. Depending on @var{cmd}, more
+arguments can or have to be provided.
+
+@table @code
+@item GCRYCTL_ENABLE_M_GUARD; Arguments: none
+This command enables the built-in memory guard. It must not be used
+to activate the memory guard after the memory management has already
+been used; therefore it can ONLY be used before
+@code{gcry_check_version}. Note that the memory guard is NOT used
+when the user of the library has set his own memory management
+callbacks.
+
+@item GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none
+This command inhibits the use the very secure random quality level
+(@code{GCRY_VERY_STRONG_RANDOM}) and degrades all request down to
+@code{GCRY_STRONG_RANDOM}. In general this is not recommened. However,
+for some applications the extra quality random Libgcrypt tries to create
+is not justified and this option may help to get better performace.
+Please check with a crypto expert whether this option can be used for
+your application.
+
+This option can only be used at initialization time.
+
+
+@item GCRYCTL_DUMP_RANDOM_STATS; Arguments: none
+This command dumps randum number generator related statistics to the
+library's logging stream.
+
+@item GCRYCTL_DUMP_MEMORY_STATS; Arguments: none
+This command dumps memory managment related statistics to the library's
+logging stream.
+
+@item GCRYCTL_DUMP_SECMEM_STATS; Arguments: none
+This command dumps secure memory manamgent related statistics to the
+library's logging stream.
+
+@item GCRYCTL_DROP_PRIVS; Arguments: none
+This command disables the use of secure memory and drops the priviliges
+of the current process. This command has not much use; the suggested way
+to disable secure memory is to use @code{GCRYCTL_DISABLE_SECMEM} right
+after initialization.
+
+@item GCRYCTL_DISABLE_SECMEM; Arguments: none
+This command disables the use of secure memory. If this command is
+used in FIPS mode, FIPS mode will be disabled and the function
+@code{gcry_fips_mode_active} returns false. However, in Enforced FIPS
+mode this command has no effect at all.
+
+Many applications do not require secure memory, so they should disable
+it right away. This command should be executed right after
+@code{gcry_check_version}.
+
+@item GCRYCTL_INIT_SECMEM; Arguments: int nbytes
+This command is used to allocate a pool of secure memory and thus
+enabling the use of secure memory. It also drops all extra privileges
+the process has (i.e. if it is run as setuid (root)). If the argument
+@var{nbytes} is 0, secure memory will be disabled. The minimum amount
+of secure memory allocated is currently 16384 bytes; you may thus use a
+value of 1 to request that default size.
+
+@item GCRYCTL_TERM_SECMEM; Arguments: none
+This command zeroises the secure memory and destroys the handler. The
+secure memory pool may not be used anymore after running this command.
+If the secure memory pool as already been destroyed, this command has
+no effect. Applications might want to run this command from their
+exit handler to make sure that the secure memory gets properly
+destroyed. This command is not necessarily thread-safe but that
+should not be needed in cleanup code. It may be called from a signal
+handler.
+
+@item GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none
+Disable warning messages about problems with the secure memory
+subsystem. This command should be run right after
+@code{gcry_check_version}.
+
+@item GCRYCTL_SUSPEND_SECMEM_WARN; Arguments: none
+Postpone warning messages from the secure memory subsystem.
+@xref{sample-use-suspend-secmem,,the initialization example}, on how to
+use it.
+
+@item GCRYCTL_RESUME_SECMEM_WARN; Arguments: none
+Resume warning messages from the secure memory subsystem.
+@xref{sample-use-resume-secmem,,the initialization example}, on how to
+use it.
+
+@item GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none
+This command tells the PRNG to store random numbers in secure memory.
+This command should be run right after @code{gcry_check_version} and not
+later than the command GCRYCTL_INIT_SECMEM. Note that in FIPS mode the
+secure memory is always used.
+
+@item GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename
+This command specifies the file, which is to be used as seed file for
+the PRNG. If the seed file is registered prior to initialization of the
+PRNG, the seed file's content (if it exists and seems to be valid) is
+fed into the PRNG pool. After the seed file has been registered, the
+PRNG can be signalled to write out the PRNG pool's content into the seed
+file with the following command.
+
+
+@item GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none
+Write out the PRNG pool's content into the registered seed file.
+
+Multiple instances of the applications sharing the same random seed file
+can be started in parallel, in which case they will read out the same
+pool and then race for updating it (the last update overwrites earlier
+updates). They will differentiate only by the weak entropy that is
+added in read_seed_file based on the PID and clock, and up to 16 bytes
+of weak random non-blockingly. The consequence is that the output of
+these different instances is correlated to some extent. In a perfect
+attack scenario, the attacker can control (or at least guess) the PID
+and clock of the application, and drain the system's entropy pool to
+reduce the "up to 16 bytes" above to 0. Then the dependencies of the
+inital states of the pools are completely known. Note that this is not
+an issue if random of @code{GCRY_VERY_STRONG_RANDOM} quality is
+requested as in this case enough extra entropy gets mixed. It is also
+not an issue when using Linux (rndlinux driver), because this one
+guarantees to read full 16 bytes from /dev/urandom and thus there is no
+way for an attacker without kernel access to control these 16 bytes.
+
+@item GCRYCTL_SET_VERBOSITY; Arguments: int level
+This command sets the verbosity of the logging. A level of 0 disables
+all extra logging whereas positive numbers enable more verbose logging.
+The level may be changed at any time but be aware that no memory
+synchronization is done so the effect of this command might not
+immediately show up in other threads. This command may even be used
+prior to @code{gcry_check_version}.
+
+@item GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags
+Set the debug flag bits as given by the argument. Be aware that that no
+memory synchronization is done so the effect of this command might not
+immediately show up in other threads. The debug flags are not
+considered part of the API and thus may change without notice. As of
+now bit 0 enables debugging of cipher functions and bit 1 debugging of
+multi-precision-integers. This command may even be used prior to
+@code{gcry_check_version}.
+
+@item GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags
+Set the debug flag bits as given by the argument. Be aware that that no
+memory synchronization is done so the effect of this command might not
+immediately show up in other threads. This command may even be used
+prior to @code{gcry_check_version}.
+
+@item GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none
+This command does nothing. It exists only for backward compatibility.
+
+@item GCRYCTL_ANY_INITIALIZATION_P; Arguments: none
+This command returns true if the library has been basically initialized.
+Such a basic initialization happens implicitly with many commands to get
+certain internal subsystems running. The common and suggested way to
+do this basic intialization is by calling gcry_check_version.
+
+@item GCRYCTL_INITIALIZATION_FINISHED; Arguments: none
+This command tells the library that the application has finished the
+intialization.
+
+@item GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none
+This command returns true if the command@*
+GCRYCTL_INITIALIZATION_FINISHED has already been run.
+
+@item GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops
+This command registers a thread-callback structure.
+@xref{Multi-Threading}.
+
+@item GCRYCTL_FAST_POLL; Arguments: none
+Run a fast random poll.
+
+@item GCRYCTL_SET_RNDEGD_SOCKET; Arguments: const char *filename
+This command may be used to override the default name of the EGD socket
+to connect to. It may be used only during initialization as it is not
+thread safe. Changing the socket name again is not supported. The
+function may return an error if the given filename is too long for a
+local socket name.
+
+EGD is an alternative random gatherer, used only on systems lacking a
+proper random device.
+
+@item GCRYCTL_PRINT_CONFIG; Arguments: FILE *stream
+This command dumps information pertaining to the configuration of the
+library to the given stream. If NULL is given for @var{stream}, the log
+system is used. This command may be used before the intialization has
+been finished but not before a gcry_version_check.
+
+@item GCRYCTL_OPERATIONAL_P; Arguments: none
+This command returns true if the library is in an operational state.
+This information makes only sense in FIPS mode. In contrast to other
+functions, this is a pure test function and won't put the library into
+FIPS mode or change the internal state. This command may be used before
+the intialization has been finished but not before a gcry_version_check.
+
+@item GCRYCTL_FIPS_MODE_P; Arguments: none
+This command returns true if the library is in FIPS mode. Note, that
+this is no indication about the current state of the library. This
+command may be used before the intialization has been finished but not
+before a gcry_version_check. An application may use this command or
+the convenience macro below to check whether FIPS mode is actually
+active.
+
+@deftypefun int gcry_fips_mode_active (void)
+
+Returns true if the FIPS mode is active. Note that this is
+implemented as a macro.
+@end deftypefun
+
+
+
+@item GCRYCTL_FORCE_FIPS_MODE; Arguments: none
+Running this command puts the library into FIPS mode. If the library is
+already in FIPS mode, a self-test is triggered and thus the library will
+be put into operational state. This command may be used before a call
+to gcry_check_version and that is actually the recommended way to let an
+application switch the library into FIPS mode. Note that Libgcrypt will
+reject an attempt to switch to fips mode during or after the intialization.
+
+@item GCRYCTL_SELFTEST; Arguments: none
+This may be used at anytime to have the library run all implemented
+self-tests. It works in standard and in FIPS mode. Returns 0 on
+success or an error code on failure.
+
+@item GCRYCTL_DISABLE_HWF; Arguments: const char *name
+
+Libgcrypt detects certain features of the CPU at startup time. For
+performace tests it is sometimes required not to use such a feature.
+This option may be used to disabale a certain feature; i.e. Libgcrypt
+behaves as if this feature has not been detected. Note that the
+detection code might be run if the feature has been disabled. This
+command must be used at initialization time; i.e. before calling
+@code{gcry_check_version}.
+
+@end table
+
+@end deftypefun
+
+@node Modules
+@section Modules
+
+Libgcrypt supports the use of `extension modules', which
+implement algorithms in addition to those already built into the library
+directly.
+
+@deftp {Data type} gcry_module_t
+This data type represents a `module'.
+@end deftp
+
+Functions registering modules provided by the user take a `module
+specification structure' as input and return a value of
+@code{gcry_module_t} and an ID that is unique in the modules'
+category. This ID can be used to reference the newly registered
+module. After registering a module successfully, the new functionality
+should be able to be used through the normal functions provided by
+Libgcrypt until it is unregistered again.
+
+@c **********************************************************
+@c ******************* Errors ****************************
+@c **********************************************************
+@node Error Handling
+@section Error Handling
+
+Many functions in Libgcrypt can return an error if they
+fail. For this reason, the application should always catch the error
+condition and take appropriate measures, for example by releasing the
+resources and passing the error up to the caller, or by displaying a
+descriptive message to the user and cancelling the operation.
+
+Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly. For
+example, if you try to decrypt a tempered message, the decryption will
+fail. Another error value actually means that the end of a data
+buffer or list has been reached. The following descriptions explain
+for many error codes what they mean usually. Some error values have
+specific meanings if returned by a certain functions. Such cases are
+described in the documentation of those functions.
+
+Libgcrypt uses the @code{libgpg-error} library. This allows to share
+the error codes with other components of the GnuPG system, and to pass
+error values transparently from the crypto engine, or some helper
+application of the crypto engine, to the user. This way no
+information is lost. As a consequence, Libgcrypt does not use its own
+identifiers for error codes, but uses those provided by
+@code{libgpg-error}. They usually start with @code{GPG_ERR_}.
+
+However, Libgcrypt does provide aliases for the functions
+defined in libgpg-error, which might be preferred for name space
+consistency.
+
+
+Most functions in Libgcrypt return an error code in the case
+of failure. For this reason, the application should always catch the
+error condition and take appropriate measures, for example by
+releasing the resources and passing the error up to the caller, or by
+displaying a descriptive message to the user and canceling the
+operation.
+
+Some error values do not indicate a system error or an error in the
+operation, but the result of an operation that failed properly.
+
+GnuPG components, including Libgcrypt, use an extra library named
+libgpg-error to provide a common error handling scheme. For more
+information on libgpg-error, see the according manual.
+
+@menu
+* Error Values:: The error value and what it means.
+* Error Sources:: A list of important error sources.
+* Error Codes:: A list of important error codes.
+* Error Strings:: How to get a descriptive string from a value.
+@end menu
+
+
+@node Error Values
+@subsection Error Values
+@cindex error values
+@cindex error codes
+@cindex error sources
+
+@deftp {Data type} {gcry_err_code_t}
+The @code{gcry_err_code_t} type is an alias for the
+@code{libgpg-error} type @code{gpg_err_code_t}. The error code
+indicates the type of an error, or the reason why an operation failed.
+
+A list of important error codes can be found in the next section.
+@end deftp
+
+@deftp {Data type} {gcry_err_source_t}
+The @code{gcry_err_source_t} type is an alias for the
+@code{libgpg-error} type @code{gpg_err_source_t}. The error source
+has not a precisely defined meaning. Sometimes it is the place where
+the error happened, sometimes it is the place where an error was
+encoded into an error value. Usually the error source will give an
+indication to where to look for the problem. This is not always true,
+but it is attempted to achieve this goal.
+
+A list of important error sources can be found in the next section.
+@end deftp
+
+@deftp {Data type} {gcry_error_t}
+The @code{gcry_error_t} type is an alias for the @code{libgpg-error}
+type @code{gpg_error_t}. An error value like this has always two
+components, an error code and an error source. Both together form the
+error value.
+
+Thus, the error value can not be directly compared against an error
+code, but the accessor functions described below must be used.
+However, it is guaranteed that only 0 is used to indicate success
+(@code{GPG_ERR_NO_ERROR}), and that in this case all other parts of
+the error value are set to 0, too.
+
+Note that in Libgcrypt, the error source is used purely for
+diagnostic purposes. Only the error code should be checked to test
+for a certain outcome of a function. The manual only documents the
+error code part of an error value. The error source is left
+unspecified and might be anything.
+@end deftp
+
+@deftypefun {gcry_err_code_t} gcry_err_code (@w{gcry_error_t @var{err}})
+The static inline function @code{gcry_err_code} returns the
+@code{gcry_err_code_t} component of the error value @var{err}. This
+function must be used to extract the error code from an error value in
+order to compare it with the @code{GPG_ERR_*} error code macros.
+@end deftypefun
+
+@deftypefun {gcry_err_source_t} gcry_err_source (@w{gcry_error_t @var{err}})
+The static inline function @code{gcry_err_source} returns the
+@code{gcry_err_source_t} component of the error value @var{err}. This
+function must be used to extract the error source from an error value in
+order to compare it with the @code{GPG_ERR_SOURCE_*} error source macros.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_err_make (@w{gcry_err_source_t @var{source}}, @w{gcry_err_code_t @var{code}})
+The static inline function @code{gcry_err_make} returns the error
+value consisting of the error source @var{source} and the error code
+@var{code}.
+
+This function can be used in callback functions to construct an error
+value to return it to the library.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_error (@w{gcry_err_code_t @var{code}})
+The static inline function @code{gcry_error} returns the error value
+consisting of the default error source and the error code @var{code}.
+
+For @acronym{GCRY} applications, the default error source is
+@code{GPG_ERR_SOURCE_USER_1}. You can define
+@code{GCRY_ERR_SOURCE_DEFAULT} before including @file{gcrypt.h} to
+change this default.
+
+This function can be used in callback functions to construct an error
+value to return it to the library.
+@end deftypefun
+
+The @code{libgpg-error} library provides error codes for all system
+error numbers it knows about. If @var{err} is an unknown error
+number, the error code @code{GPG_ERR_UNKNOWN_ERRNO} is used. The
+following functions can be used to construct error values from system
+errno numbers.
+
+@deftypefun {gcry_error_t} gcry_err_make_from_errno (@w{gcry_err_source_t @var{source}}, @w{int @var{err}})
+The function @code{gcry_err_make_from_errno} is like
+@code{gcry_err_make}, but it takes a system error like @code{errno}
+instead of a @code{gcry_err_code_t} error code.
+@end deftypefun
+
+@deftypefun {gcry_error_t} gcry_error_from_errno (@w{int @var{err}})
+The function @code{gcry_error_from_errno} is like @code{gcry_error},
+but it takes a system error like @code{errno} instead of a
+@code{gcry_err_code_t} error code.
+@end deftypefun
+
+Sometimes you might want to map system error numbers to error codes
+directly, or map an error code representing a system error back to the
+system error number. The following functions can be used to do that.
+
+@deftypefun {gcry_err_code_t} gcry_err_code_from_errno (@w{int @var{err}})
+The function @code{gcry_err_code_from_errno} returns the error code
+for the system error @var{err}. If @var{err} is not a known system
+error, the function returns @code{GPG_ERR_UNKNOWN_ERRNO}.
+@end deftypefun
+
+@deftypefun {int} gcry_err_code_to_errno (@w{gcry_err_code_t @var{err}})
+The function @code{gcry_err_code_to_errno} returns the system error
+for the error code @var{err}. If @var{err} is not an error code
+representing a system error, or if this system error is not defined on
+this system, the function returns @code{0}.
+@end deftypefun
+
+
+@node Error Sources
+@subsection Error Sources
+@cindex error codes, list of
+
+The library @code{libgpg-error} defines an error source for every
+component of the GnuPG system. The error source part of an error
+value is not well defined. As such it is mainly useful to improve the
+diagnostic error message for the user.
+
+If the error code part of an error value is @code{0}, the whole error
+value will be @code{0}. In this case the error source part is of
+course @code{GPG_ERR_SOURCE_UNKNOWN}.
+
+The list of error sources that might occur in applications using
+@acronym{Libgcrypt} is:
+
+@table @code
+@item GPG_ERR_SOURCE_UNKNOWN
+The error source is not known. The value of this error source is
+@code{0}.
+
+@item GPG_ERR_SOURCE_GPGME
+The error source is @acronym{GPGME} itself.
+
+@item GPG_ERR_SOURCE_GPG
+The error source is GnuPG, which is the crypto engine used for the
+OpenPGP protocol.
+
+@item GPG_ERR_SOURCE_GPGSM
+The error source is GPGSM, which is the crypto engine used for the
+OpenPGP protocol.
+
+@item GPG_ERR_SOURCE_GCRYPT
+The error source is @code{libgcrypt}, which is used by crypto engines
+to perform cryptographic operations.
+
+@item GPG_ERR_SOURCE_GPGAGENT
+The error source is @command{gpg-agent}, which is used by crypto
+engines to perform operations with the secret key.
+
+@item GPG_ERR_SOURCE_PINENTRY
+The error source is @command{pinentry}, which is used by
+@command{gpg-agent} to query the passphrase to unlock a secret key.
+
+@item GPG_ERR_SOURCE_SCD
+The error source is the SmartCard Daemon, which is used by
+@command{gpg-agent} to delegate operations with the secret key to a
+SmartCard.
+
+@item GPG_ERR_SOURCE_KEYBOX
+The error source is @code{libkbx}, a library used by the crypto
+engines to manage local keyrings.
+
+@item GPG_ERR_SOURCE_USER_1
+@item GPG_ERR_SOURCE_USER_2
+@item GPG_ERR_SOURCE_USER_3
+@item GPG_ERR_SOURCE_USER_4
+These error sources are not used by any GnuPG component and can be
+used by other software. For example, applications using
+Libgcrypt can use them to mark error values coming from callback
+handlers. Thus @code{GPG_ERR_SOURCE_USER_1} is the default for errors
+created with @code{gcry_error} and @code{gcry_error_from_errno},
+unless you define @code{GCRY_ERR_SOURCE_DEFAULT} before including
+@file{gcrypt.h}.
+@end table
+
+
+@node Error Codes
+@subsection Error Codes
+@cindex error codes, list of
+
+The library @code{libgpg-error} defines many error values. The
+following list includes the most important error codes.
+
+@table @code
+@item GPG_ERR_EOF
+This value indicates the end of a list, buffer or file.
+
+@item GPG_ERR_NO_ERROR
+This value indicates success. The value of this error code is
+@code{0}. Also, it is guaranteed that an error value made from the
+error code @code{0} will be @code{0} itself (as a whole). This means
+that the error source information is lost for this error code,
+however, as this error code indicates that no error occurred, this is
+generally not a problem.
+
+@item GPG_ERR_GENERAL
+This value means that something went wrong, but either there is not
+enough information about the problem to return a more useful error
+value, or there is no separate error value for this type of problem.
+
+@item GPG_ERR_ENOMEM
+This value means that an out-of-memory condition occurred.
+
+@item GPG_ERR_E...
+System errors are mapped to GPG_ERR_EFOO where FOO is the symbol for
+the system error.
+
+@item GPG_ERR_INV_VALUE
+This value means that some user provided data was out of range.
+
+@item GPG_ERR_UNUSABLE_PUBKEY
+This value means that some recipients for a message were invalid.
+
+@item GPG_ERR_UNUSABLE_SECKEY
+This value means that some signers were invalid.
+
+@item GPG_ERR_NO_DATA
+This value means that data was expected where no data was found.
+
+@item GPG_ERR_CONFLICT
+This value means that a conflict of some sort occurred.
+
+@item GPG_ERR_NOT_IMPLEMENTED
+This value indicates that the specific function (or operation) is not
+implemented. This error should never happen. It can only occur if
+you use certain values or configuration options which do not work,
+but for which we think that they should work at some later time.
+
+@item GPG_ERR_DECRYPT_FAILED
+This value indicates that a decryption operation was unsuccessful.
+
+@item GPG_ERR_WRONG_KEY_USAGE
+This value indicates that a key is not used appropriately.
+
+@item GPG_ERR_NO_SECKEY
+This value indicates that no secret key for the user ID is available.
+
+@item GPG_ERR_UNSUPPORTED_ALGORITHM
+This value means a verification failed because the cryptographic
+algorithm is not supported by the crypto backend.
+
+@item GPG_ERR_BAD_SIGNATURE
+This value means a verification failed because the signature is bad.
+
+@item GPG_ERR_NO_PUBKEY
+This value means a verification failed because the public key is not
+available.
+
+@item GPG_ERR_NOT_OPERATIONAL
+This value means that the library is not yet in state which allows to
+use this function. This error code is in particular returned if
+Libgcrypt is operated in FIPS mode and the internal state of the
+library does not yet or not anymore allow the use of a service.
+
+This error code is only available with newer libgpg-error versions, thus
+you might see ``invalid error code'' when passing this to
+@code{gpg_strerror}. The numeric value of this error code is 176.
+
+@item GPG_ERR_USER_1
+@item GPG_ERR_USER_2
+@item ...
+@item GPG_ERR_USER_16
+These error codes are not used by any GnuPG component and can be
+freely used by other software. Applications using Libgcrypt
+might use them to mark specific errors returned by callback handlers
+if no suitable error codes (including the system errors) for these
+errors exist already.
+@end table
+
+
+@node Error Strings
+@subsection Error Strings
+@cindex error values, printing of
+@cindex error codes, printing of
+@cindex error sources, printing of
+@cindex error strings
+
+@deftypefun {const char *} gcry_strerror (@w{gcry_error_t @var{err}})
+The function @code{gcry_strerror} returns a pointer to a statically
+allocated string containing a description of the error code contained
+in the error value @var{err}. This string can be used to output a
+diagnostic message to the user.
+@end deftypefun
+
+
+@deftypefun {const char *} gcry_strsource (@w{gcry_error_t @var{err}})
+The function @code{gcry_strerror} returns a pointer to a statically
+allocated string containing a description of the error source
+contained in the error value @var{err}. This string can be used to
+output a diagnostic message to the user.
+@end deftypefun
+
+The following example illustrates the use of the functions described
+above:
+
+@example
+@{
+ gcry_cipher_hd_t handle;
+ gcry_error_t err = 0;
+
+ err = gcry_cipher_open (&handle, GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ @{
+ fprintf (stderr, "Failure: %s/%s\n",
+ gcry_strsource (err),
+ gcry_strerror (err));
+ @}
+@}
+@end example
+
+@c **********************************************************
+@c ******************* General ****************************
+@c **********************************************************
+@node Handler Functions
+@chapter Handler Functions
+
+Libgcrypt makes it possible to install so called `handler functions',
+which get called by Libgcrypt in case of certain events.
+
+@menu
+* Progress handler:: Using a progress handler function.
+* Allocation handler:: Using special memory allocation functions.
+* Error handler:: Using error handler functions.
+* Logging handler:: Using a special logging function.
+@end menu
+
+@node Progress handler
+@section Progress handler
+
+It is often useful to retrieve some feedback while long running
+operations are performed.
+
+@deftp {Data type} gcry_handler_progress_t
+Progress handler functions have to be of the type
+@code{gcry_handler_progress_t}, which is defined as:
+
+@code{void (*gcry_handler_progress_t) (void *, const char *, int, int, int)}
+@end deftp
+
+The following function may be used to register a handler function for
+this purpose.
+
+@deftypefun void gcry_set_progress_handler (gcry_handler_progress_t @var{cb}, void *@var{cb_data})
+
+This function installs @var{cb} as the `Progress handler' function.
+It may be used only during initialization. @var{cb} must be defined
+as follows:
+
+@example
+void
+my_progress_handler (void *@var{cb_data}, const char *@var{what},
+ int @var{printchar}, int @var{current}, int @var{total})
+@{
+ /* Do something. */
+@}
+@end example
+
+A description of the arguments of the progress handler function follows.
+
+@table @var
+@item cb_data
+The argument provided in the call to @code{gcry_set_progress_handler}.
+@item what
+A string identifying the type of the progress output. The following
+values for @var{what} are defined:
+
+@table @code
+@item need_entropy
+Not enough entropy is available. @var{total} holds the number of
+required bytes.
+
+@item primegen
+Values for @var{printchar}:
+@table @code
+@item \n
+Prime generated.
+@item !
+Need to refresh the pool of prime numbers.
+@item <, >
+Number of bits adjusted.
+@item ^
+Searching for a generator.
+@item .
+Fermat test on 10 candidates failed.
+@item :
+Restart with a new random value.
+@item +
+Rabin Miller test passed.
+@end table
+
+@end table
+
+@end table
+@end deftypefun
+
+@node Allocation handler
+@section Allocation handler
+
+It is possible to make Libgcrypt use special memory
+allocation functions instead of the built-in ones.
+
+Memory allocation functions are of the following types:
+@deftp {Data type} gcry_handler_alloc_t
+This type is defined as: @code{void *(*gcry_handler_alloc_t) (size_t n)}.
+@end deftp
+@deftp {Data type} gcry_handler_secure_check_t
+This type is defined as: @code{int *(*gcry_handler_secure_check_t) (const void *)}.
+@end deftp
+@deftp {Data type} gcry_handler_realloc_t
+This type is defined as: @code{void *(*gcry_handler_realloc_t) (void *p, size_t n)}.
+@end deftp
+@deftp {Data type} gcry_handler_free_t
+This type is defined as: @code{void *(*gcry_handler_free_t) (void *)}.
+@end deftp
+
+Special memory allocation functions can be installed with the
+following function:
+
+@deftypefun void gcry_set_allocation_handler (gcry_handler_alloc_t @var{func_alloc}, gcry_handler_alloc_t @var{func_alloc_secure}, gcry_handler_secure_check_t @var{func_secure_check}, gcry_handler_realloc_t @var{func_realloc}, gcry_handler_free_t @var{func_free})
+Install the provided functions and use them instead of the built-in
+functions for doing memory allocation. Using this function is in
+general not recommended because the standard Libgcrypt allocation
+functions are guaranteed to zeroize memory if needed.
+
+This function may be used only during initialization and may not be
+used in fips mode.
+
+
+@end deftypefun
+
+@node Error handler
+@section Error handler
+
+The following functions may be used to register handler functions that
+are called by Libgcrypt in case certain error conditions occur. They
+may and should be registered prior to calling @code{gcry_check_version}.
+
+@deftp {Data type} gcry_handler_no_mem_t
+This type is defined as: @code{int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int)}
+@end deftp
+@deftypefun void gcry_set_outofcore_handler (gcry_handler_no_mem_t @var{func_no_mem}, void *@var{cb_data})
+This function registers @var{func_no_mem} as `out-of-core handler',
+which means that it will be called in the case of not having enough
+memory available. The handler is called with 3 arguments: The first
+one is the pointer @var{cb_data} as set with this function, the second
+is the requested memory size and the last being a flag. If bit 0 of
+the flag is set, secure memory has been requested. The handler should
+either return true to indicate that Libgcrypt should try again
+allocating memory or return false to let Libgcrypt use its default
+fatal error handler.
+@end deftypefun
+
+@deftp {Data type} gcry_handler_error_t
+This type is defined as: @code{void (*gcry_handler_error_t) (void *, int, const char *)}
+@end deftp
+
+@deftypefun void gcry_set_fatalerror_handler (gcry_handler_error_t @var{func_error}, void *@var{cb_data})
+This function registers @var{func_error} as `error handler',
+which means that it will be called in error conditions.
+@end deftypefun
+
+@node Logging handler
+@section Logging handler
+
+@deftp {Data type} gcry_handler_log_t
+This type is defined as: @code{void (*gcry_handler_log_t) (void *, int, const char *, va_list)}
+@end deftp
+
+@deftypefun void gcry_set_log_handler (gcry_handler_log_t @var{func_log}, void *@var{cb_data})
+This function registers @var{func_log} as `logging handler', which means
+that it will be called in case Libgcrypt wants to log a message. This
+function may and should be used prior to calling
+@code{gcry_check_version}.
+@end deftypefun
+
+@c **********************************************************
+@c ******************* Ciphers ****************************
+@c **********************************************************
+@c @include cipher-ref.texi
+@node Symmetric cryptography
+@chapter Symmetric cryptography
+
+The cipher functions are used for symmetrical cryptography,
+i.e. cryptography using a shared key. The programming model follows
+an open/process/close paradigm and is in that similar to other
+building blocks provided by Libgcrypt.
+
+@menu
+* Available ciphers:: List of ciphers supported by the library.
+* Cipher modules:: How to work with cipher modules.
+* Available cipher modes:: List of cipher modes supported by the library.
+* Working with cipher handles:: How to perform operations related to cipher handles.
+* General cipher functions:: General cipher functions independent of cipher handles.
+@end menu
+
+@node Available ciphers
+@section Available ciphers
+
+@table @code
+@item GCRY_CIPHER_NONE
+This is not a real algorithm but used by some functions as error return.
+The value always evaluates to false.
+
+@item GCRY_CIPHER_IDEA
+@cindex IDEA
+This is the IDEA algorithm. The constant is provided but there is
+currently no implementation for it because the algorithm is patented.
+
+@item GCRY_CIPHER_3DES
+@cindex 3DES
+@cindex Triple-DES
+@cindex DES-EDE
+@cindex Digital Encryption Standard
+Triple-DES with 3 Keys as EDE. The key size of this algorithm is 168 but
+you have to pass 192 bits because the most significant bits of each byte
+are ignored.
+
+@item GCRY_CIPHER_CAST5
+@cindex CAST5
+CAST128-5 block cipher algorithm. The key size is 128 bits.
+
+@item GCRY_CIPHER_BLOWFISH
+@cindex Blowfish
+The blowfish algorithm. The current implementation allows only for a key
+size of 128 bits.
+
+@item GCRY_CIPHER_SAFER_SK128
+Reserved and not currently implemented.
+
+@item GCRY_CIPHER_DES_SK
+Reserved and not currently implemented.
+
+@item GCRY_CIPHER_AES
+@itemx GCRY_CIPHER_AES128
+@itemx GCRY_CIPHER_RIJNDAEL
+@itemx GCRY_CIPHER_RIJNDAEL128
+@cindex Rijndael
+@cindex AES
+@cindex Advanced Encryption Standard
+AES (Rijndael) with a 128 bit key.
+
+@item GCRY_CIPHER_AES192
+@itemx GCRY_CIPHER_RIJNDAEL192
+AES (Rijndael) with a 192 bit key.
+
+@item GCRY_CIPHER_AES256
+@itemx GCRY_CIPHER_RIJNDAEL256
+AES (Rijndael) with a 256 bit key.
+
+@item GCRY_CIPHER_TWOFISH
+@cindex Twofish
+The Twofish algorithm with a 256 bit key.
+
+@item GCRY_CIPHER_TWOFISH128
+The Twofish algorithm with a 128 bit key.
+
+@item GCRY_CIPHER_ARCFOUR
+@cindex Arcfour
+@cindex RC4
+An algorithm which is 100% compatible with RSA Inc.'s RC4 algorithm.
+Note that this is a stream cipher and must be used very carefully to
+avoid a couple of weaknesses.
+
+@item GCRY_CIPHER_DES
+@cindex DES
+Standard DES with a 56 bit key. You need to pass 64 bit but the high
+bits of each byte are ignored. Note, that this is a weak algorithm
+which can be broken in reasonable time using a brute force approach.
+
+@item GCRY_CIPHER_SERPENT128
+@itemx GCRY_CIPHER_SERPENT192
+@itemx GCRY_CIPHER_SERPENT256
+@cindex Serpent
+The Serpent cipher from the AES contest.
+
+@item GCRY_CIPHER_RFC2268_40
+@itemx GCRY_CIPHER_RFC2268_128
+@cindex rfc-2268
+@cindex RC2
+Ron's Cipher 2 in the 40 and 128 bit variants. Note, that we currently
+only support the 40 bit variant. The identifier for 128 is reserved for
+future use.
+
+@item GCRY_CIPHER_SEED
+@cindex Seed (cipher)
+A 128 bit cipher as described by RFC4269.
+
+@item GCRY_CIPHER_CAMELLIA128
+@itemx GCRY_CIPHER_CAMELLIA192
+@itemx GCRY_CIPHER_CAMELLIA256
+@cindex Camellia
+The Camellia cipher by NTT. See
+@uref{http://info.isl.ntt.co.jp/@/crypt/@/eng/@/camellia/@/specifications.html}.
+
+@end table
+
+@node Cipher modules
+@section Cipher modules
+
+Libgcrypt makes it possible to load additional `cipher modules'; these
+ciphers can be used just like the cipher algorithms that are built
+into the library directly. For an introduction into extension
+modules, see @xref{Modules}.
+
+@deftp {Data type} gcry_cipher_spec_t
+This is the `module specification structure' needed for registering
+cipher modules, which has to be filled in by the user before it can be
+used to register a module. It contains the following members:
+
+@table @code
+@item const char *name
+The primary name of the algorithm.
+@item const char **aliases
+A list of strings that are `aliases' for the algorithm. The list must
+be terminated with a NULL element.
+@item gcry_cipher_oid_spec_t *oids
+A list of OIDs that are to be associated with the algorithm. The
+list's last element must have it's `oid' member set to NULL. See
+below for an explanation of this type.
+@item size_t blocksize
+The block size of the algorithm, in bytes.
+@item size_t keylen
+The length of the key, in bits.
+@item size_t contextsize
+The size of the algorithm-specific `context', that should be allocated
+for each handle.
+@item gcry_cipher_setkey_t setkey
+The function responsible for initializing a handle with a provided
+key. See below for a description of this type.
+@item gcry_cipher_encrypt_t encrypt
+The function responsible for encrypting a single block. See below for
+a description of this type.
+@item gcry_cipher_decrypt_t decrypt
+The function responsible for decrypting a single block. See below for
+a description of this type.
+@item gcry_cipher_stencrypt_t stencrypt
+Like `encrypt', for stream ciphers. See below for a description of
+this type.
+@item gcry_cipher_stdecrypt_t stdecrypt
+Like `decrypt', for stream ciphers. See below for a description of
+this type.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_cipher_oid_spec_t
+This type is used for associating a user-provided algorithm
+implementation with certain OIDs. It contains the following members:
+@table @code
+@item const char *oid
+Textual representation of the OID.
+@item int mode
+Cipher mode for which this OID is valid.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_cipher_setkey_t
+Type for the `setkey' function, defined as: gcry_err_code_t
+(*gcry_cipher_setkey_t) (void *c, const unsigned char *key, unsigned
+keylen)
+@end deftp
+
+@deftp {Data type} gcry_cipher_encrypt_t
+Type for the `encrypt' function, defined as: gcry_err_code_t
+(*gcry_cipher_encrypt_t) (void *c, const unsigned char *outbuf, const
+unsigned char *inbuf)
+@end deftp
+
+@deftp {Data type} gcry_cipher_decrypt_t
+Type for the `decrypt' function, defined as: gcry_err_code_t
+(*gcry_cipher_decrypt_t) (void *c, const unsigned char *outbuf, const
+unsigned char *inbuf)
+@end deftp
+
+@deftp {Data type} gcry_cipher_stencrypt_t
+Type for the `stencrypt' function, defined as: gcry_err_code_t
+(*gcry_@/cipher_@/stencrypt_@/t) (void *c, const unsigned char *outbuf, const
+unsigned char *, unsigned int n)
+@end deftp
+
+@deftp {Data type} gcry_cipher_stdecrypt_t
+Type for the `stdecrypt' function, defined as: gcry_err_code_t
+(*gcry_@/cipher_@/stdecrypt_@/t) (void *c, const unsigned char *outbuf, const
+unsigned char *, unsigned int n)
+@end deftp
+
+@deftypefun gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *@var{cipher}, unsigned int *algorithm_id, gcry_module_t *@var{module})
+
+Register a new cipher module whose specification can be found in
+@var{cipher}. On success, a new algorithm ID is stored in
+@var{algorithm_id} and a pointer representing this module is stored
+in @var{module}. Deprecated; the module register interface will be
+removed in a future version.
+@end deftypefun
+
+@deftypefun void gcry_cipher_unregister (gcry_module_t @var{module})
+Unregister the cipher identified by @var{module}, which must have been
+registered with gcry_cipher_register.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_list (int *@var{list}, int *@var{list_length})
+Get a list consisting of the IDs of the loaded cipher modules. If
+@var{list} is zero, write the number of loaded cipher modules to
+@var{list_length} and return. If @var{list} is non-zero, the first
+*@var{list_length} algorithm IDs are stored in @var{list}, which must
+be of according size. In case there are less cipher modules than
+*@var{list_length}, *@var{list_length} is updated to the correct
+number.
+@end deftypefun
+
+@node Available cipher modes
+@section Available cipher modes
+
+@table @code
+@item GCRY_CIPHER_MODE_NONE
+No mode specified. This should not be used. The only exception is that
+if Libgcrypt is not used in FIPS mode and if any debug flag has been
+set, this mode may be used to bypass the actual encryption.
+
+@item GCRY_CIPHER_MODE_ECB
+@cindex ECB, Electronic Codebook mode
+Electronic Codebook mode.
+
+@item GCRY_CIPHER_MODE_CFB
+@cindex CFB, Cipher Feedback mode
+Cipher Feedback mode. The shift size equals the block size of the
+cipher (e.g. for AES it is CFB-128).
+
+@item GCRY_CIPHER_MODE_CBC
+@cindex CBC, Cipher Block Chaining mode
+Cipher Block Chaining mode.
+
+@item GCRY_CIPHER_MODE_STREAM
+Stream mode, only to be used with stream cipher algorithms.
+
+@item GCRY_CIPHER_MODE_OFB
+@cindex OFB, Output Feedback mode
+Output Feedback mode.
+
+@item GCRY_CIPHER_MODE_CTR
+@cindex CTR, Counter mode
+Counter mode.
+
+@item GCRY_CIPHER_MODE_AESWRAP
+@cindex AES-Wrap mode
+This mode is used to implement the AES-Wrap algorithm according to
+RFC-3394. It may be used with any 128 bit block length algorithm,
+however the specs require one of the 3 AES algorithms. These special
+conditions apply: If @code{gcry_cipher_setiv} has not been used the
+standard IV is used; if it has been used the lower 64 bit of the IV
+are used as the Alternative Initial Value. On encryption the provided
+output buffer must be 64 bit (8 byte) larger than the input buffer;
+in-place encryption is still allowed. On decryption the output buffer
+may be specified 64 bit (8 byte) shorter than then input buffer. As
+per specs the input length must be at least 128 bits and the length
+must be a multiple of 64 bits.
+
+@end table
+
+@node Working with cipher handles
+@section Working with cipher handles
+
+To use a cipher algorithm, you must first allocate an according
+handle. This is to be done using the open function:
+
+@deftypefun gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *@var{hd}, int @var{algo}, int @var{mode}, unsigned int @var{flags})
+
+This function creates the context handle required for most of the
+other cipher functions and returns a handle to it in `hd'. In case of
+an error, an according error code is returned.
+
+The ID of algorithm to use must be specified via @var{algo}. See
+@xref{Available ciphers}, for a list of supported ciphers and the
+according constants.
+
+Besides using the constants directly, the function
+@code{gcry_cipher_map_name} may be used to convert the textual name of
+an algorithm into the according numeric ID.
+
+The cipher mode to use must be specified via @var{mode}. See
+@xref{Available cipher modes}, for a list of supported cipher modes
+and the according constants. Note that some modes are incompatible
+with some algorithms - in particular, stream mode
+(@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers. Any
+block cipher mode (@code{GCRY_CIPHER_MODE_ECB},
+@code{GCRY_CIPHER_MODE_CBC}, @code{GCRY_CIPHER_MODE_CFB},
+@code{GCRY_CIPHER_MODE_OFB} or @code{GCRY_CIPHER_MODE_CTR}) will work
+with any block cipher algorithm.
+
+The third argument @var{flags} can either be passed as @code{0} or as
+the bit-wise OR of the following constants.
+
+@table @code
+@item GCRY_CIPHER_SECURE
+Make sure that all operations are allocated in secure memory. This is
+useful when the key material is highly confidential.
+@item GCRY_CIPHER_ENABLE_SYNC
+@cindex sync mode (OpenPGP)
+This flag enables the CFB sync mode, which is a special feature of
+Libgcrypt's CFB mode implementation to allow for OpenPGP's CFB variant.
+See @code{gcry_cipher_sync}.
+@item GCRY_CIPHER_CBC_CTS
+@cindex cipher text stealing
+Enable cipher text stealing (CTS) for the CBC mode. Cannot be used
+simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes it possible to
+transform data of almost arbitrary size (only limitation is that it
+must be greater than the algorithm's block size).
+@item GCRY_CIPHER_CBC_MAC
+@cindex CBC-MAC
+Compute CBC-MAC keyed checksums. This is the same as CBC mode, but
+only output the last block. Cannot be used simultaneous as
+GCRY_CIPHER_CBC_CTS.
+@end table
+@end deftypefun
+
+Use the following function to release an existing handle:
+
+@deftypefun void gcry_cipher_close (gcry_cipher_hd_t @var{h})
+
+This function releases the context created by @code{gcry_cipher_open}.
+It also zeroises all sensitive information associated with this cipher
+handle.
+@end deftypefun
+
+In order to use a handle for performing cryptographic operations, a
+`key' has to be set first:
+
+@deftypefun gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l})
+
+Set the key @var{k} used for encryption or decryption in the context
+denoted by the handle @var{h}. The length @var{l} (in bytes) of the
+key @var{k} must match the required length of the algorithm set for
+this context or be in the allowed range for algorithms with variable
+key size. The function checks this and returns an error if there is a
+problem. A caller should always check for an error.
+
+@end deftypefun
+
+Most crypto modes requires an initialization vector (IV), which
+usually is a non-secret random string acting as a kind of salt value.
+The CTR mode requires a counter, which is also similar to a salt
+value. To set the IV or CTR, use these functions:
+
+@deftypefun gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l})
+
+Set the initialization vector used for encryption or decryption. The
+vector is passed as the buffer @var{K} of length @var{l} bytes and
+copied to internal data structures. The function checks that the IV
+matches the requirement of the selected algorithm and mode.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l})
+
+Set the counter vector used for encryption or decryption. The counter
+is passed as the buffer @var{c} of length @var{l} bytes and copied to
+internal data structures. The function checks that the counter
+matches the requirement of the selected algorithm (i.e., it must be
+the same size as the block size).
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t @var{h})
+
+Set the given handle's context back to the state it had after the last
+call to gcry_cipher_setkey and clear the initialization vector.
+
+Note that gcry_cipher_reset is implemented as a macro.
+@end deftypefun
+
+The actual encryption and decryption is done by using one of the
+following functions. They may be used as often as required to process
+all the data.
+
+@deftypefun gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
+
+@code{gcry_cipher_encrypt} is used to encrypt the data. This function
+can either work in place or with two buffers. It uses the cipher
+context already setup and described by the handle @var{h}. There are 2
+ways to use the function: If @var{in} is passed as @code{NULL} and
+@var{inlen} is @code{0}, in-place encryption of the data in @var{out} or
+length @var{outsize} takes place. With @var{in} being not @code{NULL},
+@var{inlen} bytes are encrypted to the buffer @var{out} which must have
+at least a size of @var{inlen}. @var{outsize} must be set to the
+allocated size of @var{out}, so that the function can check that there
+is sufficient space. Note that overlapping buffers are not allowed.
+
+Depending on the selected algorithms and encryption mode, the length of
+the buffers must be a multiple of the block size.
+
+The function returns @code{0} on success or an error code.
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
+
+@code{gcry_cipher_decrypt} is used to decrypt the data. This function
+can either work in place or with two buffers. It uses the cipher
+context already setup and described by the handle @var{h}. There are 2
+ways to use the function: If @var{in} is passed as @code{NULL} and
+@var{inlen} is @code{0}, in-place decryption of the data in @var{out} or
+length @var{outsize} takes place. With @var{in} being not @code{NULL},
+@var{inlen} bytes are decrypted to the buffer @var{out} which must have
+at least a size of @var{inlen}. @var{outsize} must be set to the
+allocated size of @var{out}, so that the function can check that there
+is sufficient space. Note that overlapping buffers are not allowed.
+
+Depending on the selected algorithms and encryption mode, the length of
+the buffers must be a multiple of the block size.
+
+The function returns @code{0} on success or an error code.
+@end deftypefun
+
+
+OpenPGP (as defined in RFC-2440) requires a special sync operation in
+some places. The following function is used for this:
+
+@deftypefun gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t @var{h})
+
+Perform the OpenPGP sync operation on context @var{h}. Note that this
+is a no-op unless the context was created with the flag
+@code{GCRY_CIPHER_ENABLE_SYNC}
+@end deftypefun
+
+Some of the described functions are implemented as macros utilizing a
+catch-all control function. This control function is rarely used
+directly but there is nothing which would inhibit it:
+
+@deftypefun gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t @var{h}, int @var{cmd}, void *@var{buffer}, size_t @var{buflen})
+
+@code{gcry_cipher_ctl} controls various aspects of the cipher module and
+specific cipher contexts. Usually some more specialized functions or
+macros are used for this purpose. The semantics of the function and its
+parameters depends on the the command @var{cmd} and the passed context
+handle @var{h}. Please see the comments in the source code
+(@code{src/global.c}) for details.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_info (gcry_cipher_hd_t @var{h}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
+
+@code{gcry_cipher_info} is used to retrieve various
+information about a cipher context or the cipher module in general.
+
+Currently no information is available.
+@end deftypefun
+
+@node General cipher functions
+@section General cipher functions
+
+To work with the algorithms, several functions are available to map
+algorithm names to the internal identifiers, as well as ways to
+retrieve information about an algorithm or the current cipher context.
+
+@deftypefun gcry_error_t gcry_cipher_algo_info (int @var{algo}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
+
+This function is used to retrieve information on a specific algorithm.
+You pass the cipher algorithm ID as @var{algo} and the type of
+information requested as @var{what}. The result is either returned as
+the return code of the function or copied to the provided @var{buffer}
+whose allocated length must be available in an integer variable with the
+address passed in @var{nbytes}. This variable will also receive the
+actual used length of the buffer.
+
+Here is a list of supported codes for @var{what}:
+
+@c begin constants for gcry_cipher_algo_info
+@table @code
+@item GCRYCTL_GET_KEYLEN:
+Return the length of the key. If the algorithm supports multiple key
+lengths, the maximum supported value is returned. The length is
+returned as number of octets (bytes) and not as number of bits in
+@var{nbytes}; @var{buffer} must be zero.
+
+@item GCRYCTL_GET_BLKLEN:
+Return the block length of the algorithm. The length is returned as a
+number of octets in @var{nbytes}; @var{buffer} must be zero.
+
+@item GCRYCTL_TEST_ALGO:
+Returns @code{0} when the specified algorithm is available for use.
+@var{buffer} and @var{nbytes} must be zero.
+
+@end table
+@c end constants for gcry_cipher_algo_info
+
+@end deftypefun
+@c end gcry_cipher_algo_info
+
+@deftypefun {const char *} gcry_cipher_algo_name (int @var{algo})
+
+@code{gcry_cipher_algo_name} returns a string with the name of the
+cipher algorithm @var{algo}. If the algorithm is not known or another
+error occurred, the string @code{"?"} is returned. This function should
+not be used to test for the availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_cipher_map_name (const char *@var{name})
+
+@code{gcry_cipher_map_name} returns the algorithm identifier for the
+cipher algorithm described by the string @var{name}. If this algorithm
+is not available @code{0} is returned.
+@end deftypefun
+
+@deftypefun int gcry_cipher_mode_from_oid (const char *@var{string})
+
+Return the cipher mode associated with an @acronym{ASN.1} object
+identifier. The object identifier is expected to be in the
+@acronym{IETF}-style dotted decimal notation. The function returns
+@code{0} for an unknown object identifier or when no mode is associated
+with it.
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* Public Key *************************
+@c **********************************************************
+@node Public Key cryptography
+@chapter Public Key cryptography
+
+Public key cryptography, also known as asymmetric cryptography, is an
+easy way for key management and to provide digital signatures.
+Libgcrypt provides two completely different interfaces to
+public key cryptography, this chapter explains the one based on
+S-expressions.
+
+@menu
+* Available algorithms:: Algorithms supported by the library.
+* Used S-expressions:: Introduction into the used S-expression.
+* Public key modules:: How to work with public key modules.
+* Cryptographic Functions:: Functions for performing the cryptographic actions.
+* General public-key related Functions:: General functions, not implementing any cryptography.
+
+* AC Interface:: Alternative interface to public key functions.
+@end menu
+
+@node Available algorithms
+@section Available algorithms
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman) algorithms as well
+as DSA (Digital Signature Algorithm) and Elgamal. The versatile
+interface allows to add more algorithms in the future.
+
+@node Used S-expressions
+@section Used S-expressions
+
+Libgcrypt's API for asymmetric cryptography is based on data structures
+called S-expressions (see
+@uref{http://people.csail.mit.edu/@/rivest/@/sexp.html}) and does not work
+with contexts as most of the other building blocks of Libgcrypt do.
+
+@noindent
+The following information are stored in S-expressions:
+
+@itemize @asis
+@item keys
+
+@item plain text data
+
+@item encrypted data
+
+@item signatures
+
+@end itemize
+
+@noindent
+To describe how Libgcrypt expect keys, we use examples. Note that
+words in
+@ifnottex
+uppercase
+@end ifnottex
+@iftex
+italics
+@end iftex
+indicate parameters whereas lowercase words are literals.
+
+Note that all MPI (multi-precision-integers) values are expected to be in
+@code{GCRYMPI_FMT_USG} format. An easy way to create S-expressions is
+by using @code{gcry_sexp_build} which allows to pass a string with
+printf-like escapes to insert MPI values.
+
+@menu
+* RSA key parameters:: Parameters used with an RSA key.
+* DSA key parameters:: Parameters used with a DSA key.
+* ECC key parameters:: Parameters used with ECC keys.
+@end menu
+
+@node RSA key parameters
+@subsection RSA key parameters
+
+@noindent
+An RSA private key is described by this S-expression:
+
+@example
+(private-key
+ (rsa
+ (n @var{n-mpi})
+ (e @var{e-mpi})
+ (d @var{d-mpi})
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (u @var{u-mpi})))
+@end example
+
+@noindent
+An RSA public key is described by this S-expression:
+
+@example
+(public-key
+ (rsa
+ (n @var{n-mpi})
+ (e @var{e-mpi})))
+@end example
+
+
+@table @var
+@item n-mpi
+RSA public modulus @math{n}.
+@item e-mpi
+RSA public exponent @math{e}.
+@item d-mpi
+RSA secret exponent @math{d = e^{-1} \bmod (p-1)(q-1)}.
+@item p-mpi
+RSA secret prime @math{p}.
+@item q-mpi
+RSA secret prime @math{q} with @math{p < q}.
+@item u-mpi
+Multiplicative inverse @math{u = p^{-1} \bmod q}.
+@end table
+
+For signing and decryption the parameters @math{(p, q, u)} are optional
+but greatly improve the performance. Either all of these optional
+parameters must be given or none of them. They are mandatory for
+gcry_pk_testkey.
+
+Note that OpenSSL uses slighly different parameters: @math{q < p} and
+ @math{u = q^{-1} \bmod p}. To use these parameters you will need to
+swap the values and recompute @math{u}. Here is example code to do this:
+
+@example
+ if (gcry_mpi_cmp (p, q) > 0)
+ @{
+ gcry_mpi_swap (p, q);
+ gcry_mpi_invm (u, p, q);
+ @}
+@end example
+
+
+
+
+@node DSA key parameters
+@subsection DSA key parameters
+
+@noindent
+A DSA private key is described by this S-expression:
+
+@example
+(private-key
+ (dsa
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})
+ (x @var{x-mpi})))
+@end example
+
+@table @var
+@item p-mpi
+DSA prime @math{p}.
+@item q-mpi
+DSA group order @math{q} (which is a prime divisor of @math{p-1}).
+@item g-mpi
+DSA group generator @math{g}.
+@item y-mpi
+DSA public key value @math{y = g^x \bmod p}.
+@item x-mpi
+DSA secret exponent x.
+@end table
+
+The public key is similar with "private-key" replaced by "public-key"
+and no @var{x-mpi}.
+
+
+@node ECC key parameters
+@subsection ECC key parameters
+
+@noindent
+An ECC private key is described by this S-expression:
+
+@example
+(private-key
+ (ecc
+ (p @var{p-mpi})
+ (a @var{a-mpi})
+ (b @var{b-mpi})
+ (g @var{g-point})
+ (n @var{n-mpi})
+ (q @var{q-point})
+ (d @var{d-mpi})))
+@end example
+
+@table @var
+@item p-mpi
+Prime specifying the field @math{GF(p)}.
+@item a-mpi
+@itemx b-mpi
+The two coefficients of the Weierstrass equation @math{y^2 = x^3 + ax + b}
+@item g-point
+Base point @math{g}.
+@item n-mpi
+Order of @math{g}
+@item q-point
+The point representing the public key @math{Q = dP}.
+@item d-mpi
+The private key @math{d}
+@end table
+
+All point values are encoded in standard format; Libgcrypt does
+currently only support uncompressed points, thus the first byte needs to
+be @code{0x04}.
+
+The public key is similar with "private-key" replaced by "public-key"
+and no @var{d-mpi}.
+
+If the domain parameters are well-known, the name of this curve may be
+used. For example
+
+@example
+(private-key
+ (ecc
+ (curve "NIST P-192")
+ (q @var{q-point})
+ (d @var{d-mpi})))
+@end example
+
+The @code{curve} parameter may be given in any case and is used to replace
+missing parameters.
+
+@noindent
+Currently implemented curves are:
+@table @code
+@item NIST P-192
+@itemx 1.2.840.10045.3.1.1
+@itemx prime192v1
+@itemx secp192r1
+The NIST 192 bit curve, its OID, X9.62 and SECP aliases.
+
+@item NIST P-224
+@itemx secp224r1
+The NIST 224 bit curve and its SECP alias.
+
+@item NIST P-256
+@itemx 1.2.840.10045.3.1.7
+@itemx prime256v1
+@itemx secp256r1
+The NIST 256 bit curve, its OID, X9.62 and SECP aliases.
+
+@item NIST P-384
+@itemx secp384r1
+The NIST 384 bit curve and its SECP alias.
+
+@item NIST P-521
+@itemx secp521r1
+The NIST 521 bit curve and its SECP alias.
+
+@end table
+As usual the OIDs may optionally be prefixed with the string @code{OID.}
+or @code{oid.}.
+
+
+
+@node Public key modules
+@section Public key modules
+
+Libgcrypt makes it possible to load additional `public key
+modules'; these public key algorithms can be used just like the
+algorithms that are built into the library directly. For an
+introduction into extension modules, see @xref{Modules}.
+
+@deftp {Data type} gcry_pk_spec_t
+This is the `module specification structure' needed for registering
+public key modules, which has to be filled in by the user before it
+can be used to register a module. It contains the following members:
+
+@table @code
+@item const char *name
+The primary name of this algorithm.
+@item char **aliases
+A list of strings that are `aliases' for the algorithm. The list
+must be terminated with a NULL element.
+@item const char *elements_pkey
+String containing the one-letter names of the MPI values contained in
+a public key.
+@item const char *element_skey
+String containing the one-letter names of the MPI values contained in
+a secret key.
+@item const char *elements_enc
+String containing the one-letter names of the MPI values that are the
+result of an encryption operation using this algorithm.
+@item const char *elements_sig
+String containing the one-letter names of the MPI values that are the
+result of a sign operation using this algorithm.
+@item const char *elements_grip
+String containing the one-letter names of the MPI values that are to
+be included in the `key grip'.
+@item int use
+The bitwise-OR of the following flags, depending on the abilities of
+the algorithm:
+@table @code
+@item GCRY_PK_USAGE_SIGN
+The algorithm supports signing and verifying of data.
+@item GCRY_PK_USAGE_ENCR
+The algorithm supports the encryption and decryption of data.
+@end table
+@item gcry_pk_generate_t generate
+The function responsible for generating a new key pair. See below for
+a description of this type.
+@item gcry_pk_check_secret_key_t check_secret_key
+The function responsible for checking the sanity of a provided secret
+key. See below for a description of this type.
+@item gcry_pk_encrypt_t encrypt
+The function responsible for encrypting data. See below for a
+description of this type.
+@item gcry_pk_decrypt_t decrypt
+The function responsible for decrypting data. See below for a
+description of this type.
+@item gcry_pk_sign_t sign
+The function responsible for signing data. See below for a description
+of this type.
+@item gcry_pk_verify_t verify
+The function responsible for verifying that the provided signature
+matches the provided data. See below for a description of this type.
+@item gcry_pk_get_nbits_t get_nbits
+The function responsible for returning the number of bits of a provided
+key. See below for a description of this type.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_pk_generate_t
+Type for the `generate' function, defined as: gcry_err_code_t
+(*gcry_pk_generate_t) (int algo, unsigned int nbits, unsigned long
+use_e, gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+@end deftp
+
+@deftp {Data type} gcry_pk_check_secret_key_t
+Type for the `check_secret_key' function, defined as: gcry_err_code_t
+(*gcry_pk_check_secret_key_t) (int algo, gcry_mpi_t *skey)
+@end deftp
+
+@deftp {Data type} gcry_pk_encrypt_t
+Type for the `encrypt' function, defined as: gcry_err_code_t
+(*gcry_pk_encrypt_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+gcry_mpi_t *pkey, int flags)
+@end deftp
+
+@deftp {Data type} gcry_pk_decrypt_t
+Type for the `decrypt' function, defined as: gcry_err_code_t
+(*gcry_pk_decrypt_t) (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
+gcry_mpi_t *skey, int flags)
+@end deftp
+
+@deftp {Data type} gcry_pk_sign_t
+Type for the `sign' function, defined as: gcry_err_code_t
+(*gcry_pk_sign_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
+gcry_mpi_t *skey)
+@end deftp
+
+@deftp {Data type} gcry_pk_verify_t
+Type for the `verify' function, defined as: gcry_err_code_t
+(*gcry_pk_verify_t) (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
+gcry_mpi_t *pkey, int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+@end deftp
+
+@deftp {Data type} gcry_pk_get_nbits_t
+Type for the `get_nbits' function, defined as: unsigned
+(*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey)
+@end deftp
+
+@deftypefun gcry_error_t gcry_pk_register (gcry_pk_spec_t *@var{pubkey}, unsigned int *algorithm_id, gcry_module_t *@var{module})
+
+Register a new public key module whose specification can be found in
+@var{pubkey}. On success, a new algorithm ID is stored in
+@var{algorithm_id} and a pointer representing this module is stored in
+@var{module}. Deprecated; the module register interface will be
+removed in a future version.
+
+@end deftypefun
+
+@deftypefun void gcry_pk_unregister (gcry_module_t @var{module})
+Unregister the public key module identified by @var{module}, which
+must have been registered with gcry_pk_register.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_pk_list (int *@var{list}, int *@var{list_length})
+Get a list consisting of the IDs of the loaded pubkey modules. If
+@var{list} is zero, write the number of loaded pubkey modules to
+@var{list_length} and return. If @var{list} is non-zero, the first
+*@var{list_length} algorithm IDs are stored in @var{list}, which must
+be of according size. In case there are less pubkey modules than
+*@var{list_length}, *@var{list_length} is updated to the correct
+number.
+@end deftypefun
+
+@node Cryptographic Functions
+@section Cryptographic Functions
+
+@noindent
+Note that we will in future allow to use keys without p,q and u
+specified and may also support other parameters for performance
+reasons.
+
+@noindent
+
+Some functions operating on S-expressions support `flags', that
+influence the operation. These flags have to be listed in a
+sub-S-expression named `flags'; the following flags are known:
+
+@table @code
+@item pkcs1
+Use PKCS#1 block type 2 padding for encryption, block type 1 padding
+for signing.
+@item oaep
+Use RSA-OAEP padding for encryption.
+@item pss
+Use RSA-PSS padding for signing.
+@item no-blinding
+Do not use a technique called `blinding', which is used by default in
+order to prevent leaking of secret information. Blinding is only
+implemented by RSA, but it might be implemented by other algorithms in
+the future as well, when necessary.
+@end table
+
+@noindent
+Now that we know the key basics, we can carry on and explain how to
+encrypt and decrypt data. In almost all cases the data is a random
+session key which is in turn used for the actual encryption of the real
+data. There are 2 functions to do this:
+
+@deftypefun gcry_error_t gcry_pk_encrypt (@w{gcry_sexp_t *@var{r_ciph},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{pkey}})
+
+Obviously a public key must be provided for encryption. It is
+expected as an appropriate S-expression (see above) in @var{pkey}.
+The data to be encrypted can either be in the simple old format, which
+is a very simple S-expression consisting only of one MPI, or it may be
+a more complex S-expression which also allows to specify flags for
+operation, like e.g. padding rules.
+
+@noindent
+If you don't want to let Libgcrypt handle the padding, you must pass an
+appropriate MPI using this expression for @var{data}:
+
+@example
+(data
+ (flags raw)
+ (value @var{mpi}))
+@end example
+
+@noindent
+This has the same semantics as the old style MPI only way. @var{MPI}
+is the actual data, already padded appropriate for your protocol.
+Most RSA based systems however use PKCS#1 padding and so you can use
+this S-expression for @var{data}:
+
+@example
+(data
+ (flags pkcs1)
+ (value @var{block}))
+@end example
+
+@noindent
+Here, the "flags" list has the "pkcs1" flag which let the function know
+that it should provide PKCS#1 block type 2 padding. The actual data to
+be encrypted is passed as a string of octets in @var{block}. The
+function checks that this data actually can be used with the given key,
+does the padding and encrypts it.
+
+If the function could successfully perform the encryption, the return
+value will be 0 and a new S-expression with the encrypted result is
+allocated and assigned to the variable at the address of @var{r_ciph}.
+The caller is responsible to release this value using
+@code{gcry_sexp_release}. In case of an error, an error code is
+returned and @var{r_ciph} will be set to @code{NULL}.
+
+@noindent
+The returned S-expression has this format when used with RSA:
+
+@example
+(enc-val
+ (rsa
+ (a @var{a-mpi})))
+@end example
+
+@noindent
+Where @var{a-mpi} is an MPI with the result of the RSA operation. When
+using the Elgamal algorithm, the return value will have this format:
+
+@example
+(enc-val
+ (elg
+ (a @var{a-mpi})
+ (b @var{b-mpi})))
+@end example
+
+@noindent
+Where @var{a-mpi} and @var{b-mpi} are MPIs with the result of the
+Elgamal encryption operation.
+@end deftypefun
+@c end gcry_pk_encrypt
+
+@deftypefun gcry_error_t gcry_pk_decrypt (@w{gcry_sexp_t *@var{r_plain},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
+
+Obviously a private key must be provided for decryption. It is expected
+as an appropriate S-expression (see above) in @var{skey}. The data to
+be decrypted must match the format of the result as returned by
+@code{gcry_pk_encrypt}, but should be enlarged with a @code{flags}
+element:
+
+@example
+(enc-val
+ (flags)
+ (elg
+ (a @var{a-mpi})
+ (b @var{b-mpi})))
+@end example
+
+@noindent
+This function does not remove padding from the data by default. To
+let Libgcrypt remove padding, give a hint in `flags' telling which
+padding method was used when encrypting:
+
+@example
+(flags @var{padding-method})
+@end example
+
+@noindent
+Currently @var{padding-method} is either @code{pkcs1} for PKCS#1 block
+type 2 padding, or @code{oaep} for RSA-OAEP padding.
+
+@noindent
+The function returns 0 on success or an error code. The variable at the
+address of @var{r_plain} will be set to NULL on error or receive the
+decrypted value on success. The format of @var{r_plain} is a
+simple S-expression part (i.e. not a valid one) with just one MPI if
+there was no @code{flags} element in @var{data}; if at least an empty
+@code{flags} is passed in @var{data}, the format is:
+
+@example
+(value @var{plaintext})
+@end example
+@end deftypefun
+@c end gcry_pk_decrypt
+
+
+Another operation commonly performed using public key cryptography is
+signing data. In some sense this is even more important than
+encryption because digital signatures are an important instrument for
+key management. Libgcrypt supports digital signatures using
+2 functions, similar to the encryption functions:
+
+@deftypefun gcry_error_t gcry_pk_sign (@w{gcry_sexp_t *@var{r_sig},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
+
+This function creates a digital signature for @var{data} using the
+private key @var{skey} and place it into the variable at the address of
+@var{r_sig}. @var{data} may either be the simple old style S-expression
+with just one MPI or a modern and more versatile S-expression which
+allows to let Libgcrypt handle padding:
+
+@example
+ (data
+ (flags pkcs1)
+ (hash @var{hash-algo} @var{block}))
+@end example
+
+@noindent
+This example requests to sign the data in @var{block} after applying
+PKCS#1 block type 1 style padding. @var{hash-algo} is a string with the
+hash algorithm to be encoded into the signature, this may be any hash
+algorithm name as supported by Libgcrypt. Most likely, this will be
+"sha256" or "sha1". It is obvious that the length of @var{block} must
+match the size of that message digests; the function checks that this
+and other constraints are valid.
+
+@noindent
+If PKCS#1 padding is not required (because the caller does already
+provide a padded value), either the old format or better the following
+format should be used:
+
+@example
+(data
+ (flags raw)
+ (value @var{mpi}))
+@end example
+
+@noindent
+Here, the data to be signed is directly given as an @var{MPI}.
+
+@noindent
+The signature is returned as a newly allocated S-expression in
+@var{r_sig} using this format for RSA:
+
+@example
+(sig-val
+ (rsa
+ (s @var{s-mpi})))
+@end example
+
+Where @var{s-mpi} is the result of the RSA sign operation. For DSA the
+S-expression returned is:
+
+@example
+(sig-val
+ (dsa
+ (r @var{r-mpi})
+ (s @var{s-mpi})))
+@end example
+
+Where @var{r-mpi} and @var{s-mpi} are the result of the DSA sign
+operation. For Elgamal signing (which is slow, yields large numbers
+and probably is not as secure as the other algorithms), the same format is
+used with "elg" replacing "dsa".
+@end deftypefun
+@c end gcry_pk_sign
+
+@noindent
+The operation most commonly used is definitely the verification of a
+signature. Libgcrypt provides this function:
+
+@deftypefun gcry_error_t gcry_pk_verify (@w{gcry_sexp_t @var{sig}}, @w{gcry_sexp_t @var{data}}, @w{gcry_sexp_t @var{pkey}})
+
+This is used to check whether the signature @var{sig} matches the
+@var{data}. The public key @var{pkey} must be provided to perform this
+verification. This function is similar in its parameters to
+@code{gcry_pk_sign} with the exceptions that the public key is used
+instead of the private key and that no signature is created but a
+signature, in a format as created by @code{gcry_pk_sign}, is passed to
+the function in @var{sig}.
+
+@noindent
+The result is 0 for success (i.e. the data matches the signature), or an
+error code where the most relevant code is @code{GCRYERR_BAD_SIGNATURE}
+to indicate that the signature does not match the provided data.
+
+@end deftypefun
+@c end gcry_pk_verify
+
+@node General public-key related Functions
+@section General public-key related Functions
+
+@noindent
+A couple of utility functions are available to retrieve the length of
+the key, map algorithm identifiers and perform sanity checks:
+
+@deftypefun {const char *} gcry_pk_algo_name (int @var{algo})
+
+Map the public key algorithm id @var{algo} to a string representation of
+the algorithm name. For unknown algorithms this functions returns the
+string @code{"?"}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_pk_map_name (const char *@var{name})
+
+Map the algorithm @var{name} to a public key algorithm Id. Returns 0 if
+the algorithm name is not known.
+@end deftypefun
+
+@deftypefun int gcry_pk_test_algo (int @var{algo})
+
+Return 0 if the public key algorithm @var{algo} is available for use.
+Note that this is implemented as a macro.
+@end deftypefun
+
+
+@deftypefun {unsigned int} gcry_pk_get_nbits (gcry_sexp_t @var{key})
+
+Return what is commonly referred as the key length for the given
+public or private in @var{key}.
+@end deftypefun
+
+@deftypefun {unsigned char *} gcry_pk_get_keygrip (@w{gcry_sexp_t @var{key}}, @w{unsigned char *@var{array}})
+
+Return the so called "keygrip" which is the SHA-1 hash of the public key
+parameters expressed in a way depended on the algorithm. @var{array}
+must either provide space for 20 bytes or be @code{NULL}. In the latter
+case a newly allocated array of that size is returned. On success a
+pointer to the newly allocated space or to @var{array} is returned.
+@code{NULL} is returned to indicate an error which is most likely an
+unknown algorithm or one where a "keygrip" has not yet been defined.
+The function accepts public or secret keys in @var{key}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_pk_testkey (gcry_sexp_t @var{key})
+
+Return zero if the private key @var{key} is `sane', an error code otherwise.
+Note that it is not possible to check the `saneness' of a public key.
+
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_pk_algo_info (@w{int @var{algo}}, @w{int @var{what}}, @w{void *@var{buffer}}, @w{size_t *@var{nbytes}})
+
+Depending on the value of @var{what} return various information about
+the public key algorithm with the id @var{algo}. Note that the
+function returns @code{-1} on error and the actual error code must be
+retrieved using the function @code{gcry_errno}. The currently defined
+values for @var{what} are:
+
+@table @code
+@item GCRYCTL_TEST_ALGO:
+Return 0 if the specified algorithm is available for use.
+@var{buffer} must be @code{NULL}, @var{nbytes} may be passed as
+@code{NULL} or point to a variable with the required usage of the
+algorithm. This may be 0 for "don't care" or the bit-wise OR of these
+flags:
+
+@table @code
+@item GCRY_PK_USAGE_SIGN
+Algorithm is usable for signing.
+@item GCRY_PK_USAGE_ENCR
+Algorithm is usable for encryption.
+@end table
+
+Unless you need to test for the allowed usage, it is in general better
+to use the macro gcry_pk_test_algo instead.
+
+@item GCRYCTL_GET_ALGO_USAGE:
+Return the usage flags for the given algorithm. An invalid algorithm
+return 0. Disabled algorithms are ignored here because we
+want to know whether the algorithm is at all capable of a certain usage.
+
+@item GCRYCTL_GET_ALGO_NPKEY
+Return the number of elements the public key for algorithm @var{algo}
+consist of. Return 0 for an unknown algorithm.
+
+@item GCRYCTL_GET_ALGO_NSKEY
+Return the number of elements the private key for algorithm @var{algo}
+consist of. Note that this value is always larger than that of the
+public key. Return 0 for an unknown algorithm.
+
+@item GCRYCTL_GET_ALGO_NSIGN
+Return the number of elements a signature created with the algorithm
+@var{algo} consists of. Return 0 for an unknown algorithm or for an
+algorithm not capable of creating signatures.
+
+@item GCRYCTL_GET_ALGO_NENC
+Return the number of elements a encrypted message created with the algorithm
+@var{algo} consists of. Return 0 for an unknown algorithm or for an
+algorithm not capable of encryption.
+@end table
+
+@noindent
+Please note that parameters not required should be passed as @code{NULL}.
+@end deftypefun
+@c end gcry_pk_algo_info
+
+
+@deftypefun gcry_error_t gcry_pk_ctl (@w{int @var{cmd}}, @w{void *@var{buffer}}, @w{size_t @var{buflen}})
+
+This is a general purpose function to perform certain control
+operations. @var{cmd} controls what is to be done. The return value is
+0 for success or an error code. Currently supported values for
+@var{cmd} are:
+
+@table @code
+@item GCRYCTL_DISABLE_ALGO
+Disable the algorithm given as an algorithm id in @var{buffer}.
+@var{buffer} must point to an @code{int} variable with the algorithm id
+and @var{buflen} must have the value @code{sizeof (int)}.
+
+@end table
+@end deftypefun
+@c end gcry_pk_ctl
+
+@noindent
+Libgcrypt also provides a function to generate public key
+pairs:
+
+@deftypefun gcry_error_t gcry_pk_genkey (@w{gcry_sexp_t *@var{r_key}}, @w{gcry_sexp_t @var{parms}})
+
+This function create a new public key pair using information given in
+the S-expression @var{parms} and stores the private and the public key
+in one new S-expression at the address given by @var{r_key}. In case of
+an error, @var{r_key} is set to @code{NULL}. The return code is 0 for
+success or an error code otherwise.
+
+@noindent
+Here is an example for @var{parms} to create an 2048 bit RSA key:
+
+@example
+(genkey
+ (rsa
+ (nbits 4:2048)))
+@end example
+
+@noindent
+To create an Elgamal key, substitute "elg" for "rsa" and to create a DSA
+key use "dsa". Valid ranges for the key length depend on the
+algorithms; all commonly used key lengths are supported. Currently
+supported parameters are:
+
+@table @code
+@item nbits
+This is always required to specify the length of the key. The argument
+is a string with a number in C-notation. The value should be a multiple
+of 8.
+
+@item curve @var{name}
+For ECC a named curve may be used instead of giving the number of
+requested bits. This allows to request a specific curve to override a
+default selection Libgcrypt would have taken if @code{nbits} has been
+given. The available names are listed with the description of the ECC
+public key parameters.
+
+@item rsa-use-e
+This is only used with RSA to give a hint for the public exponent. The
+value will be used as a base to test for a usable exponent. Some values
+are special:
+
+@table @samp
+@item 0
+Use a secure and fast value. This is currently the number 41.
+@item 1
+Use a value as required by some crypto policies. This is currently
+the number 65537.
+@item 2
+Reserved
+@item > 2
+Use the given value.
+@end table
+
+@noindent
+If this parameter is not used, Libgcrypt uses for historic reasons
+65537.
+
+@item qbits
+This is only meanigful for DSA keys. If it is given the DSA key is
+generated with a Q parameyer of this size. If it is not given or zero
+Q is deduced from NBITS in this way:
+@table @samp
+@item 512 <= N <= 1024
+Q = 160
+@item N = 2048
+Q = 224
+@item N = 3072
+Q = 256
+@item N = 7680
+Q = 384
+@item N = 15360
+Q = 512
+@end table
+Note that in this case only the values for N, as given in the table,
+are allowed. When specifying Q all values of N in the range 512 to
+15680 are valid as long as they are multiples of 8.
+
+@item transient-key
+This is only meaningful for RSA, DSA, ECDSA, and ECDH keys. This is a flag
+with no value. If given the key is created using a faster and a
+somewhat less secure random number generator. This flag may be used for
+keys which are only used for a short time or per-message and do not require full
+cryptographic strength.
+
+@item domain
+This is only meaningful for DLP algorithms. If specified keys are
+generated with domain parameters taken from this list. The exact
+format of this parameter depends on the actual algorithm. It is
+currently only implemented for DSA using this format:
+
+@example
+(genkey
+ (dsa
+ (domain
+ (p @var{p-mpi})
+ (q @var{q-mpi})
+ (g @var{q-mpi}))))
+@end example
+
+@code{nbits} and @code{qbits} may not be specified because they are
+derived from the domain parameters.
+
+@item derive-parms
+This is currently only implemented for RSA and DSA keys. It is not
+allowed to use this together with a @code{domain} specification. If
+given, it is used to derive the keys using the given parameters.
+
+If given for an RSA key the X9.31 key generation algorithm is used
+even if libgcrypt is not in FIPS mode. If given for a DSA key, the
+FIPS 186 algorithm is used even if libgcrypt is not in FIPS mode.
+
+@example
+(genkey
+ (rsa
+ (nbits 4:1024)
+ (rsa-use-e 1:3)
+ (derive-parms
+ (Xp1 #1A1916DDB29B4EB7EB6732E128#)
+ (Xp2 #192E8AAC41C576C822D93EA433#)
+ (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D
+ 769D6D76646C7A792E16EBD89FE6FC5B605A6493
+ 39DFC925A86A4C6D150B71B9EEA02D68885F5009
+ B98BD984#)
+ (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)
+ (Xq2 #134E4CAA16D2350A21D775C404#)
+ (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D
+ 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325
+ 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34
+ 321DE34A#))))
+@end example
+
+@example
+(genkey
+ (dsa
+ (nbits 4:1024)
+ (derive-parms
+ (seed @var{seed-mpi}))))
+@end example
+
+
+@item use-x931
+@cindex X9.31
+Force the use of the ANSI X9.31 key generation algorithm instead of
+the default algorithm. This flag is only meaningful for RSA and
+usually not required. Note that this algorithm is implicitly used if
+either @code{derive-parms} is given or Libgcrypt is in FIPS mode.
+
+@item use-fips186
+@cindex FIPS 186
+Force the use of the FIPS 186 key generation algorithm instead of the
+default algorithm. This flag is only meaningful for DSA and usually
+not required. Note that this algorithm is implicitly used if either
+@code{derive-parms} is given or Libgcrypt is in FIPS mode. As of now
+FIPS 186-2 is implemented; after the approval of FIPS 186-3 the code
+will be changed to implement 186-3.
+
+
+@item use-fips186-2
+Force the use of the FIPS 186-2 key generation algorithm instead of
+the default algorithm. This algorithm is slighlty different from
+FIPS 186-3 and allows only 1024 bit keys. This flag is only meaningful
+for DSA and only required for FIPS testing backward compatibility.
+
+
+@end table
+@c end table of parameters
+
+@noindent
+The key pair is returned in a format depending on the algorithm. Both
+private and public keys are returned in one container and may be
+accompanied by some miscellaneous information.
+
+@noindent
+As an example, here is what the Elgamal key generation returns:
+
+@example
+(key-data
+ (public-key
+ (elg
+ (p @var{p-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})))
+ (private-key
+ (elg
+ (p @var{p-mpi})
+ (g @var{g-mpi})
+ (y @var{y-mpi})
+ (x @var{x-mpi})))
+ (misc-key-info
+ (pm1-factors @var{n1 n2 ... nn}))
+@end example
+
+@noindent
+As you can see, some of the information is duplicated, but this
+provides an easy way to extract either the public or the private key.
+Note that the order of the elements is not defined, e.g. the private
+key may be stored before the public key. @var{n1 n2 ... nn} is a list
+of prime numbers used to composite @var{p-mpi}; this is in general not
+a very useful information and only available if the key generation
+algorithm provides them.
+@end deftypefun
+@c end gcry_pk_genkey
+
+@node AC Interface
+@section Alternative Public Key Interface
+
+This section documents the alternative interface to asymmetric
+cryptography (ac) that is not based on S-expressions, but on native C
+data structures. As opposed to the pk interface described in the
+former chapter, this one follows an open/use/close paradigm like other
+building blocks of the library.
+
+@strong{This interface has a few known problems; most noteworthy an
+inherent tendency to leak memory. It might not be available in
+forthcoming versions of Libgcrypt.}
+
+
+@menu
+* Available asymmetric algorithms:: List of algorithms supported by the library.
+* Working with sets of data:: How to work with sets of data.
+* Working with IO objects:: How to work with IO objects.
+* Working with handles:: How to use handles.
+* Working with keys:: How to work with keys.
+* Using cryptographic functions:: How to perform cryptographic operations.
+* Handle-independent functions:: General functions independent of handles.
+@end menu
+
+@node Available asymmetric algorithms
+@subsection Available asymmetric algorithms
+
+Libgcrypt supports the RSA (Rivest-Shamir-Adleman)
+algorithms as well as DSA (Digital Signature Algorithm) and Elgamal.
+The versatile interface allows to add more algorithms in the future.
+
+@deftp {Data type} gcry_ac_id_t
+
+The following constants are defined for this type:
+
+@table @code
+@item GCRY_AC_RSA
+Rivest-Shamir-Adleman
+@item GCRY_AC_DSA
+Digital Signature Algorithm
+@item GCRY_AC_ELG
+Elgamal
+@item GCRY_AC_ELG_E
+Elgamal, encryption only.
+@end table
+@end deftp
+
+@node Working with sets of data
+@subsection Working with sets of data
+
+In the context of this interface the term `data set' refers to a list
+of `named MPI values' that is used by functions performing
+cryptographic operations; a named MPI value is a an MPI value,
+associated with a label.
+
+Such data sets are used for representing keys, since keys simply
+consist of a variable amount of numbers. Furthermore some functions
+return data sets to the caller that are to be provided to other
+functions.
+
+This section documents the data types, symbols and functions that are
+relevant for working with data sets.
+
+@deftp {Data type} gcry_ac_data_t
+A single data set.
+@end deftp
+
+The following flags are supported:
+
+@table @code
+@item GCRY_AC_FLAG_DEALLOC
+Used for storing data in a data set. If given, the data will be
+released by the library. Note that whenever one of the ac functions
+is about to release objects because of this flag, the objects are
+expected to be stored in memory allocated through the Libgcrypt memory
+management. In other words: gcry_free() is used instead of free().
+
+@item GCRY_AC_FLAG_COPY
+Used for storing/retrieving data in/from a data set. If given, the
+library will create copies of the provided/contained data, which will
+then be given to the user/associated with the data set.
+@end table
+
+@deftypefun gcry_error_t gcry_ac_data_new (gcry_ac_data_t *@var{data})
+Creates a new, empty data set and stores it in @var{data}.
+@end deftypefun
+
+@deftypefun void gcry_ac_data_destroy (gcry_ac_data_t @var{data})
+Destroys the data set @var{data}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_set (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t @var{mpi})
+Add the value @var{mpi} to @var{data} with the label @var{name}. If
+@var{flags} contains GCRY_AC_FLAG_COPY, the data set will contain
+copies of @var{name} and @var{mpi}. If @var{flags} contains
+GCRY_AC_FLAG_DEALLOC or GCRY_AC_FLAG_COPY, the values
+contained in the data set will be deallocated when they are to be
+removed from the data set.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *@var{data_cp}, gcry_ac_data_t @var{data})
+Create a copy of the data set @var{data} and store it in
+@var{data_cp}. FIXME: exact semantics undefined.
+@end deftypefun
+
+@deftypefun {unsigned int} gcry_ac_data_length (gcry_ac_data_t @var{data})
+Returns the number of named MPI values inside of the data set
+@var{data}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t *@var{mpi})
+Store the value labelled with @var{name} found in @var{data} in
+@var{mpi}. If @var{flags} contains GCRY_AC_FLAG_COPY, store a copy of
+the @var{mpi} value contained in the data set. @var{mpi} may be NULL
+(this might be useful for checking the existence of an MPI with
+extracting it).
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t @var{data}, unsigned int flags, unsigned int @var{index}, const char **@var{name}, gcry_mpi_t *@var{mpi})
+Stores in @var{name} and @var{mpi} the named @var{mpi} value contained
+in the data set @var{data} with the index @var{idx}. If @var{flags}
+contains GCRY_AC_FLAG_COPY, store copies of the values contained in
+the data set. @var{name} or @var{mpi} may be NULL.
+@end deftypefun
+
+@deftypefun void gcry_ac_data_clear (gcry_ac_data_t @var{data})
+Destroys any values contained in the data set @var{data}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t @var{data}, gcry_sexp_t *@var{sexp}, const char **@var{identifiers})
+This function converts the data set @var{data} into a newly created
+S-Expression, which is to be stored in @var{sexp}; @var{identifiers}
+is a NULL terminated list of C strings, which specifies the structure
+of the S-Expression.
+
+Example:
+
+If @var{identifiers} is a list of pointers to the strings ``foo'' and
+``bar'' and if @var{data} is a data set containing the values ``val1 =
+0x01'' and ``val2 = 0x02'', then the resulting S-Expression will look
+like this: (foo (bar ((val1 0x01) (val2 0x02))).
+@end deftypefun
+
+@deftypefun gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *@var{data}, gcry_sexp_t @var{sexp}, const char **@var{identifiers})
+This function converts the S-Expression @var{sexp} into a newly
+created data set, which is to be stored in @var{data};
+@var{identifiers} is a NULL terminated list of C strings, which
+specifies the structure of the S-Expression. If the list of
+identifiers does not match the structure of the S-Expression, the
+function fails.
+@end deftypefun
+
+@node Working with IO objects
+@subsection Working with IO objects
+
+Note: IO objects are currently only used in the context of message
+encoding/decoding and encryption/signature schemes.
+
+@deftp {Data type} {gcry_ac_io_t}
+@code{gcry_ac_io_t} is the type to be used for IO objects.
+@end deftp
+
+IO objects provide an uniform IO layer on top of different underlying
+IO mechanisms; either they can be used for providing data to the
+library (mode is GCRY_AC_IO_READABLE) or they can be used for
+retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).
+
+IO object need to be initialized by calling on of the following
+functions:
+
+@deftypefun void gcry_ac_io_init (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, ...);
+Initialize @var{ac_io} according to @var{mode}, @var{type} and the
+variable list of arguments. The list of variable arguments to specify
+depends on the given @var{type}.
+@end deftypefun
+
+@deftypefun void gcry_ac_io_init_va (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, va_list @var{ap});
+Initialize @var{ac_io} according to @var{mode}, @var{type} and the
+variable list of arguments @var{ap}. The list of variable arguments
+to specify depends on the given @var{type}.
+@end deftypefun
+
+The following types of IO objects exist:
+
+@table @code
+@item GCRY_AC_IO_STRING
+In case of GCRY_AC_IO_READABLE the IO object will provide data from a
+memory string. Arguments to specify at initialization time:
+@table @code
+@item unsigned char *
+Pointer to the beginning of the memory string
+@item size_t
+Size of the memory string
+@end table
+In case of GCRY_AC_IO_WRITABLE the object will store retrieved data in
+a newly allocated memory string. Arguments to specify at
+initialization time:
+@table @code
+@item unsigned char **
+Pointer to address, at which the pointer to the newly created memory
+string is to be stored
+@item size_t *
+Pointer to address, at which the size of the newly created memory
+string is to be stored
+@end table
+
+@item GCRY_AC_IO_CALLBACK
+In case of GCRY_AC_IO_READABLE the object will forward read requests
+to a provided callback function. Arguments to specify at
+initialization time:
+@table @code
+@item gcry_ac_data_read_cb_t
+Callback function to use
+@item void *
+Opaque argument to provide to the callback function
+@end table
+In case of GCRY_AC_IO_WRITABLE the object will forward write requests
+to a provided callback function. Arguments to specify at
+initialization time:
+@table @code
+@item gcry_ac_data_write_cb_t
+Callback function to use
+@item void *
+Opaque argument to provide to the callback function
+@end table
+@end table
+
+@node Working with handles
+@subsection Working with handles
+
+In order to use an algorithm, an according handle must be created.
+This is done using the following function:
+
+@deftypefun gcry_error_t gcry_ac_open (gcry_ac_handle_t *@var{handle}, int @var{algorithm}, int @var{flags})
+
+Creates a new handle for the algorithm @var{algorithm} and stores it
+in @var{handle}. @var{flags} is not used currently.
+
+@var{algorithm} must be a valid algorithm ID, see @xref{Available
+asymmetric algorithms}, for a list of supported algorithms and the
+according constants. Besides using the listed constants directly, the
+functions @code{gcry_pk_name_to_id} may be used to convert the textual
+name of an algorithm into the according numeric ID.
+@end deftypefun
+
+@deftypefun void gcry_ac_close (gcry_ac_handle_t @var{handle})
+Destroys the handle @var{handle}.
+@end deftypefun
+
+@node Working with keys
+@subsection Working with keys
+
+@deftp {Data type} gcry_ac_key_type_t
+Defined constants:
+
+@table @code
+@item GCRY_AC_KEY_SECRET
+Specifies a secret key.
+@item GCRY_AC_KEY_PUBLIC
+Specifies a public key.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_ac_key_t
+This type represents a single `key', either a secret one or a public
+one.
+@end deftp
+
+@deftp {Data type} gcry_ac_key_pair_t
+This type represents a `key pair' containing a secret and a public key.
+@end deftp
+
+Key data structures can be created in two different ways; a new key
+pair can be generated, resulting in ready-to-use key. Alternatively a
+key can be initialized from a given data set.
+
+@deftypefun gcry_error_t gcry_ac_key_init (gcry_ac_key_t *@var{key}, gcry_ac_handle_t @var{handle}, gcry_ac_key_type_t @var{type}, gcry_ac_data_t @var{data})
+Creates a new key of type @var{type}, consisting of the MPI values
+contained in the data set @var{data} and stores it in @var{key}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t @var{handle}, unsigned int @var{nbits}, void *@var{key_spec}, gcry_ac_key_pair_t *@var{key_pair}, gcry_mpi_t **@var{misc_data})
+
+Generates a new key pair via the handle @var{handle} of @var{NBITS}
+bits and stores it in @var{key_pair}.
+
+In case non-standard settings are wanted, a pointer to a structure of
+type @code{gcry_ac_key_spec_<algorithm>_t}, matching the selected
+algorithm, can be given as @var{key_spec}. @var{misc_data} is not
+used yet. Such a structure does only exist for RSA. A description
+of the members of the supported structures follows.
+
+@table @code
+@item gcry_ac_key_spec_rsa_t
+@table @code
+@item gcry_mpi_t e
+Generate the key pair using a special @code{e}. The value of @code{e}
+has the following meanings:
+@table @code
+@item = 0
+Let Libgcrypt decide what exponent should be used.
+@item = 1
+Request the use of a ``secure'' exponent; this is required by some
+specification to be 65537.
+@item > 2
+Try starting at this value until a working exponent is found. Note
+that the current implementation leaks some information about the
+private key because the incrementation used is not randomized. Thus,
+this function will be changed in the future to return a random
+exponent of the given size.
+@end table
+@end table
+@end table
+
+Example code:
+@example
+@{
+ gcry_ac_key_pair_t key_pair;
+ gcry_ac_key_spec_rsa_t rsa_spec;
+
+ rsa_spec.e = gcry_mpi_new (0);
+ gcry_mpi_set_ui (rsa_spec.e, 1);
+
+ err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
+ assert (! err);
+
+ err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec,
+ &key_pair, NULL);
+ assert (! err);
+@}
+@end example
+@end deftypefun
+
+
+@deftypefun gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t @var{key_pair}, gcry_ac_key_type_t @var{which})
+Returns the key of type @var{which} out of the key pair
+@var{key_pair}.
+@end deftypefun
+
+@deftypefun void gcry_ac_key_destroy (gcry_ac_key_t @var{key})
+Destroys the key @var{key}.
+@end deftypefun
+
+@deftypefun void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t @var{key_pair})
+Destroys the key pair @var{key_pair}.
+@end deftypefun
+
+@deftypefun gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t @var{key})
+Returns the data set contained in the key @var{key}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_key_test (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key})
+Verifies that the private key @var{key} is sane via @var{handle}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned int *@var{nbits})
+Stores the number of bits of the key @var{key} in @var{nbits} via @var{handle}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned char *@var{key_grip})
+Writes the 20 byte long key grip of the key @var{key} to
+@var{key_grip} via @var{handle}.
+@end deftypefun
+
+@node Using cryptographic functions
+@subsection Using cryptographic functions
+
+The following flags might be relevant:
+
+@table @code
+@item GCRY_AC_FLAG_NO_BLINDING
+Disable any blinding, which might be supported by the chosen
+algorithm; blinding is the default.
+@end table
+
+There exist two kinds of cryptographic functions available through the
+ac interface: primitives, and high-level functions.
+
+Primitives deal with MPIs (data sets) directly; what they provide is
+direct access to the cryptographic operations provided by an algorithm
+implementation.
+
+High-level functions deal with octet strings, according to a specified
+``scheme''. Schemes make use of ``encoding methods'', which are
+responsible for converting the provided octet strings into MPIs, which
+are then forwared to the cryptographic primitives. Since schemes are
+to be used for a special purpose in order to achieve a particular
+security goal, there exist ``encryption schemes'' and ``signature
+schemes''. Encoding methods can be used seperately or implicitly
+through schemes.
+
+What follows is a description of the cryptographic primitives.
+
+@deftypefun gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data_plain}, gcry_ac_data_t *@var{data_encrypted})
+Encrypts the plain text MPI value @var{data_plain} with the key public
+@var{key} under the control of the flags @var{flags} and stores the
+resulting data set into @var{data_encrypted}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t *@var{data_plain}, gcry_ac_data_t @var{data_encrypted})
+Decrypts the encrypted data contained in the data set
+@var{data_encrypted} with the secret key KEY under the control of the
+flags @var{flags} and stores the resulting plain text MPI value in
+@var{DATA_PLAIN}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t *@var{data_signature})
+Signs the data contained in @var{data} with the secret key @var{key}
+and stores the resulting signature in the data set
+@var{data_signature}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t @var{data_signature})
+Verifies that the signature contained in the data set
+@var{data_signature} is indeed the result of signing the data
+contained in @var{data} with the secret key belonging to the public
+key @var{key}.
+@end deftypefun
+
+What follows is a description of the high-level functions.
+
+The type ``gcry_ac_em_t'' is used for specifying encoding methods; the
+following methods are supported:
+
+@table @code
+@item GCRY_AC_EME_PKCS_V1_5
+PKCS-V1_5 Encoding Method for Encryption. Options must be provided
+through a pointer to a correctly initialized object of type
+gcry_ac_eme_pkcs_v1_5_t.
+
+@item GCRY_AC_EMSA_PKCS_V1_5
+PKCS-V1_5 Encoding Method for Signatures with Appendix. Options must
+be provided through a pointer to a correctly initialized object of
+type gcry_ac_emsa_pkcs_v1_5_t.
+@end table
+
+Option structure types:
+
+@table @code
+@item gcry_ac_eme_pkcs_v1_5_t
+@table @code
+@item gcry_ac_key_t key
+@item gcry_ac_handle_t handle
+@end table
+@item gcry_ac_emsa_pkcs_v1_5_t
+@table @code
+@item gcry_md_algo_t md
+@item size_t em_n
+@end table
+@end table
+
+Encoding methods can be used directly through the following functions:
+
+@deftypefun gcry_error_t gcry_ac_data_encode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{m}, size_t @var{m_n}, unsigned char **@var{em}, size_t *@var{em_n})
+Encodes the message contained in @var{m} of size @var{m_n} according
+to @var{method}, @var{flags} and @var{options}. The newly created
+encoded message is stored in @var{em} and @var{em_n}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_decode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{em}, size_t @var{em_n}, unsigned char **@var{m}, size_t *@var{m_n})
+Decodes the message contained in @var{em} of size @var{em_n} according
+to @var{method}, @var{flags} and @var{options}. The newly created
+decoded message is stored in @var{m} and @var{m_n}.
+@end deftypefun
+
+The type ``gcry_ac_scheme_t'' is used for specifying schemes; the
+following schemes are supported:
+
+@table @code
+@item GCRY_AC_ES_PKCS_V1_5
+PKCS-V1_5 Encryption Scheme. No options can be provided.
+@item GCRY_AC_SSA_PKCS_V1_5
+PKCS-V1_5 Signature Scheme (with Appendix). Options can be provided
+through a pointer to a correctly initialized object of type
+gcry_ac_ssa_pkcs_v1_5_t.
+@end table
+
+Option structure types:
+
+@table @code
+@item gcry_ac_ssa_pkcs_v1_5_t
+@table @code
+@item gcry_md_algo_t md
+@end table
+@end table
+
+The functions implementing schemes:
+
+@deftypefun gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_cipher})
+Encrypts the plain text readable from @var{io_message} through
+@var{handle} with the public key @var{key} according to @var{scheme},
+@var{flags} and @var{opts}. If @var{opts} is not NULL, it has to be a
+pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t).
+The encrypted message is written to @var{io_cipher}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_cipher}, gcry_ac_io_t *@var{io_message})
+Decrypts the cipher text readable from @var{io_cipher} through
+@var{handle} with the secret key @var{key} according to @var{scheme},
+@var{flags} and @var{opts}. If @var{opts} is not NULL, it has to be a
+pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t).
+The decrypted message is written to @var{io_message}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
+Signs the message readable from @var{io_message} through @var{handle}
+with the secret key @var{key} according to @var{scheme}, @var{flags}
+and @var{opts}. If @var{opts} is not NULL, it has to be a pointer to
+a structure specific to the chosen scheme (gcry_ac_ssa_*_t). The
+signature is written to @var{io_signature}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
+Verifies through @var{handle} that the signature readable from
+@var{io_signature} is indeed the result of signing the message
+readable from @var{io_message} with the secret key belonging to the
+public key @var{key} according to @var{scheme} and @var{opts}. If
+@var{opts} is not NULL, it has to be an anonymous structure
+(gcry_ac_ssa_*_t) specific to the chosen scheme.
+@end deftypefun
+
+@node Handle-independent functions
+@subsection Handle-independent functions
+
+These two functions are deprecated; do not use them for new code.
+
+@deftypefun gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t @var{algorithm}, const char **@var{name})
+Stores the textual representation of the algorithm whose id is given
+in @var{algorithm} in @var{name}. Deprecated; use @code{gcry_pk_algo_name}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_ac_name_to_id (const char *@var{name}, gcry_ac_id_t *@var{algorithm})
+Stores the numeric ID of the algorithm whose textual representation is
+contained in @var{name} in @var{algorithm}. Deprecated; use
+@code{gcry_pk_map_name}.
+@end deftypefun
+
+@c **********************************************************
+@c ******************* Hash Functions *********************
+@c **********************************************************
+@node Hashing
+@chapter Hashing
+
+Libgcrypt provides an easy and consistent to use interface for hashing.
+Hashing is buffered and several hash algorithms can be updated at once.
+It is possible to compute a MAC using the same routines. The
+programming model follows an open/process/close paradigm and is in that
+similar to other building blocks provided by Libgcrypt.
+
+For convenience reasons, a few cyclic redundancy check value operations
+are also supported.
+
+@menu
+* Available hash algorithms:: List of hash algorithms supported by the library.
+* Hash algorithm modules:: How to work with hash algorithm modules.
+* Working with hash algorithms:: List of functions related to hashing.
+@end menu
+
+@node Available hash algorithms
+@section Available hash algorithms
+
+@c begin table of hash algorithms
+@cindex SHA-1
+@cindex SHA-224, SHA-256, SHA-384, SHA-512
+@cindex RIPE-MD-160
+@cindex MD2, MD4, MD5
+@cindex TIGER, TIGER1, TIGER2
+@cindex HAVAL
+@cindex Whirlpool
+@cindex CRC32
+@table @code
+@item GCRY_MD_NONE
+This is not a real algorithm but used by some functions as an error
+return value. This constant is guaranteed to have the value @code{0}.
+
+@item GCRY_MD_SHA1
+This is the SHA-1 algorithm which yields a message digest of 20 bytes.
+Note that SHA-1 begins to show some weaknesses and it is suggested to
+fade out its use if strong cryptographic properties are required.
+
+@item GCRY_MD_RMD160
+This is the 160 bit version of the RIPE message digest (RIPE-MD-160).
+Like SHA-1 it also yields a digest of 20 bytes. This algorithm share a
+lot of design properties with SHA-1 and thus it is advisable not to use
+it for new protocols.
+
+@item GCRY_MD_MD5
+This is the well known MD5 algorithm, which yields a message digest of
+16 bytes. Note that the MD5 algorithm has severe weaknesses, for
+example it is easy to compute two messages yielding the same hash
+(collision attack). The use of this algorithm is only justified for
+non-cryptographic application.
+
+
+@item GCRY_MD_MD4
+This is the MD4 algorithm, which yields a message digest of 16 bytes.
+This algorithms ha severe weaknesses and should not be used.
+
+@item GCRY_MD_MD2
+This is an reserved identifier for MD-2; there is no implementation yet.
+This algorithm has severe weaknesses and should not be used.
+
+@item GCRY_MD_TIGER
+This is the TIGER/192 algorithm which yields a message digest of 24
+bytes. Actually this is a variant of TIGER with a different output
+print order as used by GnuPG up to version 1.3.2.
+
+@item GCRY_MD_TIGER1
+This is the TIGER variant as used by the NESSIE project. It uses the
+most commonly used output print order.
+
+@item GCRY_MD_TIGER2
+This is another variant of TIGER with a different padding scheme.
+
+
+@item GCRY_MD_HAVAL
+This is an reserved value for the HAVAL algorithm with 5 passes and 160
+bit. It yields a message digest of 20 bytes. Note that there is no
+implementation yet available.
+
+@item GCRY_MD_SHA224
+This is the SHA-224 algorithm which yields a message digest of 28 bytes.
+See Change Notice 1 for FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA256
+This is the SHA-256 algorithm which yields a message digest of 32 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA384
+This is the SHA-384 algorithm which yields a message digest of 48 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_SHA512
+This is the SHA-384 algorithm which yields a message digest of 64 bytes.
+See FIPS 180-2 for the specification.
+
+@item GCRY_MD_CRC32
+This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It yields
+an output of 4 bytes. Note that this is not a hash algorithm in the
+cryptographic sense.
+
+@item GCRY_MD_CRC32_RFC1510
+This is the above cyclic redundancy check function, as modified by RFC
+1510. It yields an output of 4 bytes. Note that this is not a hash
+algorithm in the cryptographic sense.
+
+@item GCRY_MD_CRC24_RFC2440
+This is the OpenPGP cyclic redundancy check function. It yields an
+output of 3 bytes. Note that this is not a hash algorithm in the
+cryptographic sense.
+
+@item GCRY_MD_WHIRLPOOL
+This is the Whirlpool algorithm which yields a message digest of 64
+bytes.
+
+@end table
+@c end table of hash algorithms
+
+@node Hash algorithm modules
+@section Hash algorithm modules
+
+Libgcrypt makes it possible to load additional `message
+digest modules'; these digests can be used just like the message digest
+algorithms that are built into the library directly. For an
+introduction into extension modules, see @xref{Modules}.
+
+@deftp {Data type} gcry_md_spec_t
+This is the `module specification structure' needed for registering
+message digest modules, which has to be filled in by the user before
+it can be used to register a module. It contains the following
+members:
+
+@table @code
+@item const char *name
+The primary name of this algorithm.
+@item unsigned char *asnoid
+Array of bytes that form the ASN OID.
+@item int asnlen
+Length of bytes in `asnoid'.
+@item gcry_md_oid_spec_t *oids
+A list of OIDs that are to be associated with the algorithm. The
+list's last element must have it's `oid' member set to NULL. See
+below for an explanation of this type. See below for an explanation
+of this type.
+@item int mdlen
+Length of the message digest algorithm. See below for an explanation
+of this type.
+@item gcry_md_init_t init
+The function responsible for initializing a handle. See below for an
+explanation of this type.
+@item gcry_md_write_t write
+The function responsible for writing data into a message digest
+context. See below for an explanation of this type.
+@item gcry_md_final_t final
+The function responsible for `finalizing' a message digest context.
+See below for an explanation of this type.
+@item gcry_md_read_t read
+The function responsible for reading out a message digest result. See
+below for an explanation of this type.
+@item size_t contextsize
+The size of the algorithm-specific `context', that should be
+allocated for each handle.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_md_oid_spec_t
+This type is used for associating a user-provided algorithm
+implementation with certain OIDs. It contains the following members:
+
+@table @code
+@item const char *oidstring
+Textual representation of the OID.
+@end table
+@end deftp
+
+@deftp {Data type} gcry_md_init_t
+Type for the `init' function, defined as: void (*gcry_md_init_t) (void
+*c)
+@end deftp
+
+@deftp {Data type} gcry_md_write_t
+Type for the `write' function, defined as: void (*gcry_md_write_t)
+(void *c, unsigned char *buf, size_t nbytes)
+@end deftp
+
+@deftp {Data type} gcry_md_final_t
+Type for the `final' function, defined as: void (*gcry_md_final_t)
+(void *c)
+@end deftp
+
+@deftp {Data type} gcry_md_read_t
+Type for the `read' function, defined as: unsigned char
+*(*gcry_md_read_t) (void *c)
+@end deftp
+
+@deftypefun gcry_error_t gcry_md_register (gcry_md_spec_t *@var{digest}, unsigned int *algorithm_id, gcry_module_t *@var{module})
+
+Register a new digest module whose specification can be found in
+@var{digest}. On success, a new algorithm ID is stored in
+@var{algorithm_id} and a pointer representing this module is stored
+in @var{module}. Deprecated; the module register interface will be
+removed in a future version.
+@end deftypefun
+
+@deftypefun void gcry_md_unregister (gcry_module_t @var{module})
+Unregister the digest identified by @var{module}, which must have been
+registered with gcry_md_register.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_md_list (int *@var{list}, int *@var{list_length})
+Get a list consisting of the IDs of the loaded message digest modules.
+If @var{list} is zero, write the number of loaded message digest
+modules to @var{list_length} and return. If @var{list} is non-zero,
+the first *@var{list_length} algorithm IDs are stored in @var{list},
+which must be of according size. In case there are less message
+digests modules than *@var{list_length}, *@var{list_length} is updated
+to the correct number.
+@end deftypefun
+
+@node Working with hash algorithms
+@section Working with hash algorithms
+
+To use most of these function it is necessary to create a context;
+this is done using:
+
+@deftypefun gcry_error_t gcry_md_open (gcry_md_hd_t *@var{hd}, int @var{algo}, unsigned int @var{flags})
+
+Create a message digest object for algorithm @var{algo}. @var{flags}
+may be given as an bitwise OR of constants described below. @var{algo}
+may be given as @code{0} if the algorithms to use are later set using
+@code{gcry_md_enable}. @var{hd} is guaranteed to either receive a valid
+handle or NULL.
+
+For a list of supported algorithms, see @xref{Available hash
+algorithms}.
+
+The flags allowed for @var{mode} are:
+
+@c begin table of hash flags
+@table @code
+@item GCRY_MD_FLAG_SECURE
+Allocate all buffers and the resulting digest in "secure memory". Use
+this is the hashed data is highly confidential.
+
+@item GCRY_MD_FLAG_HMAC
+@cindex HMAC
+Turn the algorithm into a HMAC message authentication algorithm. This
+only works if just one algorithm is enabled for the handle. Note that
+the function @code{gcry_md_setkey} must be used to set the MAC key.
+The size of the MAC is equal to the message digest of the underlying
+hash algorithm. If you want CBC message authentication codes based on
+a cipher, see @xref{Working with cipher handles}.
+
+@end table
+@c begin table of hash flags
+
+You may use the function @code{gcry_md_is_enabled} to later check
+whether an algorithm has been enabled.
+
+@end deftypefun
+@c end function gcry_md_open
+
+If you want to calculate several hash algorithms at the same time, you
+have to use the following function right after the @code{gcry_md_open}:
+
+@deftypefun gcry_error_t gcry_md_enable (gcry_md_hd_t @var{h}, int @var{algo})
+
+Add the message digest algorithm @var{algo} to the digest object
+described by handle @var{h}. Duplicated enabling of algorithms is
+detected and ignored.
+@end deftypefun
+
+If the flag @code{GCRY_MD_FLAG_HMAC} was used, the key for the MAC must
+be set using the function:
+
+@deftypefun gcry_error_t gcry_md_setkey (gcry_md_hd_t @var{h}, const void *@var{key}, size_t @var{keylen})
+
+For use with the HMAC feature, set the MAC key to the value of
+@var{key} of length @var{keylen} bytes. There is no restriction on
+the length of the key.
+@end deftypefun
+
+
+After you are done with the hash calculation, you should release the
+resources by using:
+
+@deftypefun void gcry_md_close (gcry_md_hd_t @var{h})
+
+Release all resources of hash context @var{h}. @var{h} should not be
+used after a call to this function. A @code{NULL} passed as @var{h} is
+ignored. The function also zeroises all sensitive information
+associated with this handle.
+
+
+@end deftypefun
+
+Often you have to do several hash operations using the same algorithm.
+To avoid the overhead of creating and releasing context, a reset function
+is provided:
+
+@deftypefun void gcry_md_reset (gcry_md_hd_t @var{h})
+
+Reset the current context to its initial state. This is effectively
+identical to a close followed by an open and enabling all currently
+active algorithms.
+@end deftypefun
+
+
+Often it is necessary to start hashing some data and then continue to
+hash different data. To avoid hashing the same data several times (which
+might not even be possible if the data is received from a pipe), a
+snapshot of the current hash context can be taken and turned into a new
+context:
+
+@deftypefun gcry_error_t gcry_md_copy (gcry_md_hd_t *@var{handle_dst}, gcry_md_hd_t @var{handle_src})
+
+Create a new digest object as an exact copy of the object described by
+handle @var{handle_src} and store it in @var{handle_dst}. The context
+is not reset and you can continue to hash data using this context and
+independently using the original context.
+@end deftypefun
+
+
+Now that we have prepared everything to calculate hashes, it is time to
+see how it is actually done. There are two ways for this, one to
+update the hash with a block of memory and one macro to update the hash
+by just one character. Both methods can be used on the same hash context.
+
+@deftypefun void gcry_md_write (gcry_md_hd_t @var{h}, const void *@var{buffer}, size_t @var{length})
+
+Pass @var{length} bytes of the data in @var{buffer} to the digest object
+with handle @var{h} to update the digest values. This
+function should be used for large blocks of data.
+@end deftypefun
+
+@deftypefun void gcry_md_putc (gcry_md_hd_t @var{h}, int @var{c})
+
+Pass the byte in @var{c} to the digest object with handle @var{h} to
+update the digest value. This is an efficient function, implemented as
+a macro to buffer the data before an actual update.
+@end deftypefun
+
+The semantics of the hash functions do not provide for reading out intermediate
+message digests because the calculation must be finalized first. This
+finalization may for example include the number of bytes hashed in the
+message digest or some padding.
+
+@deftypefun void gcry_md_final (gcry_md_hd_t @var{h})
+
+Finalize the message digest calculation. This is not really needed
+because @code{gcry_md_read} does this implicitly. After this has been
+done no further updates (by means of @code{gcry_md_write} or
+@code{gcry_md_putc} are allowed. Only the first call to this function
+has an effect. It is implemented as a macro.
+@end deftypefun
+
+The way to read out the calculated message digest is by using the
+function:
+
+@deftypefun {unsigned char *} gcry_md_read (gcry_md_hd_t @var{h}, int @var{algo})
+
+@code{gcry_md_read} returns the message digest after finalizing the
+calculation. This function may be used as often as required but it will
+always return the same value for one handle. The returned message digest
+is allocated within the message context and therefore valid until the
+handle is released or reseted (using @code{gcry_md_close} or
+@code{gcry_md_reset}. @var{algo} may be given as 0 to return the only
+enabled message digest or it may specify one of the enabled algorithms.
+The function does return @code{NULL} if the requested algorithm has not
+been enabled.
+@end deftypefun
+
+Because it is often necessary to get the message digest of one block of
+memory, a fast convenience function is available for this task:
+
+@deftypefun void gcry_md_hash_buffer (int @var{algo}, void *@var{digest}, const void *@var{buffer}, size_t @var{length});
+
+@code{gcry_md_hash_buffer} is a shortcut function to calculate a message
+digest of a buffer. This function does not require a context and
+immediately returns the message digest of the @var{length} bytes at
+@var{buffer}. @var{digest} must be allocated by the caller, large
+enough to hold the message digest yielded by the the specified algorithm
+@var{algo}. This required size may be obtained by using the function
+@code{gcry_md_get_algo_dlen}.
+
+Note that this function will abort the process if an unavailable
+algorithm is used.
+@end deftypefun
+
+@c ***********************************
+@c ***** MD info functions ***********
+@c ***********************************
+
+Hash algorithms are identified by internal algorithm numbers (see
+@code{gcry_md_open} for a list). However, in most applications they are
+used by names, so two functions are available to map between string
+representations and hash algorithm identifiers.
+
+@deftypefun {const char *} gcry_md_algo_name (int @var{algo})
+
+Map the digest algorithm id @var{algo} to a string representation of the
+algorithm name. For unknown algorithms this function returns the
+string @code{"?"}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_md_map_name (const char *@var{name})
+
+Map the algorithm with @var{name} to a digest algorithm identifier.
+Returns 0 if the algorithm name is not known. Names representing
+@acronym{ASN.1} object identifiers are recognized if the @acronym{IETF}
+dotted format is used and the OID is prefixed with either "@code{oid.}"
+or "@code{OID.}". For a list of supported OIDs, see the source code at
+@file{cipher/md.c}. This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_md_get_asnoid (int @var{algo}, void *@var{buffer}, size_t *@var{length})
+
+Return an DER encoded ASN.1 OID for the algorithm @var{algo} in the
+user allocated @var{buffer}. @var{length} must point to variable with
+the available size of @var{buffer} and receives after return the
+actual size of the returned OID. The returned error code may be
+@code{GPG_ERR_TOO_SHORT} if the provided buffer is to short to receive
+the OID; it is possible to call the function with @code{NULL} for
+@var{buffer} to have it only return the required size. The function
+returns 0 on success.
+
+@end deftypefun
+
+
+To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+@deftypefun gcry_error_t gcry_md_test_algo (int @var{algo})
+
+The macro returns 0 if the algorithm @var{algo} is available for use.
+@end deftypefun
+
+If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+@deftypefun {unsigned int} gcry_md_get_algo_dlen (int @var{algo})
+
+Retrieve the length in bytes of the digest yielded by algorithm
+@var{algo}. This is often used prior to @code{gcry_md_read} to allocate
+sufficient memory for the digest.
+@end deftypefun
+
+
+In some situations it might be hard to remember the algorithm used for
+the ongoing hashing. The following function might be used to get that
+information:
+
+@deftypefun int gcry_md_get_algo (gcry_md_hd_t @var{h})
+
+Retrieve the algorithm used with the handle @var{h}. Note that this
+does not work reliable if more than one algorithm is enabled in @var{h}.
+@end deftypefun
+
+The following macro might also be useful:
+
+@deftypefun int gcry_md_is_secure (gcry_md_hd_t @var{h})
+
+This function returns true when the digest object @var{h} is allocated
+in "secure memory"; i.e. @var{h} was created with the
+@code{GCRY_MD_FLAG_SECURE}.
+@end deftypefun
+
+@deftypefun int gcry_md_is_enabled (gcry_md_hd_t @var{h}, int @var{algo})
+
+This function returns true when the algorithm @var{algo} has been
+enabled for the digest object @var{h}.
+@end deftypefun
+
+
+
+Tracking bugs related to hashing is often a cumbersome task which
+requires to add a lot of printf statements into the code.
+Libgcrypt provides an easy way to avoid this. The actual data
+hashed can be written to files on request.
+
+@deftypefun void gcry_md_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
+
+Enable debugging for the digest object with handle @var{h}. This
+creates create files named @file{dbgmd-<n>.<string>} while doing the
+actual hashing. @var{suffix} is the string part in the filename. The
+number is a counter incremented for each new hashing. The data in the
+file is the raw data as passed to @code{gcry_md_write} or
+@code{gcry_md_putc}. If @code{NULL} is used for @var{suffix}, the
+debugging is stopped and the file closed. This is only rarely required
+because @code{gcry_md_close} implicitly stops debugging.
+@end deftypefun
+
+
+The following two deprecated macros are used for debugging by old code.
+They shopuld be replaced by @code{gcry_md_debug}.
+
+@deftypefun void gcry_md_start_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
+
+Enable debugging for the digest object with handle @var{h}. This
+creates create files named @file{dbgmd-<n>.<string>} while doing the
+actual hashing. @var{suffix} is the string part in the filename. The
+number is a counter incremented for each new hashing. The data in the
+file is the raw data as passed to @code{gcry_md_write} or
+@code{gcry_md_putc}.
+@end deftypefun
+
+
+@deftypefun void gcry_md_stop_debug (gcry_md_hd_t @var{h}, int @var{reserved})
+
+Stop debugging on handle @var{h}. @var{reserved} should be specified as
+0. This function is usually not required because @code{gcry_md_close}
+does implicitly stop debugging.
+@end deftypefun
+
+
+@c *******************************************************
+@c ******************* KDF *****************************
+@c *******************************************************
+@node Key Derivation
+@chapter Key Derivation
+
+@acronym{Libgcypt} provides a general purpose function to derive keys
+from strings.
+
+@deftypefun gpg_error_t gcry_kdf_derive ( @
+ @w{const void *@var{passphrase}}, @w{size_t @var{passphraselen}}, @
+ @w{int @var{algo}}, @w{int @var{subalgo}}, @
+ @w{const void *@var{salt}}, @w{size_t @var{saltlen}}, @
+ @w{unsigned long @var{iterations}}, @
+ @w{size_t @var{keysize}}, @w{void *@var{keybuffer}} )
+
+
+Derive a key from a passphrase. @var{keysize} gives the requested
+size of the keys in octets. @var{keybuffer} is a caller provided
+buffer filled on success with the derived key. The input passphrase
+is taken from @var{passphrase} which is an arbitrary memory buffer of
+@var{passphraselen} octets. @var{algo} specifies the KDF algorithm to
+use; see below. @var{subalgo} specifies an algorithm used internally
+by the KDF algorithms; this is usually a hash algorithm but certain
+KDF algorithms may use it differently. @var{salt} is a salt of length
+@var{saltlen} octets, as needed by most KDF algorithms.
+@var{iterations} is a positive integer parameter to most KDFs.
+
+@noindent
+On success 0 is returned; on failure an error code.
+
+@noindent
+Currently supported KDFs (parameter @var{algo}):
+
+@table @code
+@item GCRY_KDF_SIMPLE_S2K
+The OpenPGP simple S2K algorithm (cf. RFC4880). Its use is strongly
+deprecated. @var{salt} and @var{iterations} are not needed and may be
+passed as @code{NULL}/@code{0}.
+
+@item GCRY_KDF_SALTED_S2K
+The OpenPGP salted S2K algorithm (cf. RFC4880). Usually not used.
+@var{iterations} is not needed and may be passed as @code{0}. @var{saltlen}
+must be given as 8.
+
+@item GCRY_KDF_ITERSALTED_S2K
+The OpenPGP iterated+salted S2K algorithm (cf. RFC4880). This is the
+default for most OpenPGP applications. @var{saltlen} must be given as
+8. Note that OpenPGP defines a special encoding of the
+@var{iterations}; however this function takes the plain decoded
+iteration count.
+
+@item GCRY_KDF_PBKDF2
+The PKCS#5 Passphrase Based Key Derivation Function number 2.
+
+@end table
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* Random *****************************
+@c **********************************************************
+@node Random Numbers
+@chapter Random Numbers
+
+@menu
+* Quality of random numbers:: Libgcrypt uses different quality levels.
+* Retrieving random numbers:: How to retrieve random numbers.
+@end menu
+
+@node Quality of random numbers
+@section Quality of random numbers
+
+@acronym{Libgcypt} offers random numbers of different quality levels:
+
+@deftp {Data type} gcry_random_level_t
+The constants for the random quality levels are of this enum type.
+@end deftp
+
+@table @code
+@item GCRY_WEAK_RANDOM
+For all functions, except for @code{gcry_mpi_randomize}, this level maps
+to GCRY_STRONG_RANDOM. If you do not want this, consider using
+@code{gcry_create_nonce}.
+@item GCRY_STRONG_RANDOM
+Use this level for session keys and similar purposes.
+@item GCRY_VERY_STRONG_RANDOM
+Use this level for long term key material.
+@end table
+
+@node Retrieving random numbers
+@section Retrieving random numbers
+
+@deftypefun void gcry_randomize (unsigned char *@var{buffer}, size_t @var{length}, enum gcry_random_level @var{level})
+
+Fill @var{buffer} with @var{length} random bytes using a random quality
+as defined by @var{level}.
+@end deftypefun
+
+@deftypefun {void *} gcry_random_bytes (size_t @var{nbytes}, enum gcry_random_level @var{level})
+
+Convenience function to allocate a memory block consisting of
+@var{nbytes} fresh random bytes using a random quality as defined by
+@var{level}.
+@end deftypefun
+
+@deftypefun {void *} gcry_random_bytes_secure (size_t @var{nbytes}, enum gcry_random_level @var{level})
+
+Convenience function to allocate a memory block consisting of
+@var{nbytes} fresh random bytes using a random quality as defined by
+@var{level}. This function differs from @code{gcry_random_bytes} in
+that the returned buffer is allocated in a ``secure'' area of the
+memory.
+@end deftypefun
+
+@deftypefun void gcry_create_nonce (unsigned char *@var{buffer}, size_t @var{length})
+
+Fill @var{buffer} with @var{length} unpredictable bytes. This is
+commonly called a nonce and may also be used for initialization
+vectors and padding. This is an extra function nearly independent of
+the other random function for 3 reasons: It better protects the
+regular random generator's internal state, provides better performance
+and does not drain the precious entropy pool.
+
+@end deftypefun
+
+
+
+@c **********************************************************
+@c ******************* S-Expressions ***********************
+@c **********************************************************
+@node S-expressions
+@chapter S-expressions
+
+S-expressions are used by the public key functions to pass complex data
+structures around. These LISP like objects are used by some
+cryptographic protocols (cf. RFC-2692) and Libgcrypt provides functions
+to parse and construct them. For detailed information, see
+@cite{Ron Rivest, code and description of S-expressions,
+@uref{http://theory.lcs.mit.edu/~rivest/sexp.html}}.
+
+@menu
+* Data types for S-expressions:: Data types related with S-expressions.
+* Working with S-expressions:: How to work with S-expressions.
+@end menu
+
+@node Data types for S-expressions
+@section Data types for S-expressions
+
+@deftp {Data type} gcry_sexp_t
+The @code{gcry_sexp_t} type describes an object with the Libgcrypt internal
+representation of an S-expression.
+@end deftp
+
+@node Working with S-expressions
+@section Working with S-expressions
+
+@noindent
+There are several functions to create an Libgcrypt S-expression object
+from its external representation or from a string template. There is
+also a function to convert the internal representation back into one of
+the external formats:
+
+
+@deftypefun gcry_error_t gcry_sexp_new (@w{gcry_sexp_t *@var{r_sexp}}, @w{const void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}})
+
+This is the generic function to create an new S-expression object from
+its external representation in @var{buffer} of @var{length} bytes. On
+success the result is stored at the address given by @var{r_sexp}.
+With @var{autodetect} set to 0, the data in @var{buffer} is expected to
+be in canonized format, with @var{autodetect} set to 1 the parses any of
+the defined external formats. If @var{buffer} does not hold a valid
+S-expression an error code is returned and @var{r_sexp} set to
+@code{NULL}.
+Note that the caller is responsible for releasing the newly allocated
+S-expression using @code{gcry_sexp_release}.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_create (@w{gcry_sexp_t *@var{r_sexp}}, @w{void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}}, @w{void (*@var{freefnc})(void*)})
+
+This function is identical to @code{gcry_sexp_new} but has an extra
+argument @var{freefnc}, which, when not set to @code{NULL}, is expected
+to be a function to release the @var{buffer}; most likely the standard
+@code{free} function is used for this argument. This has the effect of
+transferring the ownership of @var{buffer} to the created object in
+@var{r_sexp}. The advantage of using this function is that Libgcrypt
+might decide to directly use the provided buffer and thus avoid extra
+copying.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_sscan (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{buffer}}, @w{size_t @var{length}})
+
+This is another variant of the above functions. It behaves nearly
+identical but provides an @var{erroff} argument which will receive the
+offset into the buffer where the parsing stopped on error.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_sexp_build (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{format}, ...})
+
+This function creates an internal S-expression from the string template
+@var{format} and stores it at the address of @var{r_sexp}. If there is a
+parsing error, the function returns an appropriate error code and stores
+the offset into @var{format} where the parsing stopped in @var{erroff}.
+The function supports a couple of printf-like formatting characters and
+expects arguments for some of these escape sequences right after
+@var{format}. The following format characters are defined:
+
+@table @samp
+@item %m
+The next argument is expected to be of type @code{gcry_mpi_t} and a copy of
+its value is inserted into the resulting S-expression. The MPI is
+stored as a signed integer.
+@item %M
+The next argument is expected to be of type @code{gcry_mpi_t} and a copy of
+its value is inserted into the resulting S-expression. The MPI is
+stored as an unsigned integer.
+@item %s
+The next argument is expected to be of type @code{char *} and that
+string is inserted into the resulting S-expression.
+@item %d
+The next argument is expected to be of type @code{int} and its value is
+inserted into the resulting S-expression.
+@item %u
+The next argument is expected to be of type @code{unsigned int} and
+its value is inserted into the resulting S-expression.
+@item %b
+The next argument is expected to be of type @code{int} directly
+followed by an argument of type @code{char *}. This represents a
+buffer of given length to be inserted into the resulting S-expression.
+@item %S
+The next argument is expected to be of type @code{gcry_sexp_t} and a
+copy of that S-expression is embedded in the resulting S-expression.
+The argument needs to be a regular S-expression, starting with a
+parenthesis.
+
+@end table
+
+@noindent
+No other format characters are defined and would return an error. Note
+that the format character @samp{%%} does not exists, because a percent
+sign is not a valid character in an S-expression.
+@end deftypefun
+
+@deftypefun void gcry_sexp_release (@w{gcry_sexp_t @var{sexp}})
+
+Release the S-expression object @var{sexp}. If the S-expression is
+stored in secure memory it explicitly zeroises that memory; note that
+this is done in addition to the zeroisation always done when freeing
+secure memory.
+@end deftypefun
+
+
+@noindent
+The next 2 functions are used to convert the internal representation
+back into a regular external S-expression format and to show the
+structure for debugging.
+
+@deftypefun size_t gcry_sexp_sprint (@w{gcry_sexp_t @var{sexp}}, @w{int @var{mode}}, @w{char *@var{buffer}}, @w{size_t @var{maxlength}})
+
+Copies the S-expression object @var{sexp} into @var{buffer} using the
+format specified in @var{mode}. @var{maxlength} must be set to the
+allocated length of @var{buffer}. The function returns the actual
+length of valid bytes put into @var{buffer} or 0 if the provided buffer
+is too short. Passing @code{NULL} for @var{buffer} returns the required
+length for @var{buffer}. For convenience reasons an extra byte with
+value 0 is appended to the buffer.
+
+@noindent
+The following formats are supported:
+
+@table @code
+@item GCRYSEXP_FMT_DEFAULT
+Returns a convenient external S-expression representation.
+
+@item GCRYSEXP_FMT_CANON
+Return the S-expression in canonical format.
+
+@item GCRYSEXP_FMT_BASE64
+Not currently supported.
+
+@item GCRYSEXP_FMT_ADVANCED
+Returns the S-expression in advanced format.
+@end table
+@end deftypefun
+
+@deftypefun void gcry_sexp_dump (@w{gcry_sexp_t @var{sexp}})
+
+Dumps @var{sexp} in a format suitable for debugging to Libgcrypt's
+logging stream.
+@end deftypefun
+
+@noindent
+Often canonical encoding is used in the external representation. The
+following function can be used to check for valid encoding and to learn
+the length of the S-expression"
+
+@deftypefun size_t gcry_sexp_canon_len (@w{const unsigned char *@var{buffer}}, @w{size_t @var{length}}, @w{size_t *@var{erroff}}, @w{int *@var{errcode}})
+
+Scan the canonical encoded @var{buffer} with implicit length values and
+return the actual length this S-expression uses. For a valid S-expression
+it should never return 0. If @var{length} is not 0, the maximum
+length to scan is given; this can be used for syntax checks of
+data passed from outside. @var{errcode} and @var{erroff} may both be
+passed as @code{NULL}.
+
+@end deftypefun
+
+
+@noindent
+There are functions to parse S-expressions and retrieve elements:
+
+@deftypefun gcry_sexp_t gcry_sexp_find_token (@w{const gcry_sexp_t @var{list}}, @w{const char *@var{token}}, @w{size_t @var{toklen}})
+
+Scan the S-expression for a sublist with a type (the car of the list)
+matching the string @var{token}. If @var{toklen} is not 0, the token is
+assumed to be raw memory of this length. The function returns a newly
+allocated S-expression consisting of the found sublist or @code{NULL}
+when not found.
+@end deftypefun
+
+
+@deftypefun int gcry_sexp_length (@w{const gcry_sexp_t @var{list}})
+
+Return the length of the @var{list}. For a valid S-expression this
+should be at least 1.
+@end deftypefun
+
+
+@deftypefun gcry_sexp_t gcry_sexp_nth (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}})
+
+Create and return a new S-expression from the element with index @var{number} in
+@var{list}. Note that the first element has the index 0. If there is
+no such element, @code{NULL} is returned.
+@end deftypefun
+
+@deftypefun gcry_sexp_t gcry_sexp_car (@w{const gcry_sexp_t @var{list}})
+
+Create and return a new S-expression from the first element in
+@var{list}; this called the "type" and should always exist and be a
+string. @code{NULL} is returned in case of a problem.
+@end deftypefun
+
+@deftypefun gcry_sexp_t gcry_sexp_cdr (@w{const gcry_sexp_t @var{list}})
+
+Create and return a new list form all elements except for the first one.
+Note that this function may return an invalid S-expression because it
+is not guaranteed, that the type exists and is a string. However, for
+parsing a complex S-expression it might be useful for intermediate
+lists. Returns @code{NULL} on error.
+@end deftypefun
+
+
+@deftypefun {const char *} gcry_sexp_nth_data (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{size_t *@var{datalen}})
+
+This function is used to get data from a @var{list}. A pointer to the
+actual data with index @var{number} is returned and the length of this
+data will be stored to @var{datalen}. If there is no data at the given
+index or the index represents another list, @code{NULL} is returned.
+@strong{Caution:} The returned pointer is valid as long as @var{list} is
+not modified or released.
+
+@noindent
+Here is an example on how to extract and print the surname (Meier) from
+the S-expression @samp{(Name Otto Meier (address Burgplatz 3))}:
+
+@example
+size_t len;
+const char *name;
+
+name = gcry_sexp_nth_data (list, 2, &len);
+printf ("my name is %.*s\n", (int)len, name);
+@end example
+@end deftypefun
+
+@deftypefun {char *} gcry_sexp_nth_string (@w{gcry_sexp_t @var{list}}, @w{int @var{number}})
+
+This function is used to get and convert data from a @var{list}. The
+data is assumed to be a Nul terminated string. The caller must
+release this returned value using @code{gcry_free}. If there is
+no data at the given index, the index represents a list or the value
+can't be converted to a string, @code{NULL} is returned.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_sexp_nth_mpi (@w{gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{int @var{mpifmt}})
+
+This function is used to get and convert data from a @var{list}. This
+data is assumed to be an MPI stored in the format described by
+@var{mpifmt} and returned as a standard Libgcrypt MPI. The caller must
+release this returned value using @code{gcry_mpi_release}. If there is
+no data at the given index, the index represents a list or the value
+can't be converted to an MPI, @code{NULL} is returned. If you use
+this function to parse results of a public key function, you most
+likely want to use @code{GCRYMPI_FMT_USG}.
+@end deftypefun
+
+
+@c **********************************************************
+@c ******************* MPIs ******** ***********************
+@c **********************************************************
+@node MPI library
+@chapter MPI library
+
+@menu
+* Data types:: MPI related data types.
+* Basic functions:: First steps with MPI numbers.
+* MPI formats:: External representation of MPIs.
+* Calculations:: Performing MPI calculations.
+* Comparisons:: How to compare MPI values.
+* Bit manipulations:: How to access single bits of MPI values.
+* Miscellaneous:: Miscellaneous MPI functions.
+@end menu
+
+Public key cryptography is based on mathematics with large numbers. To
+implement the public key functions, a library for handling these large
+numbers is required. Because of the general usefulness of such a
+library, its interface is exposed by Libgcrypt.
+In the context of Libgcrypt and in most other applications, these large
+numbers are called MPIs (multi-precision-integers).
+
+@node Data types
+@section Data types
+
+@deftp {Data type} {gcry_mpi_t}
+This type represents an object to hold an MPI.
+@end deftp
+
+@node Basic functions
+@section Basic functions
+
+@noindent
+To work with MPIs, storage must be allocated and released for the
+numbers. This can be done with one of these functions:
+
+@deftypefun gcry_mpi_t gcry_mpi_new (@w{unsigned int @var{nbits}})
+
+Allocate a new MPI object, initialize it to 0 and initially allocate
+enough memory for a number of at least @var{nbits}. This pre-allocation is
+only a small performance issue and not actually necessary because
+Libgcrypt automatically re-allocates the required memory.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_snew (@w{unsigned int @var{nbits}})
+
+This is identical to @code{gcry_mpi_new} but allocates the MPI in the so
+called "secure memory" which in turn will take care that all derived
+values will also be stored in this "secure memory". Use this for highly
+confidential data like private key parameters.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_copy (@w{const gcry_mpi_t @var{a}})
+
+Create a new MPI as the exact copy of @var{a}.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_release (@w{gcry_mpi_t @var{a}})
+
+Release the MPI @var{a} and free all associated resources. Passing
+@code{NULL} is allowed and ignored. When a MPI stored in the "secure
+memory" is released, that memory gets wiped out immediately.
+@end deftypefun
+
+@noindent
+The simplest operations are used to assign a new value to an MPI:
+
+@deftypefun gcry_mpi_t gcry_mpi_set (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{u}})
+
+Assign the value of @var{u} to @var{w} and return @var{w}. If
+@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
+value of @var{u} and returned.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_set_ui (@w{gcry_mpi_t @var{w}}, @w{unsigned long @var{u}})
+
+Assign the value of @var{u} to @var{w} and return @var{w}. If
+@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
+value of @var{u} and returned. This function takes an @code{unsigned
+int} as type for @var{u} and thus it is only possible to set @var{w} to
+small values (usually up to the word size of the CPU).
+@end deftypefun
+
+@deftypefun void gcry_mpi_swap (@w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
+
+Swap the values of @var{a} and @var{b}.
+@end deftypefun
+
+@node MPI formats
+@section MPI formats
+
+@noindent
+The following functions are used to convert between an external
+representation of an MPI and the internal one of Libgcrypt.
+
+@deftypefun gcry_error_t gcry_mpi_scan (@w{gcry_mpi_t *@var{r_mpi}}, @w{enum gcry_mpi_format @var{format}}, @w{const unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nscanned}})
+
+Convert the external representation of an integer stored in @var{buffer}
+with a length of @var{buflen} into a newly created MPI returned which
+will be stored at the address of @var{r_mpi}. For certain formats the
+length argument is not required and should be passed as @code{0}. After a
+successful operation the variable @var{nscanned} receives the number of
+bytes actually scanned unless @var{nscanned} was given as
+@code{NULL}. @var{format} describes the format of the MPI as stored in
+@var{buffer}:
+
+@table @code
+@item GCRYMPI_FMT_STD
+2-complement stored without a length header.
+
+@item GCRYMPI_FMT_PGP
+As used by OpenPGP (only defined as unsigned). This is basically
+@code{GCRYMPI_FMT_STD} with a 2 byte big endian length header.
+
+@item GCRYMPI_FMT_SSH
+As used in the Secure Shell protocol. This is @code{GCRYMPI_FMT_STD}
+with a 4 byte big endian header.
+
+@item GCRYMPI_FMT_HEX
+Stored as a C style string with each byte of the MPI encoded as 2 hex
+digits. When using this format, @var{buflen} must be zero.
+
+@item GCRYMPI_FMT_USG
+Simple unsigned integer.
+@end table
+
+@noindent
+Note that all of the above formats store the integer in big-endian
+format (MSB first).
+@end deftypefun
+
+
+@deftypefun gcry_error_t gcry_mpi_print (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nwritten}}, @w{const gcry_mpi_t @var{a}})
+
+Convert the MPI @var{a} into an external representation described by
+@var{format} (see above) and store it in the provided @var{buffer}
+which has a usable length of at least the @var{buflen} bytes. If
+@var{nwritten} is not NULL, it will receive the number of bytes
+actually stored in @var{buffer} after a successful operation.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_mpi_aprint (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char **@var{buffer}}, @w{size_t *@var{nbytes}}, @w{const gcry_mpi_t @var{a}})
+
+Convert the MPI @var{a} into an external representation described by
+@var{format} (see above) and store it in a newly allocated buffer which
+address will be stored in the variable @var{buffer} points to. The
+number of bytes stored in this buffer will be stored in the variable
+@var{nbytes} points to, unless @var{nbytes} is @code{NULL}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_dump (@w{const gcry_mpi_t @var{a}})
+
+Dump the value of @var{a} in a format suitable for debugging to
+Libgcrypt's logging stream. Note that one leading space but no trailing
+space or linefeed will be printed. It is okay to pass @code{NULL} for
+@var{a}.
+@end deftypefun
+
+
+@node Calculations
+@section Calculations
+
+@noindent
+Basic arithmetic operations:
+
+@deftypefun void gcry_mpi_add (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} + @var{v}}.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_add_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} + @var{v}}. Note that @var{v} is an unsigned integer.
+@end deftypefun
+
+
+@deftypefun void gcry_mpi_addm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} + @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_sub (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} - @var{v}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_sub_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} - @var{v}}. @var{v} is an unsigned integer.
+@end deftypefun
+
+@deftypefun void gcry_mpi_subm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} - @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
+
+@math{@var{w} = @var{u} * @var{v}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+@math{@var{w} = @var{u} * @var{v}}. @var{v} is an unsigned integer.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mulm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
+
+@math{@var{w} = @var{u} * @var{v} \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mul_2exp (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{e}})
+
+@c FIXME: I am in need for a real TeX{info} guru:
+@c I don't know why TeX can grok @var{e} here.
+@math{@var{w} = @var{u} * 2^e}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_div (@w{gcry_mpi_t @var{q}}, @w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}}, @w{int @var{round}})
+
+@math{@var{q} = @var{dividend} / @var{divisor}}, @math{@var{r} =
+@var{dividend} \bmod @var{divisor}}. @var{q} and @var{r} may be passed
+as @code{NULL}. @var{round} should be negative or 0.
+@end deftypefun
+
+@deftypefun void gcry_mpi_mod (@w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}})
+
+@math{@var{r} = @var{dividend} \bmod @var{divisor}}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_powm (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{b}}, @w{const gcry_mpi_t @var{e}}, @w{const gcry_mpi_t @var{m}})
+
+@c I don't know why TeX can grok @var{e} here.
+@math{@var{w} = @var{b}^e \bmod @var{m}}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_gcd (@w{gcry_mpi_t @var{g}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
+
+Set @var{g} to the greatest common divisor of @var{a} and @var{b}.
+Return true if the @var{g} is 1.
+@end deftypefun
+
+@deftypefun int gcry_mpi_invm (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{m}})
+
+Set @var{x} to the multiplicative inverse of @math{@var{a} \bmod @var{m}}.
+Return true if the inverse exists.
+@end deftypefun
+
+
+@node Comparisons
+@section Comparisons
+
+@noindent
+The next 2 functions are used to compare MPIs:
+
+
+@deftypefun int gcry_mpi_cmp (@w{const gcry_mpi_t @var{u}}, @w{const gcry_mpi_t @var{v}})
+
+Compare the multi-precision-integers number @var{u} and @var{v}
+returning 0 for equality, a positive value for @var{u} > @var{v} and a
+negative for @var{u} < @var{v}. If both numbers are opaque values
+(cf, gcry_mpi_set_opaque) the comparison is done by checking the bit
+sizes using memcmp. If only one number is an opaque value, the opaque
+value is less than the other number.
+@end deftypefun
+
+@deftypefun int gcry_mpi_cmp_ui (@w{const gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
+
+Compare the multi-precision-integers number @var{u} with the unsigned
+integer @var{v} returning 0 for equality, a positive value for @var{u} >
+@var{v} and a negative for @var{u} < @var{v}.
+@end deftypefun
+
+
+@node Bit manipulations
+@section Bit manipulations
+
+@noindent
+There are a couple of functions to get information on arbitrary bits
+in an MPI and to set or clear them:
+
+@deftypefun {unsigned int} gcry_mpi_get_nbits (@w{gcry_mpi_t @var{a}})
+
+Return the number of bits required to represent @var{a}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_test_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Return true if bit number @var{n} (counting from 0) is set in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_set_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Set bit number @var{n} in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Clear bit number @var{n} in @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_set_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Set bit number @var{n} in @var{a} and clear all bits greater than @var{n}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Clear bit number @var{n} in @var{a} and all bits greater than @var{n}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_rshift (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Shift the value of @var{a} by @var{n} bits to the right and store the
+result in @var{x}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_lshift (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
+
+Shift the value of @var{a} by @var{n} bits to the left and store the
+result in @var{x}.
+@end deftypefun
+
+@node Miscellaneous
+@section Miscellaneous
+
+@deftypefun gcry_mpi_t gcry_mpi_set_opaque (@w{gcry_mpi_t @var{a}}, @w{void *@var{p}}, @w{unsigned int @var{nbits}})
+
+Store @var{nbits} of the value @var{p} points to in @var{a} and mark
+@var{a} as an opaque value (i.e. an value that can't be used for any
+math calculation and is only used to store an arbitrary bit pattern in
+@var{a}).
+
+WARNING: Never use an opaque MPI for actual math operations. The only
+valid functions are gcry_mpi_get_opaque and gcry_mpi_release. Use
+gcry_mpi_scan to convert a string of arbitrary bytes into an MPI.
+
+@end deftypefun
+
+@deftypefun {void *} gcry_mpi_get_opaque (@w{gcry_mpi_t @var{a}}, @w{unsigned int *@var{nbits}})
+
+Return a pointer to an opaque value stored in @var{a} and return its
+size in @var{nbits}. Note that the returned pointer is still owned by
+@var{a} and that the function should never be used for an non-opaque
+MPI.
+@end deftypefun
+
+@deftypefun void gcry_mpi_set_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+
+Set the @var{flag} for the MPI @var{a}. Currently only the flag
+@code{GCRYMPI_FLAG_SECURE} is allowed to convert @var{a} into an MPI
+stored in "secure memory".
+@end deftypefun
+
+@deftypefun void gcry_mpi_clear_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+
+Clear @var{flag} for the multi-precision-integers @var{a}. Note that
+this function is currently useless as no flags are allowed.
+@end deftypefun
+
+@deftypefun int gcry_mpi_get_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+
+Return true when the @var{flag} is set for @var{a}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_randomize (@w{gcry_mpi_t @var{w}}, @w{unsigned int @var{nbits}}, @w{enum gcry_random_level @var{level}})
+
+Set the multi-precision-integers @var{w} to a random value of
+@var{nbits}, using random data quality of level @var{level}. In case
+@var{nbits} is not a multiple of a byte, @var{nbits} is rounded up to
+the next byte boundary. When using a @var{level} of
+@code{GCRY_WEAK_RANDOM} this function makes use of
+@code{gcry_create_nonce}.
+@end deftypefun
+
+@c **********************************************************
+@c ******************** Prime numbers ***********************
+@c **********************************************************
+@node Prime numbers
+@chapter Prime numbers
+
+@menu
+* Generation:: Generation of new prime numbers.
+* Checking:: Checking if a given number is prime.
+@end menu
+
+@node Generation
+@section Generation
+
+@deftypefun gcry_error_t gcry_prime_generate (gcry_mpi_t *@var{prime},unsigned int @var{prime_bits}, unsigned int @var{factor_bits}, gcry_mpi_t **@var{factors}, gcry_prime_check_func_t @var{cb_func}, void *@var{cb_arg}, gcry_random_level_t @var{random_level}, unsigned int @var{flags})
+
+Generate a new prime number of @var{prime_bits} bits and store it in
+@var{prime}. If @var{factor_bits} is non-zero, one of the prime factors
+of (@var{prime} - 1) / 2 must be @var{factor_bits} bits long. If
+@var{factors} is non-zero, allocate a new, @code{NULL}-terminated array
+holding the prime factors and store it in @var{factors}. @var{flags}
+might be used to influence the prime number generation process.
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_prime_group_generator (gcry_mpi_t *@var{r_g}, gcry_mpi_t @var{prime}, gcry_mpi_t *@var{factors}, gcry_mpi_t @var{start_g})
+
+Find a generator for @var{prime} where the factorization of
+(@var{prime}-1) is in the @code{NULL} terminated array @var{factors}.
+Return the generator as a newly allocated MPI in @var{r_g}. If
+@var{start_g} is not NULL, use this as the start for the search.
+@end deftypefun
+
+@deftypefun void gcry_prime_release_factors (gcry_mpi_t *@var{factors})
+
+Convenience function to release the @var{factors} array.
+@end deftypefun
+
+@node Checking
+@section Checking
+
+@deftypefun gcry_error_t gcry_prime_check (gcry_mpi_t @var{p}, unsigned int @var{flags})
+
+Check wether the number @var{p} is prime. Returns zero in case @var{p}
+is indeed a prime, returns @code{GPG_ERR_NO_PRIME} in case @var{p} is
+not a prime and a different error code in case something went horribly
+wrong.
+@end deftypefun
+
+@c **********************************************************
+@c ******************** Utilities ***************************
+@c **********************************************************
+@node Utilities
+@chapter Utilities
+
+@menu
+* Memory allocation:: Functions related with memory allocation.
+@end menu
+
+@node Memory allocation
+@section Memory allocation
+
+@deftypefun {void *} gcry_malloc (size_t @var{n})
+
+This function tries to allocate @var{n} bytes of memory. On success
+it returns a pointer to the memory area, in an out-of-core condition,
+it returns NULL.
+@end deftypefun
+
+@deftypefun {void *} gcry_malloc_secure (size_t @var{n})
+Like @code{gcry_malloc}, but uses secure memory.
+@end deftypefun
+
+@deftypefun {void *} gcry_calloc (size_t @var{n}, size_t @var{m})
+
+This function allocates a cleared block of memory (i.e. initialized with
+zero bytes) long enough to contain a vector of @var{n} elements, each of
+size @var{m} bytes. On success it returns a pointer to the memory
+block; in an out-of-core condition, it returns NULL.
+@end deftypefun
+
+@deftypefun {void *} gcry_calloc_secure (size_t @var{n}, size_t @var{m})
+Like @code{gcry_calloc}, but uses secure memory.
+@end deftypefun
+
+@deftypefun {void *} gcry_realloc (void *@var{p}, size_t @var{n})
+
+This function tries to resize the memory area pointed to by @var{p} to
+@var{n} bytes. On success it returns a pointer to the new memory
+area, in an out-of-core condition, it returns NULL. Depending on
+whether the memory pointed to by @var{p} is secure memory or not,
+gcry_realloc tries to use secure memory as well.
+@end deftypefun
+
+@deftypefun void gcry_free (void *@var{p})
+Release the memory area pointed to by @var{p}.
+@end deftypefun
+
+@c **********************************************************
+@c ***************** Architecure Overview *****************
+@c **********************************************************
+@node Architecture
+@chapter Architecture
+
+This chapter describes the internal architecture of Libgcrypt.
+
+Libgcrypt is a function library written in ISO C-90. Any compliant
+compiler should be able to build Libgcrypt as long as the target is
+either a POSIX platform or compatible to the API used by Windows NT.
+Provisions have been take so that the library can be directly used from
+C++ applications; however building with a C++ compiler is not supported.
+
+Building Libgcrypt is done by using the common @code{./configure && make}
+approach. The configure command is included in the source distribution
+and as a portable shell script it works on any Unix-alike system. The
+result of running the configure script are a C header file
+(@file{config.h}), customized Makefiles, the setup of symbolic links and
+a few other things. After that the make tool builds and optionally
+installs the library and the documentation. See the files
+@file{INSTALL} and @file{README} in the source distribution on how to do
+this.
+
+Libgcrypt is developed using a Subversion@footnote{A version control
+system available for many platforms} repository. Although all released
+versions are tagged in this repository, they should not be used to build
+production versions of Libgcrypt. Instead released tarballs should be
+used. These tarballs are available from several places with the master
+copy at @indicateurl{ftp://ftp.gnupg.org/gcrypt/libgcrypt/}.
+Announcements of new releases are posted to the
+@indicateurl{gnupg-announce@@gnupg.org} mailing list@footnote{See
+@url{http://www.gnupg.org/documentation/mailing-lists.en.html} for
+details.}.
+
+
+@float Figure,fig:subsystems
+@caption{Libgcrypt subsystems}
+@center @image{libgcrypt-modules, 150mm,,Libgcrypt subsystems}
+@end float
+
+Libgcrypt consists of several subsystems (@pxref{fig:subsystems}) and
+all these subsystems provide a public API; this includes the helper
+subsystems like the one for S-expressions. The API style depends on the
+subsystem; in general an open-use-close approach is implemented. The
+open returns a handle to a context used for all further operations on
+this handle, several functions may then be used on this handle and a
+final close function releases all resources associated with the handle.
+
+@menu
+* Public-Key Subsystem Architecture:: About public keys.
+* Symmetric Encryption Subsystem Architecture:: About standard ciphers.
+* Hashing and MACing Subsystem Architecture:: About hashing.
+* Multi-Precision-Integer Subsystem Architecture:: About big integers.
+* Prime-Number-Generator Subsystem Architecture:: About prime numbers.
+* Random-Number Subsystem Architecture:: About random stuff.
+@c * Helper Subsystems Architecture:: About other stuff.
+@end menu
+
+
+
+@node Public-Key Subsystem Architecture
+@section Public-Key Architecture
+
+Libgcrypt implements two interfaces for public key cryptography: The
+standard interface is PK interface using functions in the
+@code{gcry_pk_} name space. The AC interface in an alternative one
+which is now deprecated and will not be further described. The AC
+interface is also disabled in FIPS mode.
+
+Because public key cryptography is almost always used to process small
+amounts of data (hash values or session keys), the interface is not
+implemented using the open-use-close paradigm, but with single
+self-contained functions. Due to the wide variety of parameters
+required by different algorithms S-expressions, as flexible way to
+convey these parameters, are used. There is a set of helper functions
+to work with these S-expressions.
+@c see @xref{S-expression Subsystem Architecture}.
+
+Aside of functions to register new algorithms, map algorithms names to
+algorithms identifiers and to lookup properties of a key, the
+following main functions are available:
+
+@table @code
+
+@item gcry_pk_encrypt
+Encrypt data using a public key.
+
+@item gcry_pk_decrypt
+Decrypt data using a private key.
+
+@item gcry_pk_sign
+Sign data using a private key.
+
+@item gcry_pk_verify
+Verify that a signature matches the data.
+
+@item gcry_pk_testkey
+Perform a consistency over a public or private key.
+
+@item gcry_pk_genkey
+Create a new public/private key pair.
+
+@end table
+
+With the help of the module registration system all these functions
+lookup the module implementing the algorithm and pass the actual work
+to that module. The parsing of the S-expression input and the
+construction of S-expression for the return values is done by the high
+level code (@file{cipher/pubkey.c}). Thus the internal interface
+between the algorithm modules and the high level functions passes data
+in a custom format. The interface to the modules is published
+(@file{gcrypt-modules.h}) so that it can used to register external
+implementations of algorithms with Libgcrypt. However, for some
+algorithms this module interface is to limited and thus for the
+internal modules an extra interface is sometimes used to convey more
+information.
+
+By default Libgcrypt uses a blinding technique for RSA decryption to
+mitigate real world timing attacks over a network: Instead of using
+the RSA decryption directly, a blinded value @math{y = x r^{e} \bmod n}
+is decrypted and the unblinded value @math{x' = y' r^{-1} \bmod n}
+returned. The blinding value @math{r} is a random value with the size
+of the modulus @math{n} and generated with @code{GCRY_WEAK_RANDOM}
+random level.
+
+@cindex X9.31
+@cindex FIPS 186
+The algorithm used for RSA and DSA key generation depends on whether
+Libgcrypt is operated in standard or in FIPS mode. In standard mode
+an algorithm based on the Lim-Lee prime number generator is used. In
+FIPS mode RSA keys are generated as specified in ANSI X9.31 (1998) and
+DSA keys as specified in FIPS 186-2.
+
+
+
+@node Symmetric Encryption Subsystem Architecture
+@section Symmetric Encryption Subsystem Architecture
+
+The interface to work with symmetric encryption algorithms is made up
+of functions from the @code{gcry_cipher_} name space. The
+implementation follows the open-use-close paradigm and uses registered
+algorithm modules for the actual work. Unless a module implements
+optimized cipher mode implementations, the high level code
+(@file{cipher/cipher.c}) implements the modes and calls the core
+algorithm functions to process each block.
+
+The most important functions are:
+
+@table @code
+
+@item gcry_cipher_open
+Create a new instance to encrypt or decrypt using a specified
+algorithm and mode.
+
+@item gcry_cipher_close
+Release an instance.
+
+@item gcry_cipher_setkey
+Set a key to be used for encryption or decryption.
+
+@item gcry_cipher_setiv
+Set an initialization vector to be used for encryption or decryption.
+
+@item gcry_cipher_encrypt
+@itemx gcry_cipher_decrypt
+Encrypt or decrypt data. These functions may be called with arbitrary
+amounts of data and as often as needed to encrypt or decrypt all data.
+
+@end table
+
+There are also functions to query properties of algorithms or context,
+like block length, key length, map names or to enable features like
+padding methods.
+
+
+
+@node Hashing and MACing Subsystem Architecture
+@section Hashing and MACing Subsystem Architecture
+
+The interface to work with message digests and CRC algorithms is made
+up of functions from the @code{gcry_md_} name space. The
+implementation follows the open-use-close paradigm and uses registered
+algorithm modules for the actual work. Although CRC algorithms are
+not considered cryptographic hash algorithms, they share enough
+properties so that it makes sense to handle them in the same way.
+It is possible to use several algorithms at once with one context and
+thus compute them all on the same data.
+
+The most important functions are:
+
+@table @code
+@item gcry_md_open
+Create a new message digest instance and optionally enable one
+algorithm. A flag may be used to turn the message digest algorithm
+into a HMAC algorithm.
+
+@item gcry_md_enable
+Enable an additional algorithm for the instance.
+
+@item gcry_md_setkey
+Set the key for the MAC.
+
+@item gcry_md_write
+Pass more data for computing the message digest to an instance.
+
+@item gcry_md_putc
+Buffered version of @code{gcry_md_write} implemented as a macro.
+
+@item gcry_md_read
+Finalize the computation of the message digest or HMAC and return the
+result.
+
+@item gcry_md_close
+Release an instance
+
+@item gcry_md_hash_buffer
+Convenience function to directly compute a message digest over a
+memory buffer without the need to create an instance first.
+
+@end table
+
+There are also functions to query properties of algorithms or the
+instance, like enabled algorithms, digest length, map algorithm names.
+it is also possible to reset an instance or to copy the current state
+of an instance at any time. Debug functions to write the hashed data
+to files are available as well.
+
+
+
+@node Multi-Precision-Integer Subsystem Architecture
+@section Multi-Precision-Integer Subsystem Architecture
+
+The implementation of Libgcrypt's big integer computation code is
+based on an old release of GNU Multi-Precision Library (GMP). The
+decision not to use the GMP library directly was due to stalled
+development at that time and due to security requirements which could
+not be provided by the code in GMP. As GMP does, Libgcrypt provides
+high performance assembler implementations of low level code for
+several CPUS to gain much better performance than with a generic C
+implementation.
+
+@noindent
+Major features of Libgcrypt's multi-precision-integer code compared to
+GMP are:
+
+@itemize
+@item
+Avoidance of stack based allocations to allow protection against
+swapping out of sensitive data and for easy zeroing of sensitive
+intermediate results.
+
+@item
+Optional use of secure memory and tracking of its use so that results
+are also put into secure memory.
+
+@item
+MPIs are identified by a handle (implemented as a pointer) to give
+better control over allocations and to augment them with extra
+properties like opaque data.
+
+@item
+Removal of unnecessary code to reduce complexity.
+
+@item
+Functions specialized for public key cryptography.
+
+@end itemize
+
+
+
+@node Prime-Number-Generator Subsystem Architecture
+@section Prime-Number-Generator Subsystem Architecture
+
+Libgcrypt provides an interface to its prime number generator. These
+functions make use of the internal prime number generator which is
+required for the generation for public key key pairs. The plain prime
+checking function is exported as well.
+
+The generation of random prime numbers is based on the Lim and Lee
+algorithm to create practically save primes.@footnote{Chae Hoon Lim
+and Pil Joong Lee. A key recovery attack on discrete log-based shemes
+using a prime order subgroup. In Burton S. Kaliski Jr., editor,
+Advances in Cryptology: Crypto '97, pages 249-263, Berlin /
+Heidelberg / New York, 1997. Springer-Verlag. Described on page 260.}
+This algorithm creates a pool of smaller primes, select a few of them
+to create candidate primes of the form @math{2 * p_0 * p_1 * ... * p_n
++ 1}, tests the candidate for primality and permutates the pool until
+a prime has been found. It is possible to clamp one of the small
+primes to a certain size to help DSA style algorithms. Because most
+of the small primes in the pool are not used for the resulting prime
+number, they are saved for later use (see @code{save_pool_prime} and
+@code{get_pool_prime} in @file{cipher/primegen.c}). The prime
+generator optionally supports the finding of an appropriate generator.
+
+@noindent
+The primality test works in three steps:
+
+@enumerate
+@item
+The standard sieve algorithm using the primes up to 4999 is used as a
+quick first check.
+
+@item
+A Fermat test filters out almost all non-primes.
+
+@item
+A 5 round Rabin-Miller test is finally used. The first round uses a
+witness of 2, whereas the next rounds use a random witness.
+
+@end enumerate
+
+To support the generation of RSA and DSA keys in FIPS mode according
+to X9.31 and FIPS 186-2, Libgcrypt implements two additional prime
+generation functions: @code{_gcry_derive_x931_prime} and
+@code{_gcry_generate_fips186_2_prime}. These functions are internal
+and not available through the public API.
+
+
+
+@node Random-Number Subsystem Architecture
+@section Random-Number Subsystem Architecture
+
+Libgcrypt provides 3 levels or random quality: The level
+@code{GCRY_VERY_STRONG_RANDOM} usually used for key generation, the
+level @code{GCRY_STRONG_RANDOM} for all other strong random
+requirements and the function @code{gcry_create_nonce} which is used
+for weaker usages like nonces. There is also a level
+@code{GCRY_WEAK_RANDOM} which in general maps to
+@code{GCRY_STRONG_RANDOM} except when used with the function
+@code{gcry_mpi_randomize}, where it randomizes an
+multi-precision-integer using the @code{gcry_create_nonce} function.
+
+@noindent
+There are two distinct random generators available:
+
+@itemize
+@item
+The Continuously Seeded Pseudo Random Number Generator (CSPRNG), which
+is based on the classic GnuPG derived big pool implementation.
+Implemented in @code{random/random-csprng.c} and used by default.
+@item
+A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key. Implemented in
+@code{random/random-fips.c} and used if Libgcrypt is in FIPS mode.
+@end itemize
+
+@noindent
+Both generators make use of so-called entropy gathering modules:
+
+@table @asis
+@item rndlinux
+Uses the operating system provided
+@file{/dev/random} and @file{/dev/urandom} devices.
+
+@item rndunix
+Runs several operating system commands to collect entropy from sources
+like virtual machine and process statistics. It is a kind of
+poor-man's @code{/dev/random} implementation. It is not available in
+FIPS mode.
+
+@item rndegd
+Uses the operating system provided Entropy Gathering Daemon (EGD).
+The EGD basically uses the same algorithms as rndunix does. However
+as a system daemon it keeps on running and thus can serve several
+processes requiring entropy input and does not waste collected entropy
+if the application does not need all the collected entropy. It is not
+available in FIPS mode.
+
+@item rndw32
+Targeted for the Microsoft Windows OS. It uses certain properties of
+that system and is the only gathering module available for that OS.
+
+@item rndhw
+Extra module to collect additional entropy by utilizing a hardware
+random number generator. As of now the only supported hardware RNG is
+the Padlock engine of VIA (Centaur) CPUs. It is not available in FIPS
+mode.
+
+@end table
+
+
+@menu
+* CSPRNG Description:: Description of the CSPRNG.
+* FIPS PRNG Description:: Description of the FIPS X9.31 PRNG.
+@end menu
+
+
+@node CSPRNG Description
+@subsection Description of the CSPRNG
+
+This random number generator is loosely modelled after the one
+described in Peter Gutmann's paper: "Software Generation of
+Practically Strong Random Numbers".@footnote{Also described in chapter
+6 of his book "Cryptographic Security Architecture", New York, 2004,
+ISBN 0-387-95387-6.}
+
+A pool of 600 bytes is used and mixed using the core RIPE-MD160 hash
+transform function. Several extra features are used to make the
+robust against a wide variety of attacks and to protect against
+failures of subsystems. The state of the generator may be saved to a
+file and initially seed form a file.
+
+Depending on how Libgcrypt was build the generator is able to select
+the best working entropy gathering module. It makes use of the slow
+and fast collection methods and requires the pool to initially seeded
+form the slow gatherer or a seed file. An entropy estimation is used
+to mix in enough data from the gather modules before returning the
+actual random output. Process fork detection and protection is
+implemented.
+
+@c FIXME: The design and implementaion needs a more verbose description.
+
+The implementation of the nonce generator (for
+@code{gcry_create_nonce}) is a straightforward repeated hash design: A
+28 byte buffer is initially seeded with the PID and the time in
+seconds in the first 20 bytes and with 8 bytes of random taken from
+the @code{GCRY_STRONG_RANDOM} generator. Random numbers are then
+created by hashing all the 28 bytes with SHA-1 and saving that again
+in the first 20 bytes. The hash is also returned as result.
+
+
+@node FIPS PRNG Description
+@subsection Description of the FIPS X9.31 PRNG
+
+The core of this deterministic random number generator is implemented
+according to the document ``NIST-Recommended Random Number Generator
+Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES
+Algorithms'', dated 2005-01-31. This implementation uses the AES
+variant.
+
+The generator is based on contexts to utilize the same core functions
+for all random levels as required by the high-level interface. All
+random generators return their data in 128 bit blocks. If the caller
+requests less bits, the extra bits are not used. The key for each
+generator is only set once at the first time a generator context is
+used. The seed value is set along with the key and again after 1000
+output blocks.
+
+On Unix like systems the @code{GCRY_VERY_STRONG_RANDOM} and
+@code{GCRY_STRONG_RANDOM} generators are keyed and seeded using the
+rndlinux module with the @file{/dev/radnom} device. Thus these
+generators may block until the OS kernel has collected enough entropy.
+When used with Microsoft Windows the rndw32 module is used instead.
+
+The generator used for @code{gcry_create_nonce} is keyed and seeded
+from the @code{GCRY_STRONG_RANDOM} generator. Thus is may also block
+if the @code{GCRY_STRONG_RANDOM} generator has not yet been used
+before and thus gets initialized on the first use by
+@code{gcry_create_nonce}. This special treatment is justified by the
+weaker requirements for a nonce generator and to save precious kernel
+entropy for use by the ``real'' random generators.
+
+A self-test facility uses a separate context to check the
+functionality of the core X9.31 functions using a known answers test.
+During runtime each output block is compared to the previous one to
+detect a stucked generator.
+
+The DT value for the generator is made up of the current time down to
+microseconds (if available) and a free running 64 bit counter. When
+used with the test context the DT value is taken from the context and
+incremented on each use.
+
+@c @node Helper Subsystems Architecture
+@c @section Helper Subsystems Architecture
+@c
+@c There are a few smaller subsystems which are mainly used internally by
+@c Libgcrypt but also available to applications.
+@c
+@c @menu
+@c * S-expression Subsystem Architecture:: Details about the S-expression architecture.
+@c * Memory Subsystem Architecture:: Details about the memory allocation architecture.
+@c * Miscellaneous Subsystems Architecture:: Details about other subsystems.
+@c @end menu
+@c
+@c @node S-expression Subsystem Architecture
+@c @subsection S-expression Subsystem Architecture
+@c
+@c Libgcrypt provides an interface to S-expression to create and parse
+@c them. To use an S-expression with Libgcrypt it needs first be
+@c converted into the internal representation used by Libgcrypt (the type
+@c @code{gcry_sexp_t}). The conversion functions support a large subset
+@c of the S-expression specification and further fature a printf like
+@c function to convert a list of big integers or other binary data into
+@c an S-expression.
+@c
+@c Libgcrypt currently implements S-expressions using a tagged linked
+@c list. However this is not exposed to an application and may be
+@c changed in future releases to reduce overhead when already working
+@c with canonically encoded S-expressions. Secure memory is supported by
+@c this S-expressions implementation.
+@c
+@c @node Memory Subsystem Architecture
+@c @subsection Memory Subsystem Architecture
+@c
+@c TBD.
+@c
+@c
+@c @node Miscellaneous Subsystems Architecture
+@c @subsection Miscellaneous Subsystems Architecture
+@c
+@c TBD.
+@c
+@c
+
+
+
+@c **********************************************************
+@c ******************* Appendices *************************
+@c **********************************************************
+
+@c ********************************************
+@node Self-Tests
+@appendix Description of the Self-Tests
+
+In addition to the build time regression test suite, Libgcrypt
+implements self-tests to be performed at runtime. Which self-tests
+are actually used depends on the mode Libgcrypt is used in. In
+standard mode a limited set of self-tests is run at the time an
+algorithm is first used. Note that not all algorithms feature a
+self-test in standard mode. The @code{GCRYCTL_SELFTEST} control
+command may be used to run all implemented self-tests at any time;
+this will even run more tests than those run in FIPS mode.
+
+If any of the self-tests fails, the library immediately returns an
+error code to the caller. If Libgcrypt is in FIPS mode the self-tests
+will be performed within the ``Self-Test'' state and any failure puts
+the library into the ``Error'' state.
+
+@c --------------------------------
+@section Power-Up Tests
+
+Power-up tests are only performed if Libgcrypt is in FIPS mode.
+
+@subsection Symmetric Cipher Algorithm Power-Up Tests
+
+The following symmetric encryption algorithm tests are run during
+power-up:
+
+@table @asis
+@item 3DES
+To test the 3DES 3-key EDE encryption in ECB mode these tests are
+run:
+@enumerate
+@item
+A known answer test is run on a 64 bit test vector processed by 64
+rounds of Single-DES block encryption and decryption using a key
+changed with each round.
+@item
+A known answer test is run on a 64 bit test vector processed by 16
+rounds of 2-key and 3-key Triple-DES block encryption and decryptions
+using a key changed with each round.
+@item
+10 known answer tests using 3-key Triple-DES EDE encryption, comparing
+the ciphertext to the known value, then running a decryption and
+comparing it to the initial plaintext.
+@end enumerate
+(@code{cipher/des.c:selftest})
+
+@item AES-128
+A known answer tests is run using one test vector and one test
+key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_128})
+
+@item AES-192
+A known answer tests is run using one test vector and one test
+key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_192})
+
+@item AES-256
+A known answer tests is run using one test vector and one test key
+with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_256})
+@end table
+
+@subsection Hash Algorithm Power-Up Tests
+
+The following hash algorithm tests are run during power-up:
+
+@table @asis
+@item SHA-1
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha1.c:@/selftests_sha1})
+@item SHA-224
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha256.c:@/selftests_sha224})
+@item SHA-256
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha256.c:@/selftests_sha256})
+@item SHA-384
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha512.c:@/selftests_sha384})
+@item SHA-512
+A known answer test using the string @code{"abc"} is run.
+(@code{cipher/@/sha512.c:@/selftests_sha512})
+@end table
+
+@subsection MAC Algorithm Power-Up Tests
+
+The following MAC algorithm tests are run during power-up:
+
+@table @asis
+@item HMAC SHA-1
+A known answer test using 9 byte of data and a 64 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha1})
+@item HMAC SHA-224
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha224})
+@item HMAC SHA-256
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha256})
+@item HMAC SHA-384
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha384})
+@item HMAC SHA-512
+A known answer test using 28 byte of data and a 4 byte key is run.
+(@code{cipher/hmac-tests.c:selftests_sha512})
+@end table
+
+@subsection Random Number Power-Up Test
+
+The DRNG is tested during power-up this way:
+
+@enumerate
+@item
+Requesting one block of random using the public interface to check
+general working and the duplicated block detection.
+@item
+3 know answer tests using pre-defined keys, seed and initial DT
+values. For each test 3 blocks of 16 bytes are requested and compared
+to the expected result. The DT value is incremented for each block.
+@end enumerate
+
+@subsection Public Key Algorithm Power-Up Tests
+
+The public key algorithms are tested during power-up:
+
+@table @asis
+@item RSA
+A pre-defined 1024 bit RSA key is used and these tests are run
+in turn:
+@enumerate
+@item
+Conversion of S-expression to internal format.
+(@code{cipher/@/rsa.c:@/selftests_rsa})
+@item
+Private key consistency check.
+(@code{cipher/@/rsa.c:@/selftests_rsa})
+@item
+A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-1.
+The result is verified using the public key against the original data
+and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_1024})
+@item
+A 1000 bit random value is encrypted and checked that it does not
+match the orginal random value. The encrtypted result is then
+decrypted and checked that it macthes the original random value.
+(@code{cipher/@/rsa.c:@/selftest_encr_1024})
+@end enumerate
+
+@item DSA
+A pre-defined 1024 bit DSA key is used and these tests are run in turn:
+@enumerate
+@item
+Conversion of S-expression to internal format.
+(@code{cipher/@/dsa.c:@/selftests_dsa})
+@item
+Private key consistency check.
+(@code{cipher/@/dsa.c:@/selftests_dsa})
+@item
+A pre-defined 20 byte value is signed with PKCS#1 padding for
+SHA-1. The result is verified using the public key against the
+original data and against modified data.
+(@code{cipher/@/dsa.c:@/selftest_sign_1024})
+@end enumerate
+@end table
+
+@subsection Integrity Power-Up Tests
+
+The integrity of the Libgcrypt is tested during power-up but only if
+checking has been enabled at build time. The check works by computing
+a HMAC SHA-256 checksum over the file used to load Libgcrypt into
+memory. That checksum is compared against a checksum stored in a file
+of the same name but with a single dot as a prefix and a suffix of
+@file{.hmac}.
+
+
+@subsection Critical Functions Power-Up Tests
+
+The 3DES weak key detection is tested during power-up by calling the
+detection function with keys taken from a table listening all weak
+keys. The table itself is protected using a SHA-1 hash.
+(@code{cipher/@/des.c:@/selftest})
+
+
+
+@c --------------------------------
+@section Conditional Tests
+
+The conditional tests are performed if a certain contidion is met.
+This may occur at any time; the library does not necessary enter the
+``Self-Test'' state to run these tests but will transit to the
+``Error'' state if a test failed.
+
+@subsection Key-Pair Generation Tests
+
+After an asymmetric key-pair has been generated, Libgcrypt runs a
+pair-wise consistency tests on the generated key. On failure the
+generated key is not used, an error code is returned and, if in FIPS
+mode, the library is put into the ``Error'' state.
+
+@table @asis
+@item RSA
+The test uses a random number 64 bits less the size of the modulus as
+plaintext and runs an encryption and decryption operation in turn. The
+encrypted value is checked to not match the plaintext and the result
+of the decryption is checked to match the plaintext.
+
+A new random number of the same size is generated, signed and verified
+to test the correctness of the signing operation. As a second signing
+test, the signature is modified by incrementing its value and then
+verified with the expected result that the verification fails.
+(@code{cipher/@/rsa.c:@/test_keys})
+@item DSA
+The test uses a random number of the size of the Q parameter to create
+a signature and then checks that the signature verifies. As a second
+signing test, the data is modified by incrementing its value and then
+verified against the signature with the expected result that the
+verification fails. (@code{cipher/@/dsa.c:@/test_keys})
+@end table
+
+
+@subsection Software Load Tests
+
+Loading of extra modules into libgcrypt is disabled in FIPS mode and
+thus no tests are
+implemented. (@code{cipher/@/cipher.c:@/_gcry_cipher_register},
+@code{cipher/@/md.c:@/_gcry_md_register},
+@code{cipher/@/pubkey.c:@/_gcry_pk_register})
+
+
+@subsection Manual Key Entry Tests
+
+A manual key entry feature is not implemented in Libgcrypt.
+
+
+@subsection Continuous RNG Tests
+
+The continuous random number test is only used in FIPS mode. The RNG
+generates blocks of 128 bit size; the first block generated per
+context is saved in the context and another block is generated to be
+returned to the caller. Each block is compared against the saved
+block and then stored in the context. If a duplicated block is
+detected an error is signaled and the library is put into the
+``Fatal-Error'' state.
+(@code{random/@/random-fips.c:@/x931_aes_driver})
+
+
+
+@c --------------------------------
+@section Application Requested Tests
+
+The application may requests tests at any time by means of the
+@code{GCRYCTL_SELFTEST} control command. Note that using these tests
+is not FIPS conform: Although Libgcrypt rejects all application
+requests for services while running self-tests, it does not ensure
+that no other operations of Libgcrypt are still being executed. Thus,
+in FIPS mode an application requesting self-tests needs to power-cycle
+Libgcrypt instead.
+
+When self-tests are requested, Libgcrypt runs all the tests it does
+during power-up as well as a few extra checks as described below.
+
+@subsection Symmetric Cipher Algorithm Tests
+
+The following symmetric encryption algorithm tests are run in addition
+to the power-up tests:
+
+@table @asis
+@item AES-128
+A known answer tests with test vectors taken from NIST SP800-38a and
+using the high level functions is run for block modes CFB and OFB.
+
+@end table
+
+@subsection Hash Algorithm Tests
+
+The following hash algorithm tests are run in addition to the
+power-up tests:
+
+@table @asis
+@item SHA-1
+@itemx SHA-224
+@itemx SHA-256
+@enumerate
+@item
+A known answer test using a 56 byte string is run.
+@item
+A known answer test using a string of one million letters "a" is run.
+@end enumerate
+(@code{cipher/@/sha1.c:@/selftests_sha1},
+@code{cipher/@/sha256.c:@/selftests_sha224},
+@code{cipher/@/sha256.c:@/selftests_sha256})
+@item SHA-384
+@item SHA-512
+@enumerate
+@item
+A known answer test using a 112 byte string is run.
+@item
+A known answer test using a string of one million letters "a" is run.
+@end enumerate
+(@code{cipher/@/sha512.c:@/selftests_sha384},
+@code{cipher/@/sha512.c:@/selftests_sha512})
+@end table
+
+@subsection MAC Algorithm Tests
+
+The following MAC algorithm tests are run in addition to the power-up
+tests:
+
+@table @asis
+@item HMAC SHA-1
+@enumerate
+@item
+A known answer test using 9 byte of data and a 20 byte key is run.
+@item
+A known answer test using 9 byte of data and a 100 byte key is run.
+@item
+A known answer test using 9 byte of data and a 49 byte key is run.
+@end enumerate
+(@code{cipher/hmac-tests.c:selftests_sha1})
+@item HMAC SHA-224
+@itemx HMAC SHA-256
+@itemx HMAC SHA-384
+@itemx HMAC SHA-512
+@enumerate
+@item
+A known answer test using 9 byte of data and a 20 byte key is run.
+@item
+A known answer test using 50 byte of data and a 20 byte key is run.
+@item
+A known answer test using 50 byte of data and a 26 byte key is run.
+@item
+A known answer test using 54 byte of data and a 131 byte key is run.
+@item
+A known answer test using 152 byte of data and a 131 byte key is run.
+@end enumerate
+(@code{cipher/@/hmac-tests.c:@/selftests_sha224},
+@code{cipher/@/hmac-tests.c:@/selftests_sha256},
+@code{cipher/@/hmac-tests.c:@/selftests_sha384},
+@code{cipher/@/hmac-tests.c:@/selftests_sha512})
+@end table
+
+
+@c ********************************************
+@node FIPS Mode
+@appendix Description of the FIPS Mode
+
+This appendix gives detailed information pertaining to the FIPS mode.
+In particular, the changes to the standard mode and the finite state
+machine are described. The self-tests required in this mode are
+described in the appendix on self-tests.
+
+@c -------------------------------
+@section Restrictions in FIPS Mode
+
+@noindent
+If Libgcrypt is used in FIPS mode these restrictions are effective:
+
+@itemize
+@item
+The cryptographic algorithms are restricted to this list:
+
+@table @asis
+@item GCRY_CIPHER_3DES
+3 key EDE Triple-DES symmetric encryption.
+@item GCRY_CIPHER_AES128
+AES 128 bit symmetric encryption.
+@item GCRY_CIPHER_AES192
+AES 192 bit symmetric encryption.
+@item GCRY_CIPHER_AES256
+AES 256 bit symmetric encryption.
+@item GCRY_MD_SHA1
+SHA-1 message digest.
+@item GCRY_MD_SHA224
+SHA-224 message digest.
+@item GCRY_MD_SHA256
+SHA-256 message digest.
+@item GCRY_MD_SHA384
+SHA-384 message digest.
+@item GCRY_MD_SHA512
+SHA-512 message digest.
+@item GCRY_MD_SHA1,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-1 message digest.
+@item GCRY_MD_SHA224,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-224 message digest.
+@item GCRY_MD_SHA256,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-256 message digest.
+@item GCRY_MD_SHA384,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-384 message digest.
+@item GCRY_MD_SHA512,GCRY_MD_FLAG_HMAC
+HMAC using a SHA-512 message digest.
+@item GCRY_PK_RSA
+RSA encryption and signing.
+@item GCRY_PK_DSA
+DSA signing.
+@end table
+
+Note that the CRC algorithms are not considered cryptographic algorithms
+and thus are in addition available.
+
+@item
+RSA key generation refuses to create a key with a keysize of
+less than 1024 bits.
+
+@item
+DSA key generation refuses to create a key with a keysize other
+than 1024 bits.
+
+@item
+The @code{transient-key} flag for RSA and DSA key generation is ignored.
+
+@item
+Support for the VIA Padlock engine is disabled.
+
+@item
+FIPS mode may only be used on systems with a /dev/random device.
+Switching into FIPS mode on other systems will fail at runtime.
+
+@item
+Saving and loading a random seed file is ignored.
+
+@item
+An X9.31 style random number generator is used in place of the
+large-pool-CSPRNG generator.
+
+@item
+The command @code{GCRYCTL_ENABLE_QUICK_RANDOM} is ignored.
+
+@item
+The Alternative Public Key Interface (@code{gcry_ac_xxx}) is not
+supported and all API calls return an error.
+
+@item
+Registration of external modules is not supported.
+
+@item
+Message digest debugging is disabled.
+
+@item
+All debug output related to cryptographic data is suppressed.
+
+@item
+On-the-fly self-tests are not performed, instead self-tests are run
+before entering operational state.
+
+@item
+The function @code{gcry_set_allocation_handler} may not be used. If
+it is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is
+enabled, in which case Libgcrypt will enter the error state.
+
+@item
+The digest algorithm MD5 may not be used. If it is used Libgcrypt
+disables FIPS mode unless Enforced FIPS mode is enabled, in which case
+Libgcrypt will enter the error state.
+
+@item
+In Enforced FIPS mode the command @code{GCRYCTL_DISABLE_SECMEM} is
+ignored. In standard FIPS mode it disables FIPS mode.
+
+@item
+A handler set by @code{gcry_set_outofcore_handler} is ignored.
+@item
+A handler set by @code{gcry_set_fatalerror_handler} is ignored.
+
+@end itemize
+
+Note that when we speak about disabling FIPS mode, it merely means
+that the function @code{gcry_fips_mode_active} returns false; it does
+not mean that any non FIPS algorithms are allowed.
+
+@c ********************************************
+@section FIPS Finite State Machine
+
+The FIPS mode of libgcrypt implements a finite state machine (FSM) using
+8 states (@pxref{tbl:fips-states}) and checks at runtime that only valid
+transitions (@pxref{tbl:fips-state-transitions}) may happen.
+
+@float Figure,fig:fips-fsm
+@caption{FIPS mode state diagram}
+@center @image{fips-fsm,150mm,,FIPS FSM Diagram}
+@end float
+
+@float Table,tbl:fips-states
+@caption{FIPS mode states}
+@noindent
+States used by the FIPS FSM:
+@table @asis
+
+@item Power-Off
+Libgcrypt is not runtime linked to another application. This usually
+means that the library is not loaded into main memory. This state is
+documentation only.
+
+@item Power-On
+Libgcrypt is loaded into memory and API calls may be made. Compiler
+introducted constructor functions may be run. Note that Libgcrypt does
+not implement any arbitrary constructor functions to be called by the
+operating system
+
+@item Init
+The Libgcrypt initialization functions are performed and the library has
+not yet run any self-test.
+
+@item Self-Test
+Libgcrypt is performing self-tests.
+
+@item Operational
+Libgcrypt is in the operational state and all interfaces may be used.
+
+@item Error
+Libgrypt is in the error state. When calling any FIPS relevant
+interfaces they either return an error (@code{GPG_ERR_NOT_OPERATIONAL})
+or put Libgcrypt into the Fatal-Error state and won't return.
+
+@item Fatal-Error
+Libgcrypt is in a non-recoverable error state and
+will automatically transit into the Shutdown state.
+
+@item Shutdown
+Libgcrypt is about to be terminated and removed from the memory. The
+application may at this point still runing cleanup handlers.
+
+@end table
+@end float
+
+
+@float Table,tbl:fips-state-transitions
+@caption{FIPS mode state transitions}
+@noindent
+The valid state transitions (@pxref{fig:fips-fsm}) are:
+@table @code
+@item 1
+Power-Off to Power-On is implicitly done by the OS loading Libgcrypt as
+a shared library and having it linked to an application.
+
+@item 2
+Power-On to Init is triggered by the application calling the
+Libgcrypt intialization function @code{gcry_check_version}.
+
+@item 3
+Init to Self-Test is either triggred by a dedicated API call or implicit
+by invoking a libgrypt service conrolled by the FSM.
+
+@item 4
+Self-Test to Operational is triggered after all self-tests passed
+successfully.
+
+@item 5
+Operational to Shutdown is an artifical state without any direct action
+in Libgcrypt. When reaching the Shutdown state the library is
+deinitialized and can't return to any other state again.
+
+@item 6
+Shutdown to Power-off is the process of removing Libgcrypt from the
+computer's memory. For obvious reasons the Power-Off state can't be
+represented within Libgcrypt and thus this transition is for
+documentation only.
+
+@item 7
+Operational to Error is triggered if Libgcrypt detected an application
+error which can't be returned to the caller but still allows Libgcrypt
+to properly run. In the Error state all FIPS relevant interfaces return
+an error code.
+
+@item 8
+Error to Shutdown is similar to the Operational to Shutdown transition
+(5).
+
+@item 9
+Error to Fatal-Error is triggred if Libgrypt detects an fatal error
+while already being in Error state.
+
+@item 10
+Fatal-Error to Shutdown is automatically entered by Libgcrypt
+after having reported the error.
+
+@item 11
+Power-On to Shutdown is an artifical state to document that Libgcrypt
+has not ye been initializaed but the process is about to terminate.
+
+@item 12
+Power-On to Fatal-Error will be triggerd if certain Libgcrypt functions
+are used without having reached the Init state.
+
+@item 13
+Self-Test to Fatal-Error is triggred by severe errors in Libgcrypt while
+running self-tests.
+
+@item 14
+Self-Test to Error is triggred by a failed self-test.
+
+@item 15
+Operational to Fatal-Error is triggered if Libcrypt encountered a
+non-recoverable error.
+
+@item 16
+Operational to Self-Test is triggred if the application requested to run
+the self-tests again.
+
+@item 17
+Error to Self-Test is triggered if the application has requested to run
+self-tests to get to get back into operational state after an error.
+
+@item 18
+Init to Error is triggered by errors in the initialization code.
+
+@item 19
+Init to Fatal-Error is triggered by non-recoverable errors in the
+initialization code.
+
+@item 20
+Error to Error is triggered by errors while already in the Error
+state.
+
+
+@end table
+@end float
+
+@c ********************************************
+@section FIPS Miscellaneous Information
+
+Libgcrypt does not do any key management on itself; the application
+needs to care about it. Keys which are passed to Libgcrypt should be
+allocated in secure memory as available with the functions
+@code{gcry_malloc_secure} and @code{gcry_calloc_secure}. By calling
+@code{gcry_free} on this memory, the memory and thus the keys are
+overwritten with zero bytes before releasing the memory.
+
+For use with the random number generator, Libgcrypt generates 3
+internal keys which are stored in the encryption contexts used by the
+RNG. These keys are stored in secure memory for the lifetime of the
+process. Application are required to use @code{GCRYCTL_TERM_SECMEM}
+before process termination. This will zero out the entire secure
+memory and thus also the encryption contexts with these keys.
+
+
+
+@c **********************************************************
+@c ************* Appendices (license etc.) ****************
+@c **********************************************************
+@include lgpl.texi
+
+@include gpl.texi
+
+@node Figures and Tables
+@unnumbered List of Figures and Tables
+
+@listoffloats Figure
+
+@listoffloats Table
+
+@node Concept Index
+@unnumbered Concept Index
+
+@printindex cp
+
+@node Function and Data Index
+@unnumbered Function and Data Index
+
+@printindex fn
+
+
+
+@bye
+
+GCRYCTL_SET_RANDOM_DAEMON_SOCKET
+GCRYCTL_USE_RANDOM_DAEMON
+The random damon is still a bit experimental, thus we do not document
+them. Note that they should be used during initialization and that
+these functions are not really thread safe.
+
+
+
+
+@c LocalWords: int HD
--- /dev/null
+@node Copying
+@unnumbered GNU General Public License
+
+@cindex GPL, GNU General Public License
+@center Version 2, June 1991
+
+@display
+Copyright @copyright{} 1989, 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.
+@end display
+
+@heading Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software---to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, 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 software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, 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 redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+@iftex
+@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate
+@item
+This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The ``Program'', below,
+refers to any such program or work, and a ``work based on the Program''
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term ``modification''.) Each licensee is addressed as ``you''.
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+@item
+You may copy and distribute verbatim copies of the Program's
+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 give any other recipients of the Program a copy of this License
+along with the Program.
+
+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.
+
+@item
+You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+@enumerate a
+@item
+You must cause the modified files to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause any work that you distribute or publish, that in
+whole or in part contains or is derived from the Program or any
+part thereof, to be licensed as a whole at no charge to all third
+parties under the terms of this License.
+
+@item
+If the modified program normally reads commands interactively
+when run, you must cause it, when started running for such
+interactive use in the most ordinary way, to print or display an
+announcement including an appropriate copyright notice and a
+notice that there is no warranty (or else, saying that you provide
+a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this
+License. (Exception: if the Program itself is interactive but
+does not normally print such an announcement, your work based on
+the Program is not required to print an announcement.)
+@end enumerate
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+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 Program, 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 Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+@item
+You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+@enumerate a
+@item
+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; or,
+
+@item
+Accompany it with a written offer, valid for at least three
+years, to give any third party, for a charge no more than your
+cost of physically performing source distribution, a complete
+machine-readable copy of the corresponding source code, to be
+distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+@item
+Accompany it with the information you received as to the offer
+to distribute corresponding source code. (This alternative is
+allowed only for noncommercial distribution and only if you
+received the program in object code or executable form with such
+an offer, in accord with Subsection b above.)
+@end enumerate
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, 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 executable. 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.
+
+If distribution of executable or 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 counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+@item
+You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program 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.
+
+@item
+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 Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+@item
+Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program 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.
+
+@item
+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 Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program 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 Program.
+
+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.
+
+@item
+If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program 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.
+
+@item
+The Free Software Foundation may publish revised and/or new versions
+of the 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 Program
+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 Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+@item
+If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM ``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 PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+@item
+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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+@end enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@heading How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. 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.
+
+@smallexample
+@var{one line to give the program's name and an idea of what it does.}
+Copyright (C) 19@var{yy} @var{name of author}
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+@end smallexample
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+@smallexample
+Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
+Gnomovision comes with ABSOLUTELY NO WARRANTY; for details
+type `show w'. This is free software, and you are welcome
+to redistribute it under certain conditions; type `show c'
+for details.
+@end smallexample
+
+The hypothetical commands @samp{show w} and @samp{show c} should show
+the appropriate parts of the General Public License. Of course, the
+commands you use may be called something other than @samp{show w} and
+@samp{show c}; they could even be mouse-clicks or menu items---whatever
+suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a ``copyright disclaimer'' for the program, if
+necessary. Here is a sample; alter the names:
+
+@smallexample
+@group
+Yoyodyne, Inc., hereby disclaims all copyright
+interest in the program `Gnomovision'
+(which makes passes at compilers) written
+by James Hacker.
+
+@var{signature of Ty Coon}, 1 April 1989
+Ty Coon, President of Vice
+@end group
+@end smallexample
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null
+@node Library Copying
+@unnumbered GNU Lesser General Public License
+
+@cindex LGPL, GNU Lesser General Public License
+@center Version 2.1, February 1999
+
+@display
+Copyright @copyright{} 1991, 1999 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 Lesser GPL. It also counts
+as the successor of the GNU Library Public License, version 2, hence the
+version number 2.1.]
+@end display
+
+@heading 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 Lesser General Public License, applies to some
+specially designated software---typically libraries---of the Free
+Software Foundation and other authors who decide to use it. You can use
+it too, but we suggest you first think carefully about whether this
+license or the ordinary General Public License is the better strategy to
+use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of it
+in new free programs; and that you are informed that you can do these
+things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+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 other code 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.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the @dfn{Lesser} General Public License because it
+does @emph{Less} to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ 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, whereas the latter must
+be combined with the library in order to run.
+
+@iftex
+@heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end iftex
+@ifinfo
+@center GNU LESSER GENERAL PUBLIC LICENSE
+@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+@end ifinfo
+
+@enumerate 0
+@item
+This License Agreement applies to any software library or other program
+which contains a notice placed by the copyright holder or other
+authorized party saying it may be distributed under the terms of this
+Lesser 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.
+
+@item
+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.
+
+@item
+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:
+
+@enumerate a
+@item
+The modified work must itself be a software library.
+
+@item
+You must cause the files modified to carry prominent notices
+stating that you changed the files and the date of any change.
+
+@item
+You must cause the whole of the work to be licensed at no
+charge to all third parties under the terms of this License.
+
+@item
+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.)
+@end enumerate
+
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+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.
+
+@item
+As an exception to the Sections above, you may also combine 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:
+
+@enumerate a
+@item
+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.)
+
+@item
+Use a suitable shared library mechanism for linking with the Library. A
+suitable mechanism is one that (1) uses at run time a copy of the
+library already present on the user's computer system, rather than
+copying library functions into the executable, and (2) will operate
+properly with a modified version of the library, if the user installs
+one, as long as the modified version is interface-compatible with the
+version that the work was made with.
+
+@item
+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.
+
+@item
+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.
+
+@item
+Verify that the user has already received a copy of these
+materials or that you have already sent this user a copy.
+@end enumerate
+
+ 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 materials to be 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.
+
+@item
+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:
+
+@enumerate a
+@item
+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.
+
+@item
+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.
+@end enumerate
+
+@item
+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.
+
+@item
+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.
+
+@item
+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 with
+this License.
+
+@item
+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.
+
+@item
+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.
+
+@item
+The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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.
+
+@item
+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.
+
+@iftex
+@heading NO WARRANTY
+@end iftex
+@ifinfo
+@center NO WARRANTY
+@end ifinfo
+
+@item
+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.
+
+@item
+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 enumerate
+
+@iftex
+@heading END OF TERMS AND CONDITIONS
+@end iftex
+@ifinfo
+@center END OF TERMS AND CONDITIONS
+@end ifinfo
+
+@page
+@heading 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.
+
+@smallexample
+@var{one line to give the library's name and an idea of what it does.}
+Copyright (C) @var{year} @var{name of author}
+
+This library is free software; you can redistribute it and/or modify it
+under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 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
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser 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.
+@end smallexample
+
+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:
+
+@smallexample
+Yoyodyne, Inc., hereby disclaims all copyright interest in the library
+`Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+@var{signature of Ty Coon}, 1 April 1990
+Ty Coon, President of Vice
+@end smallexample
+
+That's all there is to it!
--- /dev/null
+%!PS-Adobe-2.0 EPSF-2.0
+%%Title: /home/wk/w/libgcrypt/doc/libgcrypt-modules.fig
+%%Creator: fig2dev Version 3.2 Patchlevel 4
+%%CreationDate: Mon Mar 28 14:04:57 2011
+%%For: wk@vigenere (Werner Koch,,,)
+%%BoundingBox: 0 0 488 300
+%%Magnification: 1.0000
+%%EndComments
+/$F2psDict 200 dict def
+$F2psDict begin
+$F2psDict /mtrx matrix put
+/col-1 {0 setgray} bind def
+/col0 {0.000 0.000 0.000 srgb} bind def
+/col1 {0.000 0.000 1.000 srgb} bind def
+/col2 {0.000 1.000 0.000 srgb} bind def
+/col3 {0.000 1.000 1.000 srgb} bind def
+/col4 {1.000 0.000 0.000 srgb} bind def
+/col5 {1.000 0.000 1.000 srgb} bind def
+/col6 {1.000 1.000 0.000 srgb} bind def
+/col7 {1.000 1.000 1.000 srgb} bind def
+/col8 {0.000 0.000 0.560 srgb} bind def
+/col9 {0.000 0.000 0.690 srgb} bind def
+/col10 {0.000 0.000 0.820 srgb} bind def
+/col11 {0.530 0.810 1.000 srgb} bind def
+/col12 {0.000 0.560 0.000 srgb} bind def
+/col13 {0.000 0.690 0.000 srgb} bind def
+/col14 {0.000 0.820 0.000 srgb} bind def
+/col15 {0.000 0.560 0.560 srgb} bind def
+/col16 {0.000 0.690 0.690 srgb} bind def
+/col17 {0.000 0.820 0.820 srgb} bind def
+/col18 {0.560 0.000 0.000 srgb} bind def
+/col19 {0.690 0.000 0.000 srgb} bind def
+/col20 {0.820 0.000 0.000 srgb} bind def
+/col21 {0.560 0.000 0.560 srgb} bind def
+/col22 {0.690 0.000 0.690 srgb} bind def
+/col23 {0.820 0.000 0.820 srgb} bind def
+/col24 {0.500 0.190 0.000 srgb} bind def
+/col25 {0.630 0.250 0.000 srgb} bind def
+/col26 {0.750 0.380 0.000 srgb} bind def
+/col27 {1.000 0.500 0.500 srgb} bind def
+/col28 {1.000 0.630 0.630 srgb} bind def
+/col29 {1.000 0.750 0.750 srgb} bind def
+/col30 {1.000 0.880 0.880 srgb} bind def
+/col31 {1.000 0.840 0.000 srgb} bind def
+/col32 {0.555 0.555 0.555 srgb} bind def
+/col33 {0.254 0.270 0.254 srgb} bind def
+/col34 {0.750 0.750 0.750 srgb} bind def
+/col35 {0.500 0.500 0.500 srgb} bind def
+/col36 {0.387 0.387 0.387 srgb} bind def
+/col37 {0.801 0.801 0.801 srgb} bind def
+/col38 {0.422 0.422 0.422 srgb} bind def
+/col39 {0.773 0.715 0.590 srgb} bind def
+/col40 {0.934 0.969 0.996 srgb} bind def
+/col41 {0.859 0.793 0.648 srgb} bind def
+/col42 {0.250 0.250 0.250 srgb} bind def
+/col43 {0.875 0.875 0.875 srgb} bind def
+/col44 {0.555 0.559 0.555 srgb} bind def
+/col45 {0.664 0.664 0.664 srgb} bind def
+/col46 {0.332 0.332 0.332 srgb} bind def
+/col47 {0.840 0.840 0.840 srgb} bind def
+/col48 {0.680 0.680 0.680 srgb} bind def
+/col49 {0.742 0.742 0.742 srgb} bind def
+/col50 {0.316 0.316 0.316 srgb} bind def
+/col51 {0.902 0.887 0.902 srgb} bind def
+/col52 {0.000 0.000 0.285 srgb} bind def
+/col53 {0.473 0.473 0.473 srgb} bind def
+/col54 {0.188 0.203 0.188 srgb} bind def
+/col55 {0.254 0.254 0.254 srgb} bind def
+/col56 {0.777 0.711 0.586 srgb} bind def
+/col57 {0.863 0.613 0.574 srgb} bind def
+/col58 {0.941 0.922 0.875 srgb} bind def
+/col59 {0.762 0.762 0.762 srgb} bind def
+/col60 {0.883 0.781 0.656 srgb} bind def
+/col61 {0.879 0.879 0.879 srgb} bind def
+/col62 {0.820 0.820 0.820 srgb} bind def
+/col63 {0.926 0.926 0.926 srgb} bind def
+/col64 {0.852 0.477 0.102 srgb} bind def
+/col65 {0.941 0.891 0.102 srgb} bind def
+/col66 {0.531 0.488 0.758 srgb} bind def
+/col67 {0.836 0.836 0.836 srgb} bind def
+/col68 {0.547 0.547 0.645 srgb} bind def
+/col69 {0.289 0.289 0.289 srgb} bind def
+/col70 {0.547 0.418 0.418 srgb} bind def
+/col71 {0.352 0.352 0.352 srgb} bind def
+/col72 {0.715 0.605 0.449 srgb} bind def
+/col73 {0.254 0.574 0.996 srgb} bind def
+/col74 {0.746 0.438 0.230 srgb} bind def
+/col75 {0.855 0.465 0.000 srgb} bind def
+/col76 {0.852 0.719 0.000 srgb} bind def
+/col77 {0.000 0.391 0.000 srgb} bind def
+/col78 {0.352 0.418 0.230 srgb} bind def
+/col79 {0.824 0.824 0.824 srgb} bind def
+/col80 {0.555 0.555 0.641 srgb} bind def
+/col81 {0.949 0.723 0.363 srgb} bind def
+/col82 {0.535 0.598 0.418 srgb} bind def
+/col83 {0.391 0.391 0.391 srgb} bind def
+/col84 {0.715 0.898 0.996 srgb} bind def
+/col85 {0.523 0.750 0.922 srgb} bind def
+/col86 {0.738 0.738 0.738 srgb} bind def
+/col87 {0.824 0.582 0.320 srgb} bind def
+/col88 {0.594 0.820 0.992 srgb} bind def
+/col89 {0.547 0.609 0.418 srgb} bind def
+/col90 {0.965 0.418 0.000 srgb} bind def
+/col91 {0.352 0.418 0.223 srgb} bind def
+/col92 {0.547 0.609 0.418 srgb} bind def
+/col93 {0.547 0.609 0.480 srgb} bind def
+/col94 {0.094 0.289 0.094 srgb} bind def
+/col95 {0.676 0.676 0.676 srgb} bind def
+/col96 {0.965 0.738 0.352 srgb} bind def
+/col97 {0.387 0.418 0.609 srgb} bind def
+/col98 {0.965 0.965 0.965 srgb} bind def
+/col99 {0.867 0.000 0.000 srgb} bind def
+/col100 {0.676 0.676 0.676 srgb} bind def
+/col101 {0.965 0.738 0.352 srgb} bind def
+/col102 {0.676 0.676 0.676 srgb} bind def
+/col103 {0.965 0.738 0.352 srgb} bind def
+/col104 {0.387 0.418 0.609 srgb} bind def
+/col105 {0.320 0.418 0.160 srgb} bind def
+/col106 {0.578 0.578 0.578 srgb} bind def
+/col107 {0.000 0.387 0.000 srgb} bind def
+/col108 {0.000 0.387 0.289 srgb} bind def
+/col109 {0.480 0.516 0.289 srgb} bind def
+/col110 {0.902 0.738 0.480 srgb} bind def
+/col111 {0.645 0.707 0.773 srgb} bind def
+/col112 {0.418 0.418 0.578 srgb} bind def
+/col113 {0.516 0.418 0.418 srgb} bind def
+/col114 {0.320 0.609 0.289 srgb} bind def
+/col115 {0.836 0.902 0.902 srgb} bind def
+/col116 {0.320 0.387 0.387 srgb} bind def
+/col117 {0.094 0.418 0.289 srgb} bind def
+/col118 {0.609 0.645 0.707 srgb} bind def
+/col119 {0.996 0.578 0.000 srgb} bind def
+/col120 {0.996 0.578 0.000 srgb} bind def
+/col121 {0.000 0.387 0.289 srgb} bind def
+/col122 {0.480 0.516 0.289 srgb} bind def
+/col123 {0.387 0.449 0.480 srgb} bind def
+/col124 {0.902 0.738 0.480 srgb} bind def
+/col125 {0.867 0.867 0.867 srgb} bind def
+/col126 {0.949 0.930 0.824 srgb} bind def
+/col127 {0.957 0.680 0.363 srgb} bind def
+/col128 {0.582 0.805 0.598 srgb} bind def
+/col129 {0.707 0.082 0.488 srgb} bind def
+/col130 {0.930 0.930 0.930 srgb} bind def
+/col131 {0.516 0.516 0.516 srgb} bind def
+/col132 {0.480 0.480 0.480 srgb} bind def
+/col133 {0.000 0.352 0.000 srgb} bind def
+/col134 {0.902 0.449 0.449 srgb} bind def
+/col135 {0.996 0.793 0.191 srgb} bind def
+/col136 {0.160 0.473 0.289 srgb} bind def
+/col137 {0.867 0.156 0.129 srgb} bind def
+/col138 {0.129 0.348 0.773 srgb} bind def
+/col139 {0.969 0.969 0.969 srgb} bind def
+/col140 {0.898 0.898 0.898 srgb} bind def
+/col141 {0.129 0.516 0.352 srgb} bind def
+/col142 {0.785 0.785 0.785 srgb} bind def
+/col143 {0.871 0.844 0.871 srgb} bind def
+/col144 {0.965 0.949 0.965 srgb} bind def
+
+end
+save
+newpath 0 300 moveto 0 0 lineto 488 0 lineto 488 300 lineto closepath clip newpath
+-32.6 348.9 translate
+1 -1 scale
+
+/cp {closepath} bind def
+/ef {eofill} bind def
+/gr {grestore} bind def
+/gs {gsave} bind def
+/sa {save} bind def
+/rs {restore} bind def
+/l {lineto} bind def
+/m {moveto} bind def
+/rm {rmoveto} bind def
+/n {newpath} bind def
+/s {stroke} bind def
+/sh {show} bind def
+/slc {setlinecap} bind def
+/slj {setlinejoin} bind def
+/slw {setlinewidth} bind def
+/srgb {setrgbcolor} bind def
+/rot {rotate} bind def
+/sc {scale} bind def
+/sd {setdash} bind def
+/ff {findfont} bind def
+/sf {setfont} bind def
+/scf {scalefont} bind def
+/sw {stringwidth} bind def
+/tr {translate} bind def
+/tnt {dup dup currentrgbcolor
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add
+ 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
+ bind def
+/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
+ 4 -2 roll mul srgb} bind def
+/reencdict 12 dict def /ReEncode { reencdict begin
+/newcodesandnames exch def /newfontname exch def /basefontname exch def
+/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def
+basefontdict { exch dup /FID ne { dup /Encoding eq
+{ exch dup length array copy newfont 3 1 roll put }
+{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall
+newfont /FontName newfontname put newcodesandnames aload pop
+128 1 255 { newfont /Encoding get exch /.notdef put } for
+newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat
+newfontname newfont definefont pop end } def
+/isovec [
+8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde
+8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis
+8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron
+8#220 /dotlessi 8#230 /oe 8#231 /OE
+8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling
+8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis
+8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot
+8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus
+8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph
+8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine
+8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf
+8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute
+8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring
+8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute
+8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute
+8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve
+8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply
+8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex
+8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave
+8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring
+8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute
+8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute
+8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve
+8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide
+8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex
+8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def
+/Helvetica /Helvetica-iso isovec ReEncode
+/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
+/$F2psEnd {$F2psEnteredState restore end} def
+
+$F2psBegin
+10 setmiterlimit
+0 slj 0 slc
+ 0.06299 0.06299 sc
+%
+% Fig objects follow
+%
+%
+% here starts figure with depth 50
+/Helvetica-iso ff 300.00 scf sf
+900 1440 m
+gs 1 -1 sc (Public-Key) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+% Polyline
+15.000 slw
+n 645 810 m 540 810 540 2055 105 arcto 4 {pop} repeat
+ 540 2160 2685 2160 105 arcto 4 {pop} repeat
+ 2790 2160 2790 915 105 arcto 4 {pop} repeat
+ 2790 810 645 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 300.00 scf sf
+630 3420 m
+gs 1 -1 sc (Multi-Precision-) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 3795 m
+gs 1 -1 sc (Integers) col0 sh gr
+% Polyline
+n 645 2790 m 540 2790 540 4035 105 arcto 4 {pop} repeat
+ 540 4140 2685 4140 105 arcto 4 {pop} repeat
+ 2790 4140 2790 2895 105 arcto 4 {pop} repeat
+ 2790 2790 645 2790 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3420 m
+gs 1 -1 sc (Prime-Number) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3795 m
+gs 1 -1 sc (Generator) col0 sh gr
+% Polyline
+n 3345 2790 m 3240 2790 3240 4035 105 arcto 4 {pop} repeat
+ 3240 4140 5385 4140 105 arcto 4 {pop} repeat
+ 5490 4140 5490 2895 105 arcto 4 {pop} repeat
+ 5490 2790 3345 2790 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3435 m
+gs 1 -1 sc (Random) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3810 m
+gs 1 -1 sc (Numbers) col0 sh gr
+% Polyline
+n 6075 2805 m 5970 2805 5970 4050 105 arcto 4 {pop} repeat
+ 5970 4155 8115 4155 105 arcto 4 {pop} repeat
+ 8220 4155 8220 2910 105 arcto 4 {pop} repeat
+ 8220 2805 6075 2805 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1440 m
+gs 1 -1 sc (Symmetric) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+% Polyline
+n 3345 810 m 3240 810 3240 2055 105 arcto 4 {pop} repeat
+ 3240 2160 5385 2160 105 arcto 4 {pop} repeat
+ 5490 2160 5490 915 105 arcto 4 {pop} repeat
+ 5490 810 3345 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1440 m
+gs 1 -1 sc (Hashing) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1815 m
+gs 1 -1 sc (MACing) col0 sh gr
+% Polyline
+n 6090 810 m 5985 810 5985 2055 105 arcto 4 {pop} repeat
+ 5985 2160 8130 2160 105 arcto 4 {pop} repeat
+ 8235 2160 8235 915 105 arcto 4 {pop} repeat
+ 8235 810 6090 810 105 arcto 4 {pop} repeat
+ cp gs col0 s gr
+% Polyline
+n 3513 4563 m 3438 4563 3438 5438 75 arcto 4 {pop} repeat
+ 3438 5513 4947 5513 75 arcto 4 {pop} repeat
+ 5022 5513 5022 4638 75 arcto 4 {pop} repeat
+ 5022 4563 3513 4563 75 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 210.00 scf sf
+3825 5130 m
+gs 1 -1 sc (Memory) col0 sh gr
+% Polyline
+n 5583 4563 m 5508 4563 5508 5438 75 arcto 4 {pop} repeat
+ 5508 5513 7017 5513 75 arcto 4 {pop} repeat
+ 7092 5513 7092 4638 75 arcto 4 {pop} repeat
+ 7092 4563 5583 4563 75 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 210.00 scf sf
+5635 5133 m
+gs 1 -1 sc (Miscelleanous) col0 sh gr
+% Polyline
+n 1443 4567 m 1368 4567 1368 5442 75 arcto 4 {pop} repeat
+ 1368 5517 2877 5517 75 arcto 4 {pop} repeat
+ 2952 5517 2952 4642 75 arcto 4 {pop} repeat
+ 2952 4567 1443 4567 75 arcto 4 {pop} repeat
+ cp gs col0 s gr
+/Helvetica-iso ff 210.00 scf sf
+1495 5137 m
+gs 1 -1 sc (S-expressions) col0 sh gr
+% here ends figure;
+$F2psEnd
+rs
+showpage
--- /dev/null
+#FIG 3.2
+Landscape
+Center
+Metric
+A4
+100.00
+Single
+-2
+1200 2
+0 32 #8e8e8e
+0 33 #414541
+0 34 #c0c0c0
+0 35 #808080
+0 36 #636363
+0 37 #cdcdcd
+0 38 #6c6c6c
+0 39 #c6b797
+0 40 #eff8ff
+0 41 #dccba6
+0 42 #404040
+0 43 #e0e0e0
+0 44 #8e8f8e
+0 45 #aaaaaa
+0 46 #555555
+0 47 #d7d7d7
+0 48 #aeaeae
+0 49 #bebebe
+0 50 #515151
+0 51 #e7e3e7
+0 52 #000049
+0 53 #797979
+0 54 #303430
+0 55 #414141
+0 56 #c7b696
+0 57 #dd9d93
+0 58 #f1ece0
+0 59 #c3c3c3
+0 60 #e2c8a8
+0 61 #e1e1e1
+0 62 #d2d2d2
+0 63 #ededed
+0 64 #da7a1a
+0 65 #f1e41a
+0 66 #887dc2
+0 67 #d6d6d6
+0 68 #8c8ca5
+0 69 #4a4a4a
+0 70 #8c6b6b
+0 71 #5a5a5a
+0 72 #b79b73
+0 73 #4193ff
+0 74 #bf703b
+0 75 #db7700
+0 76 #dab800
+0 77 #006400
+0 78 #5a6b3b
+0 79 #d3d3d3
+0 80 #8e8ea4
+0 81 #f3b95d
+0 82 #89996b
+0 83 #646464
+0 84 #b7e6ff
+0 85 #86c0ec
+0 86 #bdbdbd
+0 87 #d39552
+0 88 #98d2fe
+0 89 #8c9c6b
+0 90 #f76b00
+0 91 #5a6b39
+0 92 #8c9c6b
+0 93 #8c9c7b
+0 94 #184a18
+0 95 #adadad
+0 96 #f7bd5a
+0 97 #636b9c
+0 98 #f7f7f7
+0 99 #de0000
+0 100 #adadad
+0 101 #f7bd5a
+0 102 #adadad
+0 103 #f7bd5a
+0 104 #636b9c
+0 105 #526b29
+0 106 #949494
+0 107 #006300
+0 108 #00634a
+0 109 #7b844a
+0 110 #e7bd7b
+0 111 #a5b5c6
+0 112 #6b6b94
+0 113 #846b6b
+0 114 #529c4a
+0 115 #d6e7e7
+0 116 #526363
+0 117 #186b4a
+0 118 #9ca5b5
+0 119 #ff9400
+0 120 #ff9400
+0 121 #00634a
+0 122 #7b844a
+0 123 #63737b
+0 124 #e7bd7b
+0 125 #dedede
+0 126 #f3eed3
+0 127 #f5ae5d
+0 128 #95ce99
+0 129 #b5157d
+0 130 #eeeeee
+0 131 #848484
+0 132 #7b7b7b
+0 133 #005a00
+0 134 #e77373
+0 135 #ffcb31
+0 136 #29794a
+0 137 #de2821
+0 138 #2159c6
+0 139 #f8f8f8
+0 140 #e6e6e6
+0 141 #21845a
+0 142 #c9c9c9
+0 143 #dfd8df
+0 144 #f7f3f7
+6 450 720 8325 5580
+6 450 720 8325 4275
+6 450 720 2880 2250
+6 900 1170 2340 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1410 900 1440 Public-Key\001
+4 0 0 50 -1 16 20 0.0000 4 300 1410 900 1815 Encryption\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2790 2160 2790 810 540 810 540 2160 2790 2160
+-6
+6 525 2775 2805 4155
+6 630 3150 2700 3870
+6 630 3150 2700 3870
+4 0 0 50 -1 16 20 0.0000 4 225 2055 630 3420 Multi-Precision-\001
+4 0 0 50 -1 16 20 0.0000 4 300 1095 900 3795 Integers\001
+-6
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2790 4140 2790 2790 540 2790 540 4140 2790 4140
+-6
+6 3150 2700 5580 4230
+6 3420 3150 5400 3870
+4 0 0 50 -1 16 20 0.0000 4 225 1965 3420 3420 Prime-Number\001
+4 0 0 50 -1 16 20 0.0000 4 225 1365 3420 3795 Generator\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5490 4140 5490 2790 3240 2790 3240 4140 5490 4140
+-6
+6 5880 2715 8310 4245
+6 6420 3165 7680 3885
+4 0 0 50 -1 16 20 0.0000 4 225 1140 6420 3435 Random\001
+4 0 0 50 -1 16 20 0.0000 4 225 1230 6420 3810 Numbers\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 8220 4155 8220 2805 5970 2805 5970 4155 8220 4155
+-6
+6 3150 720 5580 2250
+6 3600 1170 5040 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1425 3600 1440 Symmetric\001
+4 0 0 50 -1 16 20 0.0000 4 300 1410 3600 1815 Encryption\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5490 2160 5490 810 3240 810 3240 2160 5490 2160
+-6
+6 5940 765 8280 2205
+6 6435 1215 7530 1890
+4 0 0 50 -1 16 20 0.0000 4 300 1095 6435 1440 Hashing\001
+4 0 0 50 -1 16 20 0.0000 4 300 1065 6435 1815 MACing\001
+-6
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 8235 2160 8235 810 5985 810 5985 2160 8235 2160
+-6
+-6
+6 1305 4500 7155 5580
+6 3375 4500 5085 5580
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 5022 5513 5022 4563 3438 4563 3438 5513 5022 5513
+4 0 0 50 -1 16 14 0.0000 4 195 780 3825 5130 Memory\001
+-6
+6 5445 4500 7155 5576
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 7092 5513 7092 4563 5508 4563 5508 5513 7092 5513
+4 0 0 50 -1 16 14 0.0000 4 150 1350 5635 5133 Miscelleanous\001
+-6
+6 1305 4504 3015 5580
+2 4 0 2 0 7 50 -1 -1 0.000 0 0 5 0 0 5
+ 2952 5517 2952 4567 1368 4567 1368 5517 2952 5517
+4 0 0 50 -1 16 14 0.0000 4 195 1350 1495 5137 S-expressions\001
+-6
+-6
+-6
--- /dev/null
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2005-06-29.22
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004, 2005 Free Software
+# Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+ '')
+ echo "$0: No file. Try \`$0 --help' for more information." 1>&2
+ exit 1;
+ ;;
+ -h | --h*)
+ cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+ exit $?
+ ;;
+ -v | --v*)
+ echo "mdate-sh $scriptversion"
+ exit $?
+ ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# GNU ls changes its time format in response to the TIME_STYLE
+# variable. Since we cannot assume `unset' works, revert this
+# variable to its documented default.
+if test "${TIME_STYLE+set}" = set; then
+ TIME_STYLE=posix-long-iso
+ export TIME_STYLE
+fi
+
+save_arg1=$1
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ ls_command='ls -L -l -d'
+else
+ ls_command='ls -l -d'
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+# drwxrwx--- 0 Aug 11 2001 foo
+# This differs from Unix, which adds ownership information.
+# drwxrwx--- 2 root root 4096 Aug 11 2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month. This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc. However, it's unlikely that `/'
+# will be owned by a user whose name is a month. So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`ls -l -d /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+ shift
+ # Add another shift to the command.
+ command="$command shift;"
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+# Get the extended ls output of the file or directory.
+set dummy x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Because of the dummy argument above, month is in $2.
+#
+# On a POSIX system, we should have
+#
+# $# = 5
+# $1 = file size
+# $2 = month
+# $3 = day
+# $4 = year or time
+# $5 = filename
+#
+# On Darwin 7.7.0 and 7.6.0, we have
+#
+# $# = 4
+# $1 = day
+# $2 = month
+# $3 = year or time
+# $4 = filename
+
+# Get the month.
+case $2 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+esac
+
+case $3 in
+ ???*) day=$1;;
+ *) day=$3; shift;;
+esac
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+@set UPDATED 29 June 2011
+@set UPDATED-MONTH June 2011
+@set EDITION 1.5.0
+@set VERSION 1.5.0
--- /dev/null
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2006-10-04.17}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free
+% Software Foundation, Inc.
+%
+% This texinfo.tex file is free software; you can redistribute it and/or
+% modify it under the terms of the GNU General Public License as
+% published by the Free Software Foundation; either version 2, or (at
+% your option) any later version.
+%
+% This texinfo.tex file 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
+% General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with this texinfo.tex file; see the file COPYING. If not, write
+% to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+% Boston, MA 02110-1301, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction. (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+% http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+% ftp://tug.org/tex/texinfo.tex
+% (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org. Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem. Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution. For a simple
+% manual foo.texi, however, you can get away with this:
+% tex foo.texi
+% texindex foo.??
+% tex foo.texi
+% tex foo.texi
+% dvips foo.dvi -o # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent. You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+ \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Pre-3.0.
+\else
+ \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi
+
+% Since the category of space is not known, we have to be careful.
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode`\ =\spacecat}
+
+% sometimes characters are active, so we need control sequences.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dashChar = `\-
+\chardef\dotChar = `\.
+\chardef\exclamChar= `\!
+\chardef\lquoteChar= `\`
+\chardef\questChar = `\?
+\chardef\rquoteChar= `\'
+\chardef\semiChar = `\;
+\chardef\underChar = `\_
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+ Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+ ap-pen-dix bit-map bit-maps
+ data-base data-bases eshell fall-ing half-way long-est man-u-script
+ man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+ par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+ spell-ing spell-ings
+ stand-alone strong-est time-stamp time-stamps which-ever white-space
+ wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal. We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+ \tracingstats2
+ \tracingpages1
+ \tracinglostchars2 % 2 gives us more in etex
+ \tracingparagraphs1
+ \tracingoutput1
+ \tracingmacros2
+ \tracingrestores1
+ \showboxbreadth\maxdimen \showboxdepth\maxdimen
+ \ifx\eTeXversion\undefined\else % etex gives us more logging
+ \tracingscantokens1
+ \tracingifs1
+ \tracinggroups1
+ \tracingnesting2
+ \tracingassigns1
+ \fi
+ \tracingcommands3 % 3 gives us more in etex
+ \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions. If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+ \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+ \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+ \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+ \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+ %
+ \ifodd\pageno \advance\hoffset by \bindingoffset
+ \else \advance\hoffset by -\bindingoffset\fi
+ %
+ % Do this outside of the \shipout so @code etc. will be expanded in
+ % the headline as they should be, not taken literally (outputting ''code).
+ \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+ \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+ %
+ {%
+ % Have to do this stuff outside the \shipout because we want it to
+ % take effect in \write's, yet the group defined by the \vbox ends
+ % before the \shipout runs.
+ %
+ \indexdummies % don't expand commands in the output.
+ \normalturnoffactive % \ in index entries must not stay \, e.g., if
+ % the page break happens to be in the middle of an example.
+ % We don't want .vr (or whatever) entries like this:
+ % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
+ % "\acronym" won't work when it's read back in;
+ % it needs to be
+ % {\code {{\tt \backslashcurfont }acronym}
+ \shipout\vbox{%
+ % Do this early so pdf references go to the beginning of the page.
+ \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+ %
+ \ifcropmarks \vbox to \outervsize\bgroup
+ \hsize = \outerhsize
+ \vskip-\topandbottommargin
+ \vtop to0pt{%
+ \line{\ewtop\hfil\ewtop}%
+ \nointerlineskip
+ \line{%
+ \vbox{\moveleft\cornerthick\nstop}%
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}%
+ }%
+ \vss}%
+ \vskip\topandbottommargin
+ \line\bgroup
+ \hfil % center the page within the outer (page) hsize.
+ \ifodd\pageno\hskip\bindingoffset\fi
+ \vbox\bgroup
+ \fi
+ %
+ \unvbox\headlinebox
+ \pagebody{#1}%
+ \ifdim\ht\footlinebox > 0pt
+ % Only leave this space if the footline is nonempty.
+ % (We lessened \vsize for it in \oddfootingyyy.)
+ % The \baselineskip=24pt in plain's \makefootline has no effect.
+ \vskip 24pt
+ \unvbox\footlinebox
+ \fi
+ %
+ \ifcropmarks
+ \egroup % end of \vbox\bgroup
+ \hfil\egroup % end of (centering) \line\bgroup
+ \vskip\topandbottommargin plus1fill minus1fill
+ \boxmaxdepth = \cornerthick
+ \vbox to0pt{\vss
+ \line{%
+ \vbox{\moveleft\cornerthick\nsbot}%
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}%
+ }%
+ \nointerlineskip
+ \line{\ewbot\hfil\ewbot}%
+ }%
+ \egroup % \vbox from first cropmarks clause
+ \fi
+ }% end of \shipout\vbox
+ }% end of group with \indexdummies
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+ \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+ \def\argtorun{#2}%
+ \begingroup
+ \obeylines
+ \spaceisspace
+ #1%
+ \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ \argremovecomment #1\comment\ArgTerm%
+ }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+% @end itemize @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+ \def\temp{#3}%
+ \ifx\temp\empty
+ % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp:
+ \let\temp\finishparsearg
+ \else
+ \let\temp\argcheckspaces
+ \fi
+ % Put the space token in:
+ \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \argtorun.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}}
+
+% \parseargdef\foo{...}
+% is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick. --kasal, 16nov03
+
+\def\parseargdef#1{%
+ \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+ \def#2{\parsearg#1}%
+ \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+ \obeyspaces
+ \gdef\obeyedspace{ }
+
+ % Make each space character in the input produce a normal interword
+ % space in the output. Don't allow a line break at this space, as this
+ % is used only in environments like @example, where each line of input
+ % should produce a line of output anyway.
+ %
+ \gdef\sepspaces{\obeyspaces\let =\tie}
+
+ % If an index command is used in an @example environment, any spaces
+ % therein should become regular spaces in the raw index file, not the
+ % expansion of \tie (\leavevmode \penalty \@M \ ).
+ \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex. It's used like this:
+%
+% \envdef\foo{...}
+% \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo. \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches. The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group. (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+ \def\temp{#1}%
+ \ifx\thisenv\temp
+ \else
+ \badenverr
+ \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+ \errhelp = \EMsimple
+ \errmessage{This command can appear only \inenvironment\temp,
+ not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+ \ifx#1\empty
+ out of any environment%
+ \else
+ in environment \expandafter\string#1%
+ \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+ \if 1\csname iscond.#1\endcsname
+ \else
+ % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+ \expandafter\checkenv\csname#1\endcsname
+ \csname E#1\endcsname
+ \endgroup
+ \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+ % Definitions to produce \{ and \} commands for indices,
+ % and @{ and @} for the aux/toc files.
+ \catcode`\{ = \other \catcode`\} = \other
+ \catcode`\[ = 1 \catcode`\] = 2
+ \catcode`\! = 0 \catcode`\\ = \other
+ !gdef!lbracecmd[\{]%
+ !gdef!rbracecmd[\}]%
+ !gdef!lbraceatcmd[@{]%
+ !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+ \def\temp{#1}%
+ \ifx\temp\imacro \ptexi
+ \else\ifx\temp\jmacro \j
+ \else \errmessage{@dotless can be used only with i or j}%
+ \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence. (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo. Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+ L\kern-.36em
+ {\setbox0=\hbox{T}%
+ \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+ \kern-.15em
+ \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=\endofsentencespacefactor\space}
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=\endofsentencespacefactor\space}
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=\endofsentencespacefactor\space}
+
+% @frenchspacing on|off says whether to put extra space after punctuation.
+%
+\def\onword{on}
+\def\offword{off}
+%
+\parseargdef\frenchspacing{%
+ \def\temp{#1}%
+ \ifx\temp\onword \plainfrenchspacing
+ \else\ifx\temp\offword \plainnonfrenchspacing
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @frenchspacing option `\temp', must be on/off}%
+ \fi\fi
+}
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large. This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material. In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom. The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+ \ifnum\catcode`\^^M=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ \startsavinginserts
+ %
+ \setbox\groupbox = \vtop\bgroup
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it. Thus, space below is not quite equal to space
+% above. But it's pretty close.
+\def\Egroup{%
+ % To get correct interline space between the last line of the group
+ % and the first line afterwards, we have to propagate \prevdepth.
+ \endgraf % Not \par, as it may have been set to \lisppar.
+ \global\dimen1 = \prevdepth
+ \egroup % End the \vtop.
+ % \dimen0 is the vertical size of the group's box.
+ \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox
+ % \dimen2 is how much space is left on the page (more or less).
+ \dimen2 = \pageheight \advance\dimen2 by -\pagetotal
+ % if the group doesn't fit on the current page, and it's a big big
+ % group, force a page break.
+ \ifdim \dimen0 > \dimen2
+ \ifdim \pagetotal < \vfilllimit\pageheight
+ \page
+ \fi
+ \fi
+ \box\groupbox
+ \prevdepth = \dimen1
+ \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+ % Ensure vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % If the @need value is less than one line space, it's useless.
+ \dimen0 = #1\mil
+ \dimen2 = \ht\strutbox
+ \advance\dimen2 by \dp\strutbox
+ \ifdim\dimen0 > \dimen2
+ %
+ % Do a \strut just to make the height of this box be normal, so the
+ % normal leading is inserted relative to the preceding line.
+ % And a page break here is fine.
+ \vtop to #1\mil{\strut\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+ \fi
+}
+
+% @br forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+ \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph. For more general purposes, use the \margin insertion
+% class. WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+ \nobreak
+ \kern-\strutdepth
+ \vtop to \strutdepth{%
+ \baselineskip=\strutdepth
+ \vss
+ % if you have multiple lines of stuff to put here, you'll need to
+ % make the vbox yourself of the appropriate size.
+ \ifx#1l%
+ \llap{\ignorespaces #2\hskip\inmarginspacing}%
+ \else
+ \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+ \fi
+ \null
+ }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \def\lefttext{#1}% have both texts
+ \def\righttext{#2}%
+ \else
+ \def\lefttext{#1}% have only one text
+ \def\righttext{#1}%
+ \fi
+ %
+ \ifodd\pageno
+ \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+ \else
+ \def\temp{\inleftmargin\lefttext}%
+ \fi
+ \temp
+}
+
+% @include file insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+ \pushthisfilestack
+ \def\thisfile{#1}%
+ {%
+ \makevalueexpandable
+ \def\temp{\input #1 }%
+ \expandafter
+ }\temp
+ \popthisfilestack
+}
+\def\filenamecatcodes{%
+ \catcode`\\=\other
+ \catcode`~=\other
+ \catcode`^=\other
+ \catcode`_=\other
+ \catcode`|=\other
+ \catcode`<=\other
+ \catcode`>=\other
+ \catcode`+=\other
+ \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+ \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+ \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+ \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+ the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+ \ifhmode
+ \let\next\centerH
+ \else
+ \let\next\centerV
+ \fi
+ \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+ {%
+ \hfil\break
+ \advance\hsize by -\leftskip
+ \advance\hsize by -\rightskip
+ \line{#1}%
+ \break
+ }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \defaultparindent = 0pt
+ \else
+ \defaultparindent = #1em
+ \fi
+ \fi
+ \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+ \def\temp{#1}%
+ \ifx\temp\asisword
+ \else
+ \ifx\temp\noneword
+ \lispnarrowing = 0pt
+ \else
+ \lispnarrowing = #1em
+ \fi
+ \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading. If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+ \def\temp{#1}%
+ \ifx\temp\noneword
+ \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+ \else\ifx\temp\insertword
+ \let\suppressfirstparagraphindent = \relax
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @firstparagraphindent option `\temp'}%
+ \fi\fi
+}
+
+% Here is how we actually suppress indentation. Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+ \gdef\indent{%
+ \restorefirstparagraphindent
+ \indent
+ }%
+ \gdef\noindent{%
+ \restorefirstparagraphindent
+ \noindent
+ }%
+ \global\everypar = {%
+ \kern -\parindent
+ \restorefirstparagraphindent
+ }%
+}
+
+\gdef\restorefirstparagraphindent{%
+ \global \let \indent = \ptexindent
+ \global \let \noindent = \ptexnoindent
+ \global \everypar = {}%
+}
+
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}. So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+ \catcode`\_ = \active
+ \gdef\mathunderscore{%
+ \catcode`\_=\active
+ \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+ }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care. Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+ \tex
+ \mathunderscore
+ \let\\ = \mathbackslash
+ \mathactive
+ $\finishmath
+}
+\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+ \catcode`^ = \active
+ \catcode`< = \active
+ \catcode`> = \active
+ \catcode`+ = \active
+ \gdef\mathactive{%
+ \let^ = \ptexhat
+ \let< = \ptexless
+ \let> = \ptexgtr
+ \let+ = \ptexplus
+ }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in the cm
+% typewriter fonts as three actual period characters; on the other hand,
+% in other typewriter fonts three periods are wider than 1.5em. So do
+% whichever is larger.
+%
+\def\dots{%
+ \leavevmode
+ \setbox0=\hbox{...}% get width of three periods
+ \ifdim\wd0 > 1.5em
+ \dimen0 = \wd0
+ \else
+ \dimen0 = 1.5em
+ \fi
+ \hbox to \dimen0{%
+ \hskip 0pt plus.25fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus1fil
+ .\hskip 0pt plus.5fil
+ }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+ \dots
+ \spacefactor=\endofsentencespacefactor
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \iflinks
+ \tryauxfile
+ % Open the new aux file. TeX will close it automatically at exit.
+ \immediate\openout\auxfile=\jobname.aux
+ \fi % \openindices needs to do some work in any case.
+ \openindices
+ \let\setfilename=\comment % Ignore extra @setfilename cmds.
+ %
+ % If texinfo.cnf is present on the system, read it.
+ % Useful for site-wide @afourpaper, etc.
+ \openin 1 texinfo.cnf
+ \ifeof 1 \else \input texinfo.cnf \fi
+ \closein 1
+ %
+ \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set). So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+ \ifx\pdfoutput\relax
+ \else
+ \ifcase\pdfoutput
+ \else
+ \pdftrue
+ \fi
+ \fi
+\fi
+
+% PDF uses PostScript string constants for the names of xref targets,
+% for display in the outlines, and in other places. Thus, we have to
+% double any backslashes. Otherwise, a name like "\node" will be
+% interpreted as a newline (\n), followed by o, d, e. Not good.
+% http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html
+% (and related messages, the final outcome is that it is up to the TeX
+% user to double the backslashes and otherwise make the string valid, so
+% that's what we do).
+
+% double active backslashes.
+%
+{\catcode`\@=0 \catcode`\\=\active
+ @gdef@activebackslashdouble{%
+ @catcode`@\=@active
+ @let\=@doublebackslash}
+}
+
+% To handle parens, we must adopt a different approach, since parens are
+% not active characters. hyperref.dtx (which has the same problem as
+% us) handles it with this amazing macro to replace tokens. I've
+% tinkered with it a little for texinfo, but it's definitely from there.
+%
+% #1 is the tokens to replace.
+% #2 is the replacement.
+% #3 is the control sequence with the string.
+%
+\def\HyPsdSubst#1#2#3{%
+ \def\HyPsdReplace##1#1##2\END{%
+ ##1%
+ \ifx\\##2\\%
+ \else
+ #2%
+ \HyReturnAfterFi{%
+ \HyPsdReplace##2\END
+ }%
+ \fi
+ }%
+ \xdef#3{\expandafter\HyPsdReplace#3#1\END}%
+}
+\long\def\HyReturnAfterFi#1\fi{\fi#1}
+
+% #1 is a control sequence in which to do the replacements.
+\def\backslashparens#1{%
+ \xdef#1{#1}% redefine it as its expansion; the definition is simply
+ % \lastnode when called from \setref -> \pdfmkdest.
+ \HyPsdSubst{(}{\realbackslash(}{#1}%
+ \HyPsdSubst{)}{\realbackslash)}{#1}%
+}
+
+\ifpdf
+ \input pdfcolor
+ \pdfcatalog{/PageMode /UseOutlines}%
+ % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto).
+ \def\dopdfimage#1#2#3{%
+ \def\imagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}%
+ \def\imageheight{#3}\setbox2 = \hbox{\ignorespaces #3}%
+ % without \immediate, pdftex seg faults when the same image is
+ % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.)
+ \ifnum\pdftexversion < 14
+ \immediate\pdfimage
+ \else
+ \immediate\pdfximage
+ \fi
+ \ifdim \wd0 >0pt width \imagewidth \fi
+ \ifdim \wd2 >0pt height \imageheight \fi
+ \ifnum\pdftexversion<13
+ #1.pdf%
+ \else
+ {#1.pdf}%
+ \fi
+ \ifnum\pdftexversion < 14 \else
+ \pdfrefximage \pdflastximage
+ \fi}
+ \def\pdfmkdest#1{{%
+ % We have to set dummies so commands such as @code, and characters
+ % such as \, aren't expanded when present in a section title.
+ \atdummies
+ \activebackslashdouble
+ \def\pdfdestname{#1}%
+ \backslashparens\pdfdestname
+ \pdfdest name{\pdfdestname} xyz%
+ }}%
+ %
+ % used to mark target names; must be expandable.
+ \def\pdfmkpgn#1{#1}%
+ %
+ \let\linkcolor = \Blue % was Cyan, but that seems light?
+ \def\endlink{\Black\pdfendlink}
+ % Adding outlines to PDF; macros for calculating structure of outlines
+ % come from Petr Olsak
+ \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi}
+ \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+ \advance\tempnum by 1
+ \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+ %
+ % #1 is the section text, which is what will be displayed in the
+ % outline by the pdf viewer. #2 is the pdf expression for the number
+ % of subentries (or empty, for subsubsections). #3 is the node text,
+ % which might be empty if this toc entry had no corresponding node.
+ % #4 is the page number
+ %
+ \def\dopdfoutline#1#2#3#4{%
+ % Generate a link to the node text if that exists; else, use the
+ % page number. We could generate a destination for the section
+ % text in the case where a section has no node, but it doesn't
+ % seem worth the trouble, since most documents are normally structured.
+ \def\pdfoutlinedest{#3}%
+ \ifx\pdfoutlinedest\empty
+ \def\pdfoutlinedest{#4}%
+ \else
+ % Doubled backslashes in the name.
+ {\activebackslashdouble \xdef\pdfoutlinedest{#3}%
+ \backslashparens\pdfoutlinedest}%
+ \fi
+ %
+ % Also double the backslashes in the display string.
+ {\activebackslashdouble \xdef\pdfoutlinetext{#1}%
+ \backslashparens\pdfoutlinetext}%
+ %
+ \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{\pdfoutlinetext}%
+ }
+ %
+ \def\pdfmakeoutlines{%
+ \begingroup
+ % Thanh's hack / proper braces in bookmarks
+ \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+ \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+ %
+ % Read toc silently, to get counts of subentries for \pdfoutline.
+ \def\numchapentry##1##2##3##4{%
+ \def\thischapnum{##2}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsecentry##1##2##3##4{%
+ \advancenumber{chap\thischapnum}%
+ \def\thissecnum{##2}%
+ \def\thissubsecnum{0}%
+ }%
+ \def\numsubsecentry##1##2##3##4{%
+ \advancenumber{sec\thissecnum}%
+ \def\thissubsecnum{##2}%
+ }%
+ \def\numsubsubsecentry##1##2##3##4{%
+ \advancenumber{subsec\thissubsecnum}%
+ }%
+ \def\thischapnum{0}%
+ \def\thissecnum{0}%
+ \def\thissubsecnum{0}%
+ %
+ % use \def rather than \let here because we redefine \chapentry et
+ % al. a second time, below.
+ \def\appentry{\numchapentry}%
+ \def\appsecentry{\numsecentry}%
+ \def\appsubsecentry{\numsubsecentry}%
+ \def\appsubsubsecentry{\numsubsubsecentry}%
+ \def\unnchapentry{\numchapentry}%
+ \def\unnsecentry{\numsecentry}%
+ \def\unnsubsecentry{\numsubsecentry}%
+ \def\unnsubsubsecentry{\numsubsubsecentry}%
+ \readdatafile{toc}%
+ %
+ % Read toc second time, this time actually producing the outlines.
+ % The `-' means take the \expnumber as the absolute number of
+ % subentries, which we calculated on our first read of the .toc above.
+ %
+ % We use the node names as the destinations.
+ \def\numchapentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+ \def\numsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+ \def\numsubsecentry##1##2##3##4{%
+ \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+ \def\numsubsubsecentry##1##2##3##4{% count is always zero
+ \dopdfoutline{##1}{}{##3}{##4}}%
+ %
+ % PDF outlines are displayed using system fonts, instead of
+ % document fonts. Therefore we cannot use special characters,
+ % since the encoding is unknown. For example, the eogonek from
+ % Latin 2 (0xea) gets translated to a | character. Info from
+ % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+ %
+ % xx to do this right, we have to translate 8-bit characters to
+ % their "best" equivalent, based on the @documentencoding. Right
+ % now, I guess we'll just let the pdf reader have its way.
+ \indexnofonts
+ \setupdatafile
+ \catcode`\\=\active \otherbackslash
+ \input \jobname.toc
+ \endgroup
+ }
+ %
+ \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+ \ifx\PP\D\let\nextsp\relax
+ \else\let\nextsp\skipspaces
+ \ifx\p\space\else\addtokens{\filename}{\PP}%
+ \advance\filenamelength by 1
+ \fi
+ \fi
+ \nextsp}
+ \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+ \ifnum\pdftexversion < 14
+ \let \startlink \pdfannotlink
+ \else
+ \let \startlink \pdfstartlink
+ \fi
+ % make a live url in pdf output.
+ \def\pdfurl#1{%
+ \begingroup
+ % it seems we really need yet another set of dummies; have not
+ % tried to figure out what each command should do in the context
+ % of @url. for now, just make @/ a no-op, that's the only one
+ % people have actually reported a problem with.
+ %
+ \normalturnoffactive
+ \def\@{@}%
+ \let\/=\empty
+ \makevalueexpandable
+ \leavevmode\Red
+ \startlink attr{/Border [0 0 0]}%
+ user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+ \endgroup}
+ \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+ \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+ \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+ \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+ \def\maketoks{%
+ \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+ \ifx\first0\adn0
+ \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+ \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+ \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+ \else
+ \ifnum0=\countA\else\makelink\fi
+ \ifx\first.\let\next=\done\else
+ \let\next=\maketoks
+ \addtokens{\toksB}{\the\toksD}
+ \ifx\first,\addtokens{\toksB}{\space}\fi
+ \fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next}
+ \def\makelink{\addtokens{\toksB}%
+ {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+ \def\pdflink#1{%
+ \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+ \linkcolor #1\endlink}
+ \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+ \let\pdfmkdest = \gobble
+ \let\pdfurl = \gobble
+ \let\endlink = \relax
+ \let\linkcolor = \relax
+ \let\pdfmakeoutlines = \relax
+\fi % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+ \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+ \csname ten#1\endcsname % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+
+% Default leading.
+\newdimen\textleading \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx} %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Definitions for a main text size of 11pt. This is the default in
+% Texinfo.
+%
+\def\definetextfontsizexi{
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 11pt text font size definitions
+
+
+% Definitions to make the main text be 10pt Computer Modern, with
+% section, chapter, etc., sizes following suit. This is for the GNU
+% Press printing of the Emacs 22 manual. Maybe other manuals in the
+% future. Used with @smallbook, which sets the leading to 12pt.
+%
+\def\definetextfontsizex{%
+% Text fonts (10pt).
+\def\textnominalsize{10pt}
+\edef\mainmagstep{1000}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstephalf}
+\setfont\deftt\ttshape{10}{\magstephalf}
+\setfont\defttsl\ttslshape{10}{\magstephalf}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter fonts (14.4pt).
+\def\chapnominalsize{14pt}
+\setfont\chaprm\rmbshape{12}{\magstep1}
+\setfont\chapit\itbshape{10}{\magstep2}
+\setfont\chapsl\slbshape{10}{\magstep2}
+\setfont\chaptt\ttbshape{12}{\magstep1}
+\setfont\chapttsl\ttslshape{10}{\magstep2}
+\setfont\chapsf\sfbshape{12}{\magstep1}
+\let\chapbf\chaprm
+\setfont\chapsc\scbshape{10}{\magstep2}
+\font\chapi=cmmi12 scaled \magstep1
+\font\chapsy=cmsy10 scaled \magstep2
+
+% Section fonts (12pt).
+\def\secnominalsize{12pt}
+\setfont\secrm\rmbshape{12}{1000}
+\setfont\secit\itbshape{10}{\magstep1}
+\setfont\secsl\slbshape{10}{\magstep1}
+\setfont\sectt\ttbshape{12}{1000}
+\setfont\secttsl\ttslshape{10}{\magstep1}
+\setfont\secsf\sfbshape{12}{1000}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep1}
+\font\seci=cmmi12
+\font\secsy=cmsy10 scaled \magstep1
+
+% Subsection fonts (10pt).
+\def\ssecnominalsize{10pt}
+\setfont\ssecrm\rmbshape{10}{1000}
+\setfont\ssecit\itbshape{10}{1000}
+\setfont\ssecsl\slbshape{10}{1000}
+\setfont\ssectt\ttbshape{10}{1000}
+\setfont\ssecttsl\ttslshape{10}{1000}
+\setfont\ssecsf\sfbshape{10}{1000}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1000}
+\font\sseci=cmmi10
+\font\ssecsy=cmsy10
+
+% Reduced fonts for @acro in text (9pt).
+\def\reducednominalsize{9pt}
+\setfont\reducedrm\rmshape{9}{1000}
+\setfont\reducedtt\ttshape{9}{1000}
+\setfont\reducedbf\bfshape{10}{900}
+\setfont\reducedit\itshape{9}{1000}
+\setfont\reducedsl\slshape{9}{1000}
+\setfont\reducedsf\sfshape{9}{1000}
+\setfont\reducedsc\scshape{10}{900}
+\setfont\reducedttsl\ttslshape{10}{900}
+\font\reducedi=cmmi9
+\font\reducedsy=cmsy9
+
+% reduce space between paragraphs
+\divide\parskip by 2
+
+% reset the current fonts
+\textfonts
+\rm
+} % end of 10pt text font size definitions
+
+
+% We provide the user-level command
+% @fonttextsize 10
+% (or 11) to redefine the text font size. pt is assumed.
+%
+\def\xword{10}
+\def\xiword{11}
+%
+\parseargdef\fonttextsize{%
+ \def\textsizearg{#1}%
+ \wlog{doing @fonttextsize \textsizearg}%
+ %
+ % Set \globaldefs so that documents can use this inside @tex, since
+ % makeinfo 4.8 does not support it, but we need it nonetheless.
+ %
+ \begingroup \globaldefs=1
+ \ifx\textsizearg\xword \definetextfontsizex
+ \else \ifx\textsizearg\xiword \definetextfontsizexi
+ \else
+ \errhelp=\EMsimple
+ \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'}
+ \fi\fi
+ \endgroup
+}
+
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+ \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+ \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this because \STYLE needs to also set the
+% current \fam for math mode. Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower). These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \let\tenttsl=\textttsl
+ \def\curfontsize{text}%
+ \def\lsize{reduced}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+ \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+ \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+ \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+ \let\tenttsl=\titlettsl
+ \def\curfontsize{title}%
+ \def\lsize{chap}\def\lllsize{subsec}%
+ \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \let\tenttsl=\chapttsl
+ \def\curfontsize{chap}%
+ \def\lsize{sec}\def\lllsize{text}%
+ \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \let\tenttsl=\secttsl
+ \def\curfontsize{sec}%
+ \def\lsize{subsec}\def\lllsize{reduced}%
+ \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \let\tenttsl=\ssecttsl
+ \def\curfontsize{ssec}%
+ \def\lsize{text}\def\lllsize{small}%
+ \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+ \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+ \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+ \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+ \let\tenttsl=\reducedttsl
+ \def\curfontsize{reduced}%
+ \def\lsize{small}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+ \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+ \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+ \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+ \let\tenttsl=\smallttsl
+ \def\curfontsize{small}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+ \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+ \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+ \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+ \let\tenttsl=\smallerttsl
+ \def\curfontsize{smaller}%
+ \def\lsize{smaller}\def\lllsize{smaller}%
+ \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+% 8.5x11=86 smallbook=72 a4=90 a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+% 8.5x11=90+ smallbook=80 a4=90+ a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt. So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+% 8.5x11=71 smallbook=60 a4=75 a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\definetextfontsizexi
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1} % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+ \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl. We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+ \def\plainfrenchspacing{%
+ \sfcode\dotChar =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+ \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+ \def\endofsentencespacefactor{1000}% for @. and friends
+ }
+ \def\plainnonfrenchspacing{%
+ \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000
+ \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250
+ \def\endofsentencespacefactor{3000}% for @. and friends
+ }
+\catcode`@=\other
+\def\endofsentencespacefactor{3000}% default
+
+\def\t#1{%
+ {\tt \rawbackslash \plainfrenchspacing #1}%
+ \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+ \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+ \vbox{\hrule\kern-0.4pt
+ \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+ \kern-0.4pt\hrule}%
+ \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \plainfrenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+% -- rms.
+{
+ \catcode`\-=\active \catcode`\_=\active
+ \catcode`\'=\active \catcode`\`=\active
+ %
+ \global\def\code{\begingroup
+ \catcode\rquoteChar=\active \catcode\lquoteChar=\active
+ \let'\codequoteright \let`\codequoteleft
+ %
+ \catcode\dashChar=\active \catcode\underChar=\active
+ \ifallowcodebreaks
+ \let-\codedash
+ \let_\codeunder
+ \else
+ \let-\realdash
+ \let_\realunder
+ \fi
+ \codex
+ }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+ % this is all so @math{@code{var_name}+1} can work. In math mode, _
+ % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+ % will therefore expand the active definition of _, which is us
+ % (inside @code that is), therefore an endless loop.
+ \ifusingtt{\ifmmode
+ \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+ \else\normalunderscore \fi
+ \discretionary{}{}{}}%
+ {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% An additional complication: the above will allow breaks after, e.g.,
+% each of the four underscores in __typeof__. This is undesirable in
+% some manuals, especially if they don't have long identifiers in
+% general. @allowcodebreaks provides a way to control this.
+%
+\newif\ifallowcodebreaks \allowcodebreakstrue
+
+\def\keywordtrue{true}
+\def\keywordfalse{false}
+
+\parseargdef\allowcodebreaks{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\keywordtrue
+ \allowcodebreakstrue
+ \else\ifx\txiarg\keywordfalse
+ \allowcodebreaksfalse
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @allowcodebreaks option `\txiarg'}%
+ \fi\fi
+}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+% `example' (@kbd uses ttsl only inside of @example and friends),
+% or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+ \def\txiarg{#1}%
+ \ifx\txiarg\worddistinct
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+ \else\ifx\txiarg\wordexample
+ \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+ \else\ifx\txiarg\wordcode
+ \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+ \else
+ \errhelp = \EMsimple
+ \errmessage{Unknown @kbdinputstyle option `\txiarg'}%
+ \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself. First (mandatory) arg is the url. Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+ \unsepspaces
+ \pdfurl{#1}%
+ \setbox0 = \hbox{\ignorespaces #3}%
+ \ifdim\wd0 > 0pt
+ \unhbox0 % third arg given, show only that
+ \else
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0 > 0pt
+ \ifpdf
+ \unhbox0 % PDF: 2nd arg given, show only it
+ \else
+ \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+ \fi
+ \else
+ \code{#1}% only url given, so show it
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+ \def\email#1{\doemail#1,,\finish}
+ \def\doemail#1,#2,#3\finish{\begingroup
+ \unsepspaces
+ \pdfurl{mailto:#1}%
+ \setbox0 = \hbox{\ignorespaces #2}%
+ \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+ \endlink
+ \endgroup}
+\else
+ \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font. Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find. We need it for
+% Polish suppressed-l. --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}} % roman font
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+%
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+ {\selectfonts\lsize #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+%
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+ {\plainfrenchspacing #1}%
+ \def\temp{#2}%
+ \ifx\temp\empty \else
+ \space ({\unsepspaces \ignorespaces \temp \unskip})%
+ \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+%
+% Although only regular is the truly official Euro symbol, we ignore
+% that. The Euro is designed to be slightly taller than the regular
+% font height.
+%
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+%
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+%
+% Also doesn't work in math. Do we need to do math with euro symbols?
+% Hope not.
+%
+%
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+ % We set the font at each command, rather than predefining it in
+ % \textfonts and the other font-switching commands, so that
+ % installations which never need the symbol don't have to have the
+ % font installed.
+ %
+ % There is only one designed size (nominal 10pt), so we always scale
+ % that to the current nominal size.
+ %
+ % By the way, simply using "at 1em" works for cmr10 and the like, but
+ % does not work for cmbx10 and other extended/shrunken fonts.
+ %
+ \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+ %
+ \ifx\curfontstyle\bfstylename
+ % bold:
+ \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+ \else
+ % regular:
+ \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+ \fi
+ \thiseurofont
+}
+
+% @registeredsymbol - R in a circle. The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+ $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+ \hfil\crcr\Orb}}%
+ }$%
+}
+
+% @textdegree - the normal degrees sign.
+%
+\def\textdegree{$^\circ$}
+
+% Laurent Siebenmann reports \Orb undefined with:
+% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38
+% so we'll define it if necessary.
+%
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+ % Open one extra group, as we want to close it in the middle of \Etitlepage.
+ \begingroup
+ \parindent=0pt \textfonts
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \let\page = \oldpage
+ \page
+ \null
+ }%
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ %
+ % Need this before the \...aftertitlepage checks so that if they are
+ % in effect the toc pages will come out with page numbers.
+ \HEADINGSon
+ %
+ % If they want short, they certainly want long too.
+ \ifsetshortcontentsaftertitlepage
+ \shortcontents
+ \contents
+ \global\let\shortcontents = \relax
+ \global\let\contents = \relax
+ \fi
+ %
+ \ifsetcontentsaftertitlepage
+ \contents
+ \global\let\contents = \relax
+ \global\let\shortcontents = \relax
+ \fi
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+ \let\tt=\authortt}
+
+\parseargdef\title{%
+ \checkenv\titlepage
+ \leftline{\titlefonts\rm #1}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+ \checkenv\titlepage
+ {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+ \def\temp{\quotation}%
+ \ifx\thisenv\temp
+ \def\quotationauthor{#1}% printed in \Equotation.
+ \else
+ \checkenv\titlepage
+ \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+ {\authorfont \leftline{#1}}%
+ \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline % headline on even pages
+\newtoks\oddheadline % headline on odd pages
+\newtoks\evenfootline % footline on even pages
+\newtoks\oddfootline % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+ \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+ %
+ % Leave some space for the footline. Hopefully ok to assume
+ % @evenfooting will not be used by itself.
+ \global\advance\pageheight by -12pt
+ \global\advance\vsize by -12pt
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+ \number\day\space
+ \ifcase\month
+ \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+ \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+ \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+ \fi
+ \space\number\year}
+\fi
+
+% @settitle line... specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemindicate{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. However, if
+ % what follows is an environment such as @example, there will be no
+ % \parskip glue; then the negative vskip we just inserted would
+ % cause the example and the item to crash together. So we use this
+ % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+ % \parskip glue after all. Section titles are handled this way also.
+ %
+ \penalty 10001
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line.
+ \noindent
+ % Do this with kerns and \unhbox so that if there is a footnote in
+ % the item text, it can migrate to the main vertical list and
+ % eventually be printed.
+ \nobreak\kern-\tableindent
+ \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+ \unhbox0
+ \nobreak\kern\dimen0
+ \endgroup
+ \itemxneedsnegativevskiptrue
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+ \let\itemindex\gobble
+ \tablecheck{table}%
+}
+\envdef\ftable{%
+ \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+ \tablecheck{ftable}%
+}
+\envdef\vtable{%
+ \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+ \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+ \ifnum \the\catcode`\^^M=\active
+ \endgroup
+ \errmessage{This command won't work in this context; perhaps the problem is
+ that we are \inenvironment\thisenv}%
+ \def\next{\doignore{#1}}%
+ \else
+ \let\next\tablex
+ \fi
+ \next
+}
+\def\tablex#1{%
+ \def\itemindicate{#1}%
+ \parsearg\tabley
+}
+\def\tabley#1{%
+ {%
+ \makevalueexpandable
+ \edef\temp{\noexpand\tablez #1\space\space\space}%
+ \expandafter
+ }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+ \aboveenvbreak
+ \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+ \ifnum 0#2>0 \tableindent=#2\mil \fi
+ \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+ \itemmax=\tableindent
+ \advance \itemmax by -\itemmargin
+ \advance \leftskip by \tableindent
+ \exdentamount=\tableindent
+ \parindent = 0pt
+ \parskip = \smallskipamount
+ \ifdim \parskip=0pt \parskip=2pt \fi
+ \let\item = \internalBitem
+ \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+ \aboveenvbreak
+ \itemmax=\itemindent
+ \advance\itemmax by -\itemmargin
+ \advance\leftskip by \itemindent
+ \exdentamount=\itemindent
+ \parindent=0pt
+ \parskip=\smallskipamount
+ \ifdim\parskip=0pt \parskip=2pt \fi
+ \def\itemcontents{#1}%
+ % @itemize with no arg is equivalent to @itemize @bullet.
+ \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+ \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+ \advance\itemno by 1 % for enumerations
+ {\let\par=\endgraf \smallbreak}% reasonable place to break
+ {%
+ % If the document has an @itemize directly after a section title, a
+ % \nobreak will be last on the list, and \sectionheading will have
+ % done a \vskip-\parskip. In that case, we don't want to zero
+ % parskip, or the item text will crash with the heading. On the
+ % other hand, when there is normal text preceding the item (as there
+ % usually is), we do want to zero parskip, or there would be too much
+ % space. In that case, we won't have a \nobreak before. At least
+ % that's the theory.
+ \ifnum\lastpenalty<10000 \parskip=0in \fi
+ \noindent
+ \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+ \vadjust{\penalty 1200}}% not good to break after first line of item.
+ \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @columnfractions .25 .3 .45
+% @item ...
+%
+% Numbers following @columnfractions are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+% to baseline.
+% 0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1. We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+ \global\advance\colcount by 1
+ \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+ \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+ \def\firstarg{#1}%
+ \ifx\firstarg\xendsetuptable
+ \let\go = \relax
+ \else
+ \ifx\firstarg\xcolumnfractions
+ \global\setpercenttrue
+ \else
+ \ifsetpercent
+ \let\go\pickupwholefraction
+ \else
+ \global\advance\colcount by 1
+ \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+ % separator; typically that is always in the input, anyway.
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi
+ \fi
+ \ifx\go\pickupwholefraction
+ % Put the argument back for the \pickupwholefraction call, so
+ % we'll always have a period there to be parsed.
+ \def\go{\pickupwholefraction#1}%
+ \else
+ \let\go = \setuptable
+ \fi%
+ \fi
+ \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry. Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp. But then the space in a template
+% line is not enough. That is bad. So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+% --karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab % insert after every tab.
+%
+\envdef\multitable{%
+ \vskip\parskip
+ \startsavinginserts
+ %
+ % @item within a multitable starts a normal row.
+ % We use \def instead of \let so that if one of the multitable entries
+ % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+ % \endtemplate) expanding \doitemize.
+ \def\item{\crcr}%
+ %
+ \tolerance=9500
+ \hbadness=9500
+ \setmultitablespacing
+ \parskip=\multitableparskip
+ \parindent=\multitableparindent
+ \overfullrule=0pt
+ \global\colcount=0
+ %
+ \everycr = {%
+ \noalign{%
+ \global\everytab={}%
+ \global\colcount=0 % Reset the column counter.
+ % Check for saved footnotes, etc.
+ \checkinserts
+ % Keeps underfull box messages off when table breaks over pages.
+ %\filbreak
+ % Maybe so, but it also creates really weird page breaks when the
+ % table breaks over pages. Wouldn't \vfil be better? Wait until the
+ % problem manifests itself, so it can be fixed for real --karl.
+ }%
+ }%
+ %
+ \parsearg\domultitable
+}
+\def\domultitable#1{%
+ % To parse everything between @multitable and @item:
+ \setuptable#1 \endsetuptable
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+ \halign\bgroup &%
+ \global\advance\colcount by 1
+ \multistrut
+ \vtop{%
+ % Use the current \colcount to find the correct column width:
+ \hsize=\expandafter\csname col\the\colcount\endcsname
+ %
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \multitablecolspace to all columns after
+ % the first one.
+ %
+ % If a template has been used, we will add \multitablecolspace
+ % to the width of each template entry.
+ %
+ % If the user has set preamble in terms of percent of \hsize we will
+ % use that dimension as the width of the column, and the \leftskip
+ % will keep entries from bumping into each other. Table will start at
+ % left margin and final column will justify at right margin.
+ %
+ % Make sure we don't inherit \rightskip from the outer environment.
+ \rightskip=0pt
+ \ifnum\colcount=1
+ % The first column will be indented with the surrounding text.
+ \advance\hsize by\leftskip
+ \else
+ \ifsetpercent \else
+ % If user has not set preamble in terms of percent of \hsize
+ % we will advance \hsize by \multitablecolspace.
+ \advance\hsize by \multitablecolspace
+ \fi
+ % In either case we will make \leftskip=\multitablecolspace:
+ \leftskip=\multitablecolspace
+ \fi
+ % Ignoring space at the beginning and end avoids an occasional spurious
+ % blank line, when TeX decides to break the line at the space before the
+ % box from the multistrut, so the strut ends up on a line by itself.
+ % For example:
+ % @multitable @columnfractions .11 .89
+ % @item @code{#}
+ % @tab Legal holiday which is valid in major parts of the whole country.
+ % Is automatically provided with highlighting sequences respectively
+ % marking characters.
+ \noindent\ignorespaces##\unskip\multistrut
+ }\cr
+}
+\def\Emultitable{%
+ \crcr
+ \egroup % end the \halign
+ \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+ \def\multistrut{\strut}% just use the standard line spacing
+ %
+ % Compute \multitablelinespace (if not defined by user) for use in
+ % \multitableparskip calculation. We used define \multistrut based on
+ % this, but (ironically) that caused the spacing to be off.
+ % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%% If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+ %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed. They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested. But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+ \expandafter\let\csname #1\endcsname = \relax
+ \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+ % Scan in ``verbatim'' mode:
+ \obeylines
+ \catcode`\@ = \other
+ \catcode`\{ = \other
+ \catcode`\} = \other
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \spaceisspace
+ %
+ % Count number of #1's that we've seen.
+ \doignorecount = 0
+ %
+ % Swallow text until we reach the matching `@end #1'.
+ \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+ \obeylines %
+ %
+ \gdef\dodoignore#1{%
+ % #1 contains the command name as a string, e.g., `ifinfo'.
+ %
+ % Define a command to find the next `@end #1'.
+ \long\def\doignoretext##1^^M@end #1{%
+ \doignoretextyyy##1^^M@#1\_STOP_}%
+ %
+ % And this command to find another #1 command, at the beginning of a
+ % line. (Otherwise, we would consider a line `@c @ifset', for
+ % example, to count as an @ifset for nesting.)
+ \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+ %
+ % And now expand that command.
+ \doignoretext ^^M%
+ }%
+}
+
+\def\doignoreyyy#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty % Nothing found.
+ \let\next\doignoretextzzz
+ \else % Found a nested condition, ...
+ \advance\doignorecount by 1
+ \let\next\doignoretextyyy % ..., look for another.
+ % If we're here, #1 ends with ^^M\ifinfo (for example).
+ \fi
+ \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+ \ifnum\doignorecount = 0 % We have just found the outermost @end.
+ \let\next\enddoignore
+ \else % Still inside a nested condition.
+ \advance\doignorecount by -1
+ \let\next\doignoretext % Look for the next @end.
+ \fi
+ \next
+}
+
+% Finish off ignored text.
+{ \obeylines%
+ % Ignore anything after the last `@end #1'; this matters in verbatim
+ % environments, where otherwise the newline after an ignored conditional
+ % would result in a blank line in the output.
+ \gdef\enddoignore#1^^M{\endgroup\ignorespaces}%
+}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ {%
+ \makevalueexpandable
+ \def\temp{#2}%
+ \edef\next{\gdef\makecsname{SET#1}}%
+ \ifx\temp\empty
+ \next{}%
+ \else
+ \setzzz#2\endsetzzz
+ \fi
+ }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+ {%
+ \makevalueexpandable
+ \global\expandafter\let\csname SET#1\endcsname=\relax
+ }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+ \catcode`\- = \active \catcode`\_ = \active
+ %
+ \gdef\makevalueexpandable{%
+ \let\value = \expandablevalue
+ % We don't want these characters active, ...
+ \catcode`\-=\other \catcode`\_=\other
+ % ..., but we might end up with active ones in the argument if
+ % we're called from @code, as @code{@value{foo-bar_}}, though.
+ % So \let them to their normal equivalents.
+ \let-\realdash \let_\normalunderscore
+ }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file. This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ {[No value for ``#1'']}%
+ \message{Variable `#1', used in @value, is not set.}%
+ \else
+ \csname SET#1\endcsname
+ \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+ {%
+ \makevalueexpandable
+ \let\next=\empty
+ \expandafter\ifx\csname SET#2\endcsname\relax
+ #1% If not set, redefine \next.
+ \fi
+ \expandafter
+ }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY -- specify a category of the dir file
+% which this file should belong to. Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{% % Define @#1index
+ \noexpand\doindex{#1}}
+}
+
+% @defindex foo == \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+ \iflinks
+ \expandafter\newwrite \csname#1indfile\endcsname
+ \openout \csname#1indfile\endcsname \jobname.#1
+ \fi
+ \expandafter\xdef\csname#1index\endcsname{%
+ \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+ % Only do \closeout if we haven't already done it, else we'll end up
+ % closing the target index.
+ \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+ % The \closeout helps reduce unnecessary open files; the limit on the
+ % Acorn RISC OS is a mere 16 files.
+ \expandafter\closeout\csname#2indfile\endcsname
+ \expandafter\let\csname\donesynindex#2\endcsname = 1
+ \fi
+ % redefine \fooindfile:
+ \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+ \expandafter\let\csname#2indfile\endcsname=\temp
+ % redefine \fooindex:
+ \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+ \escapechar = `\\ % use backslash in output files.
+ \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+ \def\ {\realbackslash\space }%
+ %
+ % Need these in case \tex is in effect and \{ is a \delimiter again.
+ % But can't use \lbracecmd and \rbracecmd because texindex assumes
+ % braces and backslashes are used only as delimiters.
+ \let\{ = \mylbrace
+ \let\} = \myrbrace
+ %
+ % I don't entirely understand this, but when an index entry is
+ % generated from a macro call, the \endinput which \scanmacro inserts
+ % causes processing to be prematurely terminated. This is,
+ % apparently, because \indexsorttmp is fully expanded, and \endinput
+ % is an expandable command. The redefinition below makes \endinput
+ % disappear altogether for that purpose -- although logging shows that
+ % processing continues to some further point. On the other hand, it
+ % seems \endinput does not hurt in the printed index arg, since that
+ % is still getting written without apparent harm.
+ %
+ % Sample source (mac-idx3.tex, reported by Graham Percival to
+ % help-texinfo, 22may06):
+ % @macro funindex {WORD}
+ % @findex xyz
+ % @end macro
+ % ...
+ % @funindex commtest
+ %
+ % The above is not enough to reproduce the bug, but it gives the flavor.
+ %
+ % Sample whatsit resulting:
+ % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
+ %
+ % So:
+ \let\endinput = \empty
+ %
+ % Do the redefinitions.
+ \commondummies
+}
+
+% For the aux and toc files, @ is the escape character. So we want to
+% redefine everything using @ as the escape character (instead of
+% \realbackslash, still used for index files). When everything uses @,
+% this will be simpler.
+%
+\def\atdummies{%
+ \def\@{@@}%
+ \def\ {@ }%
+ \let\{ = \lbraceatcmd
+ \let\} = \rbraceatcmd
+ %
+ % Do the redefinitions.
+ \commondummies
+ \otherbackslash
+}
+
+% Called from \indexdummies and \atdummies.
+%
+\def\commondummies{%
+ %
+ % \definedummyword defines \#1 as \string\#1\space, thus effectively
+ % preventing its expansion. This is used only for control% words,
+ % not control letters, because the \space would be incorrect for
+ % control characters, but is needed to separate the control word
+ % from whatever follows.
+ %
+ % For control letters, we have \definedummyletter, which omits the
+ % space.
+ %
+ % These can be used both for control words that take an argument and
+ % those that do not. If it is followed by {arg} in the input, then
+ % that will dutifully get written to the index (or wherever).
+ %
+ \def\definedummyword ##1{\def##1{\string##1\space}}%
+ \def\definedummyletter##1{\def##1{\string##1}}%
+ \let\definedummyaccent\definedummyletter
+ %
+ \commondummiesnofonts
+ %
+ \definedummyletter\_%
+ %
+ % Non-English letters.
+ \definedummyword\AA
+ \definedummyword\AE
+ \definedummyword\L
+ \definedummyword\OE
+ \definedummyword\O
+ \definedummyword\aa
+ \definedummyword\ae
+ \definedummyword\l
+ \definedummyword\oe
+ \definedummyword\o
+ \definedummyword\ss
+ \definedummyword\exclamdown
+ \definedummyword\questiondown
+ \definedummyword\ordf
+ \definedummyword\ordm
+ %
+ % Although these internal commands shouldn't show up, sometimes they do.
+ \definedummyword\bf
+ \definedummyword\gtr
+ \definedummyword\hat
+ \definedummyword\less
+ \definedummyword\sf
+ \definedummyword\sl
+ \definedummyword\tclose
+ \definedummyword\tt
+ %
+ \definedummyword\LaTeX
+ \definedummyword\TeX
+ %
+ % Assorted special characters.
+ \definedummyword\bullet
+ \definedummyword\comma
+ \definedummyword\copyright
+ \definedummyword\registeredsymbol
+ \definedummyword\dots
+ \definedummyword\enddots
+ \definedummyword\equiv
+ \definedummyword\error
+ \definedummyword\euro
+ \definedummyword\expansion
+ \definedummyword\minus
+ \definedummyword\pounds
+ \definedummyword\point
+ \definedummyword\print
+ \definedummyword\result
+ \definedummyword\textdegree
+ %
+ % We want to disable all macros so that they are not expanded by \write.
+ \macrolist
+ %
+ \normalturnoffactive
+ %
+ % Handle some cases of @value -- where it does not contain any
+ % (non-fully-expandable) commands.
+ \makevalueexpandable
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+\def\commondummiesnofonts{%
+ % Control letters and accents.
+ \definedummyletter\!%
+ \definedummyaccent\"%
+ \definedummyaccent\'%
+ \definedummyletter\*%
+ \definedummyaccent\,%
+ \definedummyletter\.%
+ \definedummyletter\/%
+ \definedummyletter\:%
+ \definedummyaccent\=%
+ \definedummyletter\?%
+ \definedummyaccent\^%
+ \definedummyaccent\`%
+ \definedummyaccent\~%
+ \definedummyword\u
+ \definedummyword\v
+ \definedummyword\H
+ \definedummyword\dotaccent
+ \definedummyword\ringaccent
+ \definedummyword\tieaccent
+ \definedummyword\ubaraccent
+ \definedummyword\udotaccent
+ \definedummyword\dotless
+ %
+ % Texinfo font commands.
+ \definedummyword\b
+ \definedummyword\i
+ \definedummyword\r
+ \definedummyword\sc
+ \definedummyword\t
+ %
+ % Commands that take arguments.
+ \definedummyword\acronym
+ \definedummyword\cite
+ \definedummyword\code
+ \definedummyword\command
+ \definedummyword\dfn
+ \definedummyword\emph
+ \definedummyword\env
+ \definedummyword\file
+ \definedummyword\kbd
+ \definedummyword\key
+ \definedummyword\math
+ \definedummyword\option
+ \definedummyword\pxref
+ \definedummyword\ref
+ \definedummyword\samp
+ \definedummyword\strong
+ \definedummyword\tie
+ \definedummyword\uref
+ \definedummyword\url
+ \definedummyword\var
+ \definedummyword\verb
+ \definedummyword\w
+ \definedummyword\xref
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names. It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+ % Accent commands should become @asis.
+ \def\definedummyaccent##1{\let##1\asis}%
+ % We can just ignore other control letters.
+ \def\definedummyletter##1{\let##1\empty}%
+ % Hopefully, all control words can become @asis.
+ \let\definedummyword\definedummyaccent
+ %
+ \commondummiesnofonts
+ %
+ % Don't no-op \tt, since it isn't a user-level command
+ % and is used in the definitions of the active chars like <, >, |, etc.
+ % Likewise with the other plain tex font commands.
+ %\let\tt=\asis
+ %
+ \def\ { }%
+ \def\@{@}%
+ % how to handle braces?
+ \def\_{\normalunderscore}%
+ %
+ % Non-English letters.
+ \def\AA{AA}%
+ \def\AE{AE}%
+ \def\L{L}%
+ \def\OE{OE}%
+ \def\O{O}%
+ \def\aa{aa}%
+ \def\ae{ae}%
+ \def\l{l}%
+ \def\oe{oe}%
+ \def\o{o}%
+ \def\ss{ss}%
+ \def\exclamdown{!}%
+ \def\questiondown{?}%
+ \def\ordf{a}%
+ \def\ordm{o}%
+ %
+ \def\LaTeX{LaTeX}%
+ \def\TeX{TeX}%
+ %
+ % Assorted special characters.
+ % (The following {} will end up in the sort string, but that's ok.)
+ \def\bullet{bullet}%
+ \def\comma{,}%
+ \def\copyright{copyright}%
+ \def\registeredsymbol{R}%
+ \def\dots{...}%
+ \def\enddots{...}%
+ \def\equiv{==}%
+ \def\error{error}%
+ \def\euro{euro}%
+ \def\expansion{==>}%
+ \def\minus{-}%
+ \def\pounds{pounds}%
+ \def\point{.}%
+ \def\print{-|}%
+ \def\result{=>}%
+ \def\textdegree{degrees}%
+ %
+ % We need to get rid of all macros, leaving only the arguments (if present).
+ % Of course this is not nearly correct, but it is the best we can do for now.
+ % makeinfo does not expand macros in the argument to @deffn, which ends up
+ % writing an index entry, and texindex isn't prepared for an index sort entry
+ % that starts with \.
+ %
+ % Since macro invocations are followed by braces, we can just redefine them
+ % to take a single TeX argument. The case of a macro invocation that
+ % goes to end-of-line is not handled.
+ %
+ \macrolist
+}
+
+\let\indexbackslash=0 %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+ \iflinks
+ {%
+ % Store the main index entry text (including the third arg).
+ \toks0 = {#2}%
+ % If third arg is present, precede it with a space.
+ \def\thirdarg{#3}%
+ \ifx\thirdarg\empty \else
+ \toks0 = \expandafter{\the\toks0 \space #3}%
+ \fi
+ %
+ \edef\writeto{\csname#1indfile\endcsname}%
+ %
+ \ifvmode
+ \dosubindsanitize
+ \else
+ \dosubindwrite
+ \fi
+ }%
+ \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+ % Put the index entry in the margin if desired.
+ \ifx\SETmarginindex\relax\else
+ \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+ \fi
+ %
+ % Remember, we are within a group.
+ \indexdummies % Must do this here, since \bf, etc expand at this stage
+ \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+ % so it will be output as is; and it will print as backslash.
+ %
+ % Process the index entry with all font commands turned off, to
+ % get the string to sort by.
+ {\indexnofonts
+ \edef\temp{\the\toks0}% need full expansion
+ \xdef\indexsorttmp{\temp}%
+ }%
+ %
+ % Set up the complete index entry, with both the sort key and
+ % the original text, including any font commands. We write
+ % three arguments to \entry to the .?? file (four in the
+ % subentry case), texindex reduces to two when writing the .??s
+ % sorted result.
+ \edef\temp{%
+ \write\writeto{%
+ \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+ }%
+ \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again. Otherwise, the whatsit generated by the
+% \write will make \lastskip zero. The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode. We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip. \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip. The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+ % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+ \skip0 = \lastskip
+ \edef\lastskipmacro{\the\lastskip}%
+ \count255 = \lastpenalty
+ %
+ % If \lastskip is nonzero, that means the last item was a
+ % skip. And since a skip is discardable, that means this
+ % -\skip0 glue we're inserting is preceded by a
+ % non-discardable item, therefore it is not a potential
+ % breakpoint, therefore no \nobreak needed.
+ \ifx\lastskipmacro\zeroskipmacro
+ \else
+ \vskip-\skip0
+ \fi
+ %
+ \dosubindwrite
+ %
+ \ifx\lastskipmacro\zeroskipmacro
+ % If \lastskip was zero, perhaps the last item was a penalty, and
+ % perhaps it was >=10000, e.g., a \nobreak. In that case, we want
+ % to re-insert the same penalty (values >10000 are used for various
+ % signals); since we just inserted a non-discardable item, any
+ % following glue (such as a \parskip) would be a breakpoint. For example:
+ %
+ % @deffn deffn-whatever
+ % @vindex index-whatever
+ % Description.
+ % would allow a break between the index-whatever whatsit
+ % and the "Description." paragraph.
+ \ifnum\count255>9999 \penalty\count255 \fi
+ \else
+ % On the other hand, if we had a nonzero \lastskip,
+ % this make-up glue would be preceded by a non-discardable item
+ % (the whatsit from the \write), so we must insert a \nobreak.
+ \nobreak\vskip\skip0
+ \fi
+}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+ \dobreak \chapheadingskip{10000}%
+ %
+ \smallfonts \rm
+ \tolerance = 9500
+ \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+ %
+ % See if the index file exists and is nonempty.
+ % Change catcode of @ here so that if the index file contains
+ % \initial {@}
+ % as its first line, TeX doesn't complain about mismatched braces
+ % (because it thinks @} is a control sequence).
+ \catcode`\@ = 11
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ \putwordIndexNonexistent
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ \putwordIndexIsEmpty
+ \else
+ % Index files are almost Texinfo source, but we use \ as the escape
+ % character. It would be better to use @, but that's too big a change
+ % to make right now.
+ \def\indexbackslash{\backslashcurfont}%
+ \catcode`\\ = 0
+ \escapechar = `\\
+ \begindoublecolumns
+ \input \jobname.#1s
+ \enddoublecolumns
+ \fi
+ \fi
+ \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+ % Some minor font changes for the special characters.
+ \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+ %
+ % Remove any glue we may have, we'll be inserting our own.
+ \removelastskip
+ %
+ % We like breaks before the index initials, so insert a bonus.
+ \nobreak
+ \vskip 0pt plus 3\baselineskip
+ \penalty 0
+ \vskip 0pt plus -3\baselineskip
+ %
+ % Typeset the initial. Making this add up to a whole number of
+ % baselineskips increases the chance of the dots lining up from column
+ % to column. It still won't often be perfect, because of the stretch
+ % we need before each entry, but it's better.
+ %
+ % No shrink because it confuses \balancecolumns.
+ \vskip 1.67\baselineskip plus .5\baselineskip
+ \leftline{\secbf #1}%
+ % Do our best not to break after the initial.
+ \nobreak
+ \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin. It is used for index
+% and table of contents entries. The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+% \def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active. This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+% --kasal, 21nov03
+\def\entry{%
+ \begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent = 2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % A bit of stretch before each entry for the benefit of balancing
+ % columns.
+ \vskip 0pt plus1pt
+ %
+ % Swallow the left brace of the text (first parameter):
+ \afterassignment\doentry
+ \let\temp =
+}
+\def\doentry{%
+ \bgroup % Instead of the swallowed brace.
+ \noindent
+ \aftergroup\finishentry
+ % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+ % #1 is the page number.
+ %
+ % The following is kludged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#1}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd
+ \ %
+ \else
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ifpdf
+ \pdfgettoks#1.%
+ \ \the\toksA
+ \else
+ \ #1%
+ \fi
+ \fi
+ \par
+ \endgroup
+}
+
+% Like plain.tex's \dotfill, except uses up at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+ \parfillskip=0in
+ \parskip=0in
+ \hangindent=1in
+ \hangafter=1
+ \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+ \ifpdf
+ \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+ \else
+ #2
+ \fi
+ \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+ % Grab any single-column material above us.
+ \output = {%
+ %
+ % Here is a possibility not foreseen in manmac: if we accumulate a
+ % whole lot of material, we might end up calling this \output
+ % routine twice in a row (see the doublecol-lose test, which is
+ % essentially a couple of indexes with @setchapternewpage off). In
+ % that case we just ship out what is in \partialpage with the normal
+ % output routine. Generally, \partialpage will be empty when this
+ % runs and this will be a no-op. See the indexspread.tex test case.
+ \ifvoid\partialpage \else
+ \onepageout{\pagecontents\partialpage}%
+ \fi
+ %
+ \global\setbox\partialpage = \vbox{%
+ % Unvbox the main output page.
+ \unvbox\PAGE
+ \kern-\topskip \kern\baselineskip
+ }%
+ }%
+ \eject % run that output routine to set \partialpage
+ %
+ % Use the double-column output routine for subsequent pages.
+ \output = {\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it in one place.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +-<1pt)
+ % as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+ \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ % Get the available space for the double columns -- the normal
+ % (undoubled) page height minus any material left over from the
+ % previous page.
+ \dimen@ = \vsize
+ \divide\dimen@ by 2
+ \advance\dimen@ by -\ht\partialpage
+ %
+ % box0 will be the left-hand column, box2 the right.
+ \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+ \onepageout\pagesofar
+ \unvbox255
+ \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+ \unvbox\partialpage
+ %
+ \hsize = \doublecolumnhsize
+ \wd0=\hsize \wd2=\hsize
+ \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+ \output = {%
+ % Split the last of the double-column material. Leave it on the
+ % current page, no automatic page break.
+ \balancecolumns
+ %
+ % If we end up splitting too much material for the current page,
+ % though, there will be another page break right after this \output
+ % invocation ends. Having called \balancecolumns once, we do not
+ % want to call it again. Therefore, reset \output to its normal
+ % definition right away. (We hope \balancecolumns will never be
+ % called on to balance too much material, but if it is, this makes
+ % the output somewhat more palatable.)
+ \global\output = {\onepageout{\pagecontents\PAGE}}%
+ }%
+ \eject
+ \endgroup % started in \begindoublecolumns
+ %
+ % \pagegoal was set to the doubled \vsize above, since we restarted
+ % the current page. We're now back to normal single-column
+ % typesetting, so reset \pagegoal to the normal \vsize (after the
+ % \endgroup where \vsize got restored).
+ \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+ \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+ \dimen@ = \ht0
+ \advance\dimen@ by \topskip
+ \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by 2 % target to split to
+ %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+ \splittopskip = \topskip
+ % Loop until we get a decent breakpoint.
+ {%
+ \vbadness = 10000
+ \loop
+ \global\setbox3 = \copy0
+ \global\setbox1 = \vsplit3 to \dimen@
+ \ifdim\ht3>\dimen@
+ \global\advance\dimen@ by 1pt
+ \repeat
+ }%
+ %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+ \setbox0=\vbox to\dimen@{\unvbox1}%
+ \setbox2=\vbox to\dimen@{\unvbox3}%
+ %
+ \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course. But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number". We avoid collisions with chapter
+% numbers by starting them at 10000. (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno \secno=0
+\newcount\subsecno \subsecno=0
+\newcount\subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+ \ifnum\appendixno=`A A%
+ \else\ifnum\appendixno=`B B%
+ \else\ifnum\appendixno=`C C%
+ \else\ifnum\appendixno=`D D%
+ \else\ifnum\appendixno=`E E%
+ \else\ifnum\appendixno=`F F%
+ \else\ifnum\appendixno=`G G%
+ \else\ifnum\appendixno=`H H%
+ \else\ifnum\appendixno=`I I%
+ \else\ifnum\appendixno=`J J%
+ \else\ifnum\appendixno=`K K%
+ \else\ifnum\appendixno=`L L%
+ \else\ifnum\appendixno=`M M%
+ \else\ifnum\appendixno=`N N%
+ \else\ifnum\appendixno=`O O%
+ \else\ifnum\appendixno=`P P%
+ \else\ifnum\appendixno=`Q Q%
+ \else\ifnum\appendixno=`R R%
+ \else\ifnum\appendixno=`S S%
+ \else\ifnum\appendixno=`T T%
+ \else\ifnum\appendixno=`U U%
+ \else\ifnum\appendixno=`V V%
+ \else\ifnum\appendixno=`W W%
+ \else\ifnum\appendixno=`X X%
+ \else\ifnum\appendixno=`Y Y%
+ \else\ifnum\appendixno=`Z Z%
+ % The \the is necessary, despite appearances, because \appendixletter is
+ % expanded while writing the .toc file. \char\appendixno is not
+ % expandable, thus it is written literally, thus all appendixes come out
+ % with the same letter (or @) in the toc without it.
+ \else\char\the\appendixno
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+ % Compute the abs. sec. level:
+ \absseclevel=#2
+ \advance\absseclevel by \secbase
+ % Make sure \absseclevel doesn't fall outside the range:
+ \ifnum \absseclevel < 0
+ \absseclevel = 0
+ \else
+ \ifnum \absseclevel > 3
+ \absseclevel = 3
+ \fi
+ \fi
+ % The heading type:
+ \def\headtype{#1}%
+ \if \headtype U%
+ \ifnum \absseclevel < \unmlevel
+ \chardef\unmlevel = \absseclevel
+ \fi
+ \else
+ % Check for appendix sections:
+ \ifnum \absseclevel = 0
+ \edef\chapheadtype{\headtype}%
+ \else
+ \if \headtype A\if \chapheadtype N%
+ \errmessage{@appendix... within a non-appendix chapter}%
+ \fi\fi
+ \fi
+ % Check for numbered within unnumbered:
+ \ifnum \absseclevel > \unmlevel
+ \def\headtype{U}%
+ \else
+ \chardef\unmlevel = 3
+ \fi
+ \fi
+ % Now print the heading:
+ \if \headtype U%
+ \ifcase\absseclevel
+ \unnumberedzzz{#3}%
+ \or \unnumberedseczzz{#3}%
+ \or \unnumberedsubseczzz{#3}%
+ \or \unnumberedsubsubseczzz{#3}%
+ \fi
+ \else
+ \if \headtype A%
+ \ifcase\absseclevel
+ \appendixzzz{#3}%
+ \or \appendixsectionzzz{#3}%
+ \or \appendixsubseczzz{#3}%
+ \or \appendixsubsubseczzz{#3}%
+ \fi
+ \else
+ \ifcase\absseclevel
+ \chapterzzz{#3}%
+ \or \seczzz{#3}%
+ \or \numberedsubseczzz{#3}%
+ \or \numberedsubsubseczzz{#3}%
+ \fi
+ \fi
+ \fi
+ \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered. Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v. By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+ % section resetting is \global in case the chapter is in a group, such
+ % as an @include file.
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\chapno by 1
+ %
+ % Used for \float.
+ \gdef\chaplevelprefix{\the\chapno.}%
+ \resetallfloatnos
+ %
+ \message{\putwordChapter\space \the\chapno}%
+ %
+ % Write the actual heading.
+ \chapmacro{#1}{Ynumbered}{\the\chapno}%
+ %
+ % So @section and the like are numbered underneath this chapter.
+ \global\let\section = \numberedsec
+ \global\let\subsection = \numberedsubsec
+ \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\appendixno by 1
+ \gdef\chaplevelprefix{\appendixletter.}%
+ \resetallfloatnos
+ %
+ \def\appendixnum{\putwordAppendix\space \appendixletter}%
+ \message{\appendixnum}%
+ %
+ \chapmacro{#1}{Yappendix}{\appendixletter}%
+ %
+ \global\let\section = \appendixsec
+ \global\let\subsection = \appendixsubsec
+ \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+ \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+ \global\advance\unnumberedno by 1
+ %
+ % Since an unnumbered has no number, no prefix for figures.
+ \global\let\chaplevelprefix = \empty
+ \resetallfloatnos
+ %
+ % This used to be simply \message{#1}, but TeX fully expands the
+ % argument to \message. Therefore, if #1 contained @-commands, TeX
+ % expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+ % expanded @cite (which turns out to cause errors because \cite is meant
+ % to be executed, not expanded).
+ %
+ % Anyway, we don't want the fully-expanded definition of @cite to appear
+ % as a result of the \message, we just want `@cite' itself. We use
+ % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+ % simply yielding the contents of <toks register>. (We also do this for
+ % the toc entries.)
+ \toks0 = {#1}%
+ \message{(\the\toks0)}%
+ %
+ \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+ %
+ \global\let\section = \unnumberedsec
+ \global\let\subsection = \unnumberedsubsec
+ \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+ % Well, we could do the following in a group, but that would break
+ % an assumption that \chapmacro is called at the outermost level.
+ % Thus we are safer this way: --kasal, 24feb04
+ \let\centerparametersmaybe = \centerparameters
+ \unnmhead0{#1}%
+ \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+ \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1
+ \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+ \global\subsubsecno=0 \global\advance\subsecno by 1
+ \sectionheading{#1}{subsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynumbered}%
+ {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Yappendix}%
+ {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+ \global\advance\subsubsecno by 1
+ \sectionheading{#1}{subsubsec}{Ynothing}%
+ {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{%
+ {\advance\chapheadingskip by 10pt \chapbreak }%
+ \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+ {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+ \bigskip \par\penalty 200\relax
+ \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+ \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+ \pchapsepmacro
+ {%
+ \chapfonts \rm
+ %
+ % Have to define \thissection before calling \donoderef, because the
+ % xref code eventually uses it. On the other hand, it has to be called
+ % after \pchapsepmacro, or the headline will change too soon.
+ \gdef\thissection{#1}%
+ \gdef\thischaptername{#1}%
+ %
+ % Only insert the separating space if we have a chapter/appendix
+ % number, and don't print the unnumbered ``number''.
+ \def\temptype{#2}%
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unnchap}%
+ \gdef\thischapternum{}%
+ \gdef\thischapter{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+ \def\toctype{omit}%
+ \gdef\thischapternum{}%
+ \gdef\thischapter{}%
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+ \def\toctype{app}%
+ \xdef\thischapternum{\appendixletter}%
+ % We don't substitute the actual chapter name into \thischapter
+ % because we don't want its macros evaluated now. And we don't
+ % use \thissection because that changes with each section.
+ %
+ \xdef\thischapter{\putwordAppendix{} \appendixletter:
+ \noexpand\thischaptername}%
+ \else
+ \setbox0 = \hbox{#3\enspace}%
+ \def\toctype{numchap}%
+ \xdef\thischapternum{\the\chapno}%
+ \xdef\thischapter{\putwordChapter{} \the\chapno:
+ \noexpand\thischaptername}%
+ \fi\fi\fi
+ %
+ % Write the toc entry for this chapter. Must come before the
+ % \donoderef, because we include the current node name in the toc
+ % entry, and \donoderef resets it to empty.
+ \writetocentry{\toctype}{#1}{#3}%
+ %
+ % For pdftex, we have to write out the node definition (aka, make
+ % the pdfdest) after any page break, but before the actual text has
+ % been typeset. If the destination for the pdf outline is after the
+ % text, then jumping from the outline may wind up with the text not
+ % being visible, for instance under high magnification.
+ \donoderef{#2}%
+ %
+ % Typeset the actual heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 \centerparametersmaybe
+ \unhbox0 #1\par}%
+ }%
+ \nobreak\bigskip % no page break after a chapter title
+ \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+ \advance\rightskip by 3\rightskip
+ \leftskip = \rightskip
+ \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff. We'll see. --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt
+ \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+ \global\let\chapmacro=\chfopen
+ \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles. These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+ {%
+ % Switch to the right set of fonts.
+ \csname #2fonts\endcsname \rm
+ %
+ % Insert space above the heading.
+ \csname #2headingbreak\endcsname
+ %
+ % Only insert the space after the number if we have a section number.
+ \def\sectionlevel{#2}%
+ \def\temptype{#3}%
+ %
+ \ifx\temptype\Ynothingkeyword
+ \setbox0 = \hbox{}%
+ \def\toctype{unn}%
+ \gdef\thissection{#1}%
+ \else\ifx\temptype\Yomitfromtockeyword
+ % for @headings -- no section number, don't include in toc,
+ % and don't redefine \thissection.
+ \setbox0 = \hbox{}%
+ \def\toctype{omit}%
+ \let\sectionlevel=\empty
+ \else\ifx\temptype\Yappendixkeyword
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{app}%
+ \gdef\thissection{#1}%
+ \else
+ \setbox0 = \hbox{#4\enspace}%
+ \def\toctype{num}%
+ \gdef\thissection{#1}%
+ \fi\fi\fi
+ %
+ % Write the toc entry (before \donoderef). See comments in \chapmacro.
+ \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+ %
+ % Write the node reference (= pdf destination for pdftex).
+ % Again, see comments in \chapmacro.
+ \donoderef{#3}%
+ %
+ % Interline glue will be inserted when the vbox is completed.
+ % That glue will be a valid breakpoint for the page, since it'll be
+ % preceded by a whatsit (usually from the \donoderef, or from the
+ % \writetocentry if there was no node). We don't want to allow that
+ % break, since then the whatsits could end up on page n while the
+ % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000.
+ \nobreak
+ %
+ % Output the actual section heading.
+ \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+ \hangindent=\wd0 % zero if no section number
+ \unhbox0 #1}%
+ }%
+ % Add extra space after the heading -- half of whatever came above it.
+ % Don't allow stretch, though.
+ \kern .5 \csname #2headingskip\endcsname
+ %
+ % Do not let the kern be a potential breakpoint, as it would be if it
+ % was followed by glue.
+ \nobreak
+ %
+ % We'll almost certainly start a paragraph next, so don't let that
+ % glue accumulate. (Not a breakpoint because it's preceded by a
+ % discardable item.)
+ \vskip-\parskip
+ %
+ % This is purely so the last item on the list is a known \penalty >
+ % 10000. This is so \startdefun can avoid allowing breakpoints after
+ % section headings. Otherwise, it would insert a valid breakpoint between:
+ %
+ % @section sec-whatever
+ % @deffn def-whatever
+ \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this. The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything. This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+ \edef\writetoctype{#1}%
+ \ifx\writetoctype\omitkeyword \else
+ \iftocfileopened\else
+ \immediate\openout\tocfile = \jobname.toc
+ \global\tocfileopenedtrue
+ \fi
+ %
+ \iflinks
+ {\atdummies
+ \edef\temp{%
+ \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}%
+ \temp
+ }%
+ \fi
+ \fi
+ %
+ % Tell \shipout to create a pdf destination on each page, if we're
+ % writing pdf. These are used in the table of contents. We can't
+ % just write one on every page because the title pages are numbered
+ % 1 and 2 (the page numbers aren't printed), and so are the first
+ % two pages of the document. Thus, we'd have two destinations named
+ % `1', and two named `2'.
+ \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+
+% These characters do not print properly in the Computer Modern roman
+% fonts, so we must take special care. This is more or less redundant
+% with the Texinfo input format setup at the end of this file.
+%
+\def\activecatcodes{%
+ \catcode`\"=\active
+ \catcode`\$=\active
+ \catcode`\<=\active
+ \catcode`\>=\active
+ \catcode`\\=\active
+ \catcode`\^=\active
+ \catcode`\_=\active
+ \catcode`\|=\active
+ \catcode`\~=\active
+}
+
+
+% Read the toc file, which is essentially Texinfo input.
+\def\readtocfile{%
+ \setupdatafile
+ \activecatcodes
+ \input \jobname.toc
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+ % If @setchapternewpage on, and @headings double, the contents should
+ % start on an odd page, unlike chapters. Thus, we maintain
+ % \contentsalignmacro in parallel with \pagealignmacro.
+ % From: Torbjorn Granlund <tege@matematik.su.se>
+ \contentsalignmacro
+ \immediate\closeout\tocfile
+ %
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \def\thischapter{}%
+ \chapmacro{#1}{Yomitfromtoc}{}%
+ %
+ \savepageno = \pageno
+ \begingroup % Set up to handle contents files properly.
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+ %
+ % Roman numerals for page numbers.
+ \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+ \startcontents{\putwordTOC}%
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \ifeof 1 \else
+ \pdfmakeoutlines
+ \fi
+ \closein 1
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+ \startcontents{\putwordShortTOC}%
+ %
+ \let\numchapentry = \shortchapentry
+ \let\appentry = \shortchapentry
+ \let\unnchapentry = \shortunnchapentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf
+ \let\sl=\shortcontsl \let\tt=\shortconttt
+ \rm
+ \hyphenpenalty = 10000
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\numsecentry##1##2##3##4{}
+ \let\appsecentry = \numsecentry
+ \let\unnsecentry = \numsecentry
+ \let\numsubsecentry = \numsecentry
+ \let\appsubsecentry = \numsecentry
+ \let\unnsubsecentry = \numsecentry
+ \let\numsubsubsecentry = \numsecentry
+ \let\appsubsubsecentry = \numsecentry
+ \let\unnsubsubsecentry = \numsecentry
+ \openin 1 \jobname.toc
+ \ifeof 1 \else
+ \readtocfile
+ \fi
+ \closein 1
+ \vfill \eject
+ \contentsalignmacro % in case @setchapternewpage odd is in effect
+ \endgroup
+ \lastnegativepageno = \pageno
+ \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+ % This space should be enough, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % But use \hss just in case.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in by \shortchapentry above.)
+ %
+ % We'd like to right-justify chapter numbers, but that looks strange
+ % with appendix letters. And right-justifying numbers and
+ % left-justifying letters looks strange when there is less than 10
+ % chapters. Have to read the whole toc once to know how many chapters
+ % there are before deciding ...
+ \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+ % We use M since it's probably the widest letter.
+ \setbox0 = \hbox{\putwordAppendix{} M}%
+ \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \reducedsf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{%
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+ \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+ \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+ \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+ \catcode `\%=14
+ \catcode `\+=\other
+ \catcode `\"=\other
+ \catcode `\|=\other
+ \catcode `\<=\other
+ \catcode `\>=\other
+ \escapechar=`\\
+ %
+ \let\b=\ptexb
+ \let\bullet=\ptexbullet
+ \let\c=\ptexc
+ \let\,=\ptexcomma
+ \let\.=\ptexdot
+ \let\dots=\ptexdots
+ \let\equiv=\ptexequiv
+ \let\!=\ptexexclam
+ \let\i=\ptexi
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \let\{=\ptexlbrace
+ \let\+=\tabalign
+ \let\}=\ptexrbrace
+ \let\/=\ptexslash
+ \let\*=\ptexstar
+ \let\t=\ptext
+ \let\frenchspacing=\plainfrenchspacing
+ %
+ \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+ \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+ \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+ % =10000 instead of <10000 because of a special case in \itemzzz and
+ % \sectionheading, q.v.
+ \ifnum \lastpenalty=10000 \else
+ \advance\envskipamount by \parskip
+ \endgraf
+ \ifdim\lastskip<\envskipamount
+ \removelastskip
+ % it's not a good place to break if the last penalty was \nobreak
+ % or better ...
+ \ifnum\lastpenalty<10000 \penalty-50 \fi
+ \vskip\envskipamount
+ \fi
+ \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will
+% also clear it, so that its embedded environments do the narrowing again.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+ \ifhmode\par\fi % can't be in the midst of a paragraph.
+ \startsavinginserts
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt % we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18.4pt % allow for 3pt kerns on either
+ % side, and for 6pt waste from
+ % each corner char, and rule thickness
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing = t%
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \kern3pt
+ \hsize=\cartinner
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+ \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+ \ifhmode\par\fi
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+ \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+% @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+ \ifx\SETdispenvsize\smallword
+ \smallexamplefonts \rm
+ \fi
+}
+\def\setsmalldispenv{%
+ \ifx\SETdispenvsize\nosmallword
+ \else
+ \smallexamplefonts \rm
+ \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+ \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+ \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+ \expandafter\let\csname E#1\endcsname \afterenvbreak
+ \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+ \makedispenv{#1}{#3}
+ \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+ \nonfillstart
+ \tt\quoteexpand
+ \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+ \gobble % eat return
+}
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+ \nonfillstart
+ \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ \advance\leftskip by 0pt plus 1fill
+ \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins. We keep \parskip nonzero in general, since
+% we're doing normal filling. So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \parindent=0pt
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \else
+ \let\nonarrowing = \relax
+ \fi
+ \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+ \par
+ \ifx\quotationauthor\undefined\else
+ % indent a bit.
+ \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+ \fi
+ {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+ \def\temp{#1}%
+ \ifx\temp\empty \else
+ {\bf #1: }%
+ \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too. Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+ \do\ \do\\\do\{\do\}\do\$\do\&%
+ \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+ \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+ \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+ \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+ \tt % easiest (and conventionally used) font for verbatim
+ \def\par{\leavevmode\endgraf}%
+ \catcode`\`=\active
+ \tabeightspaces
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+
+% Allow an option to not replace quotes with a regular directed right
+% quote/apostrophe (char 0x27), but instead use the undirected quote
+% from cmtt (char 0x0d). The undirected quote is ugly, so don't make it
+% the default, but it works for pasting with more pdf viewers (at least
+% evince), the lilypond developers report. xpdf does work with the
+% regular 0x27.
+%
+\def\codequoteright{%
+ \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
+ '%
+ \else
+ \char'15
+ \fi
+}
+%
+% and a similar option for the left quote char vs. a grave accent.
+% Modern fonts display ASCII 0x60 as a grave accent, so some people like
+% the code environments to do likewise.
+%
+\def\codequoteleft{%
+ \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
+ `%
+ \else
+ \char'22
+ \fi
+}
+%
+\begingroup
+ \catcode`\^^I=\active
+ \gdef\tabexpand{%
+ \catcode`\^^I=\active
+ \def^^I{\leavevmode\egroup
+ \dimen0=\wd0 % the width so far, or since the previous tab
+ \divide\dimen0 by\tabw
+ \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+ \advance\dimen0 by\tabw % advance to next multiple of \tabw
+ \wd0=\dimen0 \box0 \starttabbox
+ }%
+ }
+ \catcode`\'=\active
+ \gdef\rquoteexpand{\catcode\rquoteChar=\active \def'{\codequoteright}}%
+ %
+ \catcode`\`=\active
+ \gdef\lquoteexpand{\catcode\lquoteChar=\active \def`{\codequoteleft}}%
+ %
+ \gdef\quoteexpand{\rquoteexpand \lquoteexpand}%
+\endgroup
+
+% start the verbatim environment.
+\def\setupverbatim{%
+ \let\nonarrowing = t%
+ \nonfillstart
+ % Easiest (and conventionally used) font for verbatim
+ \tt
+ \def\par{\leavevmode\egroup\box0\endgraf}%
+ \catcode`\`=\active
+ \tabexpand
+ \quoteexpand
+ % Respect line breaks,
+ % print special symbols as themselves, and
+ % make each space count
+ % must do in this order:
+ \obeylines \uncatcodespecials \sepspaces
+ \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters. Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+% \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+ \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+ \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+% \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+ \catcode`\ =\active
+ \obeylines %
+ % ignore everything up to the first ^^M, that's the newline at the end
+ % of the @verbatim input line itself. Otherwise we get an extra blank
+ % line in the output.
+ \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+ % We really want {...\end verbatim} in the body of the macro, but
+ % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+ \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+ {%
+ \makevalueexpandable
+ \setupverbatim
+ \input #1
+ \afterenvbreak
+ }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+ \begingroup
+ \parindent = 0pt % paragraph indentation looks wrong on title page
+ \scanexp\copyingtext
+ \endgroup
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% Start the processing of @deffn:
+\def\startdefun{%
+ \ifnum\lastpenalty<10000
+ \medbreak
+ \else
+ % If there are two @def commands in a row, we'll have a \nobreak,
+ % which is there to keep the function description together with its
+ % header. But if there's nothing but headers, we need to allow a
+ % break somewhere. Check specifically for penalty 10002, inserted
+ % by \defargscommonending, instead of 10000, since the sectioning
+ % commands also insert a nobreak penalty, and we don't want to allow
+ % a break between a section heading and a defun.
+ %
+ \ifnum\lastpenalty=10002 \penalty2000 \fi
+ %
+ % Similarly, after a section heading, do not allow a break.
+ % But do insert the glue.
+ \medskip % preceded by discardable penalty, so not a breakpoint
+ \fi
+ %
+ \parindent=0in
+ \advance\leftskip by \defbodyindent
+ \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+ % First, check whether we are in the right environment:
+ \checkenv#1%
+ %
+ % As above, allow line break if we have multiple x headers in a row.
+ % It's not a great place, though.
+ \ifnum\lastpenalty=10002 \penalty3000 \fi
+ %
+ % And now, it's time to reuse the body of the original defun:
+ \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+ \begingroup
+ % call \deffnheader:
+ #1#2 \endheader
+ % common ending:
+ \interlinepenalty = 10000
+ \advance\rightskip by 0pt plus 1fil
+ \endgraf
+ \nobreak\vskip -\parskip
+ \penalty 10002 % signal to \startdefun and \dodefunx
+ % Some of the @defun-type tags do not enable magic parentheses,
+ % rendering the following check redundant. But we don't optimize.
+ \checkparencounts
+ \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+ \expandafter\let\csname E#1\endcsname = \Edefun
+ \edef\temp{\noexpand\domakedefun
+ \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+ \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+ \envdef#1{%
+ \startdefun
+ \parseargusing\activeparens{\printdefunline#3}%
+ }%
+ \def#2{\dodefunx#1}%
+ \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+ % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+ \dosubind{fn}{\code{#3}}{#1}%
+ \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{fn}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+ \dosubind{vr}{\code{#4}}{#1}%
+ \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+ \doind{tp}{\code{#2}}%
+ \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+ % Get the values of \leftskip and \rightskip as they were outside the @def...
+ \advance\leftskip by -\defbodyindent
+ %
+ % How we'll format the type name. Putting it in brackets helps
+ % distinguish it from the body text that may end up on the next line
+ % just below it.
+ \def\temp{#1}%
+ \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+ %
+ % Figure out line sizes for the paragraph shape.
+ % The first line needs space for \box0; but if \rightskip is nonzero,
+ % we need only space for the part of \box0 which exceeds it:
+ \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip
+ % The continuations:
+ \dimen2=\hsize \advance\dimen2 by -\defargsindent
+ % (plain.tex says that \dimen1 should be used only as global.)
+ \parshape 2 0in \dimen0 \defargsindent \dimen2
+ %
+ % Put the type name to the right margin.
+ \noindent
+ \hbox to 0pt{%
+ \hfil\box0 \kern-\hsize
+ % \hsize has to be shortened this way:
+ \kern\leftskip
+ % Intentionally do not respect \rightskip, since we need the space.
+ }%
+ %
+ % Allow all lines to be underfull without complaint:
+ \tolerance=10000 \hbadness=10000
+ \exdentamount=\defbodyindent
+ {%
+ % defun fonts. We use typewriter by default (used to be bold) because:
+ % . we're printing identifiers, they should be in tt in principle.
+ % . in languages with many accents, such as Czech or French, it's
+ % common to leave accents off identifiers. The result looks ok in
+ % tt, but exceedingly strange in rm.
+ % . we don't want -- and --- to be treated as ligatures.
+ % . this still does not fix the ?` and !` ligatures, but so far no
+ % one has made identifiers using them :).
+ \df \tt
+ \def\temp{#2}% return value type
+ \ifx\temp\empty\else \tclose{\temp} \fi
+ #3% output function name
+ }%
+ {\rm\enskip}% hskip 0.5 em of \tenrm
+ %
+ \boldbrax
+ % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name. This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable. Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+ % use sl by default (not ttsl),
+ % tt for the names.
+ \df \sl \hyphenchar\font=0
+ %
+ % On the other hand, if an argument has two dashes (for instance), we
+ % want a way to get ttsl. Let's try @var for that.
+ \let\var=\ttslanted
+ #1%
+ \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+ \catcode`\(=\active \catcode`\)=\active
+ \catcode`\[=\active \catcode`\]=\active
+ \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+ \activeparens
+ \global\let(=\lparen \global\let)=\rparen
+ \global\let[=\lbrack \global\let]=\rbrack
+ \global\let& = \&
+
+ \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+ \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\ }}
+
+\def\parenfont{%
+ \ifampseen
+ % At the first level, print parens in roman,
+ % otherwise use the default font.
+ \ifnum \parencount=1 \rm \fi
+ \else
+ % The \sf parens (in \boldbrax) actually are a little bolder than
+ % the contained text. This is especially needed for [ and ] .
+ \sf
+ \fi
+}
+\def\infirstlevel#1{%
+ \ifampseen
+ \ifnum\parencount=1
+ #1%
+ \fi
+ \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+ \global\advance\parencount by 1
+ {\parenfont(}%
+ \infirstlevel \bfafterword
+}
+\def\clnr{%
+ {\parenfont)}%
+ \infirstlevel \sl
+ \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+ \global\advance\brackcount by 1
+ {\bf[}%
+}
+\def\rbrb{%
+ {\bf]}%
+ \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+ \ifnum\parencount=0 \else \badparencount \fi
+ \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+ \errmessage{Unbalanced parentheses in @def}%
+ \global\parencount=0
+}
+\def\badbrackcount{%
+ \errmessage{Unbalanced square braces in @def}%
+ \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+ \newwrite\macscribble
+ \def\scantokens#1{%
+ \toks0={#1}%
+ \immediate\openout\macscribble=\jobname.tmp
+ \immediate\write\macscribble{\the\toks0}%
+ \immediate\closeout\macscribble
+ \input \jobname.tmp
+ }
+\fi
+
+\def\scanmacro#1{%
+ \begingroup
+ \newlinechar`\^^M
+ \let\xeatspaces\eatspaces
+ % Undo catcode changes of \startcontents and \doprintindex
+ % When called from @insertcopying or (short)caption, we need active
+ % backslash to get it printed correctly. Previously, we had
+ % \catcode`\\=\other instead. We'll see whether a problem appears
+ % with macro expansion. --kasal, 19aug04
+ \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+ % ... and \example
+ \spaceisspace
+ %
+ % Append \endinput to make sure that TeX does not see the ending newline.
+ % I've verified that it is necessary both for e-TeX and for ordinary TeX
+ % --kasal, 29nov03
+ \scantokens{#1\endinput}%
+ \endgroup
+}
+
+\def\scanexp#1{%
+ \edef\temp{\noexpand\scanmacro{#1}}%
+ \temp
+}
+
+\newcount\paramno % Count of parameters
+\newtoks\macname % Macro name
+\newif\ifrecursive % Is it recursive?
+
+% List of all defined macros in the form
+% \definedummyword\macro1\definedummyword\macro2...
+% Currently is also contains all @aliases; the list can be split
+% if there is a need.
+\def\macrolist{}
+
+% Add the macro to \macrolist
+\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname}
+\def\addtomacrolistxxx#1{%
+ \toks0 = \expandafter{\macrolist\definedummyword#1}%
+ \xdef\macrolist{\the\toks0}%
+}
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+% \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+%
+\def\cslet#1#2{%
+ \expandafter\let
+ \csname#1\expandafter\endcsname
+ \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+ \catcode`\"=\other
+ \catcode`\+=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\@=\other
+ \catcode`\^=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+ \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+ \scanctxt
+ \catcode`\{=\other
+ \catcode`\}=\other
+ \catcode`\^^M=\other
+ \usembodybackslash
+}
+
+\def\macroargctxt{%
+ \scanctxt
+ \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+ \getargs{#1}% now \macname is the macname and \argl the arglist
+ \ifx\argl\empty % no arguments
+ \paramno=0%
+ \else
+ \expandafter\parsemargdef \argl;%
+ \fi
+ \if1\csname ismacro.\the\macname\endcsname
+ \message{Warning: redefining \the\macname}%
+ \else
+ \expandafter\ifx\csname \the\macname\endcsname \relax
+ \else \errmessage{Macro name \the\macname\space already defined}\fi
+ \global\cslet{macsave.\the\macname}{\the\macname}%
+ \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+ \addtomacrolist{\the\macname}%
+ \fi
+ \begingroup \macrobodyctxt
+ \ifrecursive \expandafter\parsermacbody
+ \else \expandafter\parsemacbody
+ \fi}
+
+\parseargdef\unmacro{%
+ \if1\csname ismacro.#1\endcsname
+ \global\cslet{#1}{macsave.#1}%
+ \global\expandafter\let \csname ismacro.#1\endcsname=0%
+ % Remove the macro name from \macrolist:
+ \begingroup
+ \expandafter\let\csname#1\endcsname \relax
+ \let\definedummyword\unmacrodo
+ \xdef\macrolist{\macrolist}%
+ \endgroup
+ \else
+ \errmessage{Macro #1 not defined}%
+ \fi
+}
+
+% Called by \do from \dounmacro on each macro. The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+ \ifx #1\relax
+ % remove this
+ \else
+ \noexpand\definedummyword \noexpand#1%
+ \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list. Set up \paramno and \paramlist
+% so \defmacro knows what to do. Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX: let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+ \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+ \if#1;\let\next=\relax
+ \else \let\next=\parsemargdefxxx
+ \advance\paramno by 1%
+ \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+ {\xeatspaces{\hash\the\paramno}}%
+ \edef\paramlist{\paramlist\hash\the\paramno,}%
+ \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+ \let\hash=##% convert placeholders to macro parameter chars
+ \ifrecursive
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\scanmacro{\temp}}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup\noexpand\scanmacro{\temp}}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+ \fi
+ \else
+ \ifcase\paramno
+ % 0
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \or % 1
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \noexpand\braceorline
+ \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+ \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \else % many
+ \expandafter\xdef\csname\the\macname\endcsname{%
+ \bgroup\noexpand\macroargctxt
+ \expandafter\noexpand\csname\the\macname xx\endcsname}%
+ \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+ \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+ \expandafter\expandafter
+ \expandafter\xdef
+ \expandafter\expandafter
+ \csname\the\macname xxx\endcsname
+ \paramlist{%
+ \egroup
+ \noexpand\norecurse{\the\macname}%
+ \noexpand\scanmacro{\temp}\egroup}%
+ \fi
+ \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {. If so it reads up to the closing }, if not, it reads the whole
+% line. Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+ \ifx\nchar\bgroup\else
+ \expandafter\parsearg
+ \fi \macnamexxx}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign. Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+ {%
+ \expandafter\let\obeyedspace=\empty
+ \addtomacrolist{#1}%
+ \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+ }%
+ \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references. The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross, , , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node. #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+ \ifx\lastnode\empty\else
+ \setref{\lastnode}{#1}%
+ \global\let\lastnode=\empty
+ \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+% or the anchor name.
+% 2) NAME-snt - section number and type, passed as the SNT arg, or
+% empty for anchors.
+% 3) NAME-pg - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat. In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+ \pdfmkdest{#1}%
+ \iflinks
+ {%
+ \atdummies % preserve commands, but don't expand them
+ \edef\writexrdef##1##2{%
+ \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+ ##1}{##2}}% these are parameters of \writexrdef
+ }%
+ \toks0 = \expandafter{\thissection}%
+ \immediate \writexrdef{title}{\the\toks0 }%
+ \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+ \writexrdef{pg}{\folio}% will be written later, during \shipout
+ }%
+ \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references. For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual. All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \unsepspaces
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printedrefname{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual\unskip}%
+ \setbox0=\hbox{\printedrefname\unskip}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+ % Use the node name inside the square brackets.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1 > 0pt
+ % It is in another manual, so we don't have it.
+ \def\printedrefname{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printedrefname{\refx{#1-title}{}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printedrefname{\ignorespaces #1}%
+ \fi%
+ \fi
+ \fi
+ \fi
+ %
+ % Make link in pdf output.
+ \ifpdf
+ \leavevmode
+ \getfilename{#4}%
+ {\turnoffactive
+ % See comments at \activebackslashdouble.
+ {\activebackslashdouble \xdef\pdfxrefdest{#1}%
+ \backslashparens\pdfxrefdest}%
+ %
+ \ifnum\filenamelength>0
+ \startlink attr{/Border [0 0 0]}%
+ goto file{\the\filename.pdf} name{\pdfxrefdest}%
+ \else
+ \startlink attr{/Border [0 0 0]}%
+ goto name{\pdfmkpgn{\pdfxrefdest}}%
+ \fi
+ }%
+ \linkcolor
+ \fi
+ %
+ % Float references are printed completely differently: "Figure 1.2"
+ % instead of "[somenode], p.3". We distinguish them by the
+ % LABEL-title being set to a magic string.
+ {%
+ % Have to otherify everything special to allow the \csname to
+ % include an _ in the xref name, etc.
+ \indexnofonts
+ \turnoffactive
+ \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+ \csname XR#1-title\endcsname
+ }%
+ \iffloat\Xthisreftitle
+ % If the user specified the print name (third arg) to the ref,
+ % print it instead of our usual "Figure 1.2".
+ \ifdim\wd0 = 0pt
+ \refx{#1-snt}{}%
+ \else
+ \printedrefname
+ \fi
+ %
+ % if the user also gave the printed manual name (fifth arg), append
+ % "in MANUALNAME".
+ \ifdim \wd1 > 0pt
+ \space \putwordin{} \cite{\printedmanual}%
+ \fi
+ \else
+ % node/anchor (non-float) references.
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive
+ % Only output a following space if the -snt ref is nonempty; for
+ % @unnumbered and @anchor, it won't be.
+ \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+ \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+ }%
+ % output the `[mynode]' via a macro so it can be overridden.
+ \xrefprintnodename\printedrefname
+ %
+ % But we always want a comma and a space:
+ ,\space
+ %
+ % output the `page 3'.
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+ \fi
+ \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output. It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents. Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+ \ifnum\secno=0
+ \putwordChapter@tie \the\chapno
+ \else \ifnum\subsecno=0
+ \putwordSection@tie \the\chapno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+\def\Yappendix{%
+ \ifnum\secno=0
+ \putwordAppendix@tie @char\the\appendixno{}%
+ \else \ifnum\subsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno
+ \else \ifnum\subsubsecno=0
+ \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+ \else
+ \putwordSection@tie
+ @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+ \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+ {%
+ \indexnofonts
+ \otherbackslash
+ \expandafter\global\expandafter\let\expandafter\thisrefX
+ \csname XR#1\endcsname
+ }%
+ \ifx\thisrefX\relax
+ % If not defined, say something at least.
+ \angleleft un\-de\-fined\angleright
+ \iflinks
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \thisrefX
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file. Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions). But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+ \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+ %
+ % Was that xref control sequence that we just defined for a float?
+ \expandafter\iffloat\csname XR#1\endcsname
+ % it was a float, and we have the (safe) float type in \iffloattype.
+ \expandafter\let\expandafter\floatlist
+ \csname floatlist\iffloattype\endcsname
+ %
+ % Is this the first time we've seen this float type?
+ \expandafter\ifx\floatlist\relax
+ \toks0 = {\do}% yes, so just \do
+ \else
+ % had it before, so preserve previous elements in list.
+ \toks0 = \expandafter{\floatlist\do}%
+ \fi
+ %
+ % Remember this xref in the control sequence \floatlistFLOATTYPE,
+ % for later use in \listoffloats.
+ \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+ \fi
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+%
+\def\tryauxfile{%
+ \openin 1 \jobname.aux
+ \ifeof 1 \else
+ \readdatafile{aux}%
+ \global\havexrefstrue
+ \fi
+ \closein 1
+}
+
+\def\setupdatafile{%
+ \catcode`\^^@=\other
+ \catcode`\^^A=\other
+ \catcode`\^^B=\other
+ \catcode`\^^C=\other
+ \catcode`\^^D=\other
+ \catcode`\^^E=\other
+ \catcode`\^^F=\other
+ \catcode`\^^G=\other
+ \catcode`\^^H=\other
+ \catcode`\^^K=\other
+ \catcode`\^^L=\other
+ \catcode`\^^N=\other
+ \catcode`\^^P=\other
+ \catcode`\^^Q=\other
+ \catcode`\^^R=\other
+ \catcode`\^^S=\other
+ \catcode`\^^T=\other
+ \catcode`\^^U=\other
+ \catcode`\^^V=\other
+ \catcode`\^^W=\other
+ \catcode`\^^X=\other
+ \catcode`\^^Z=\other
+ \catcode`\^^[=\other
+ \catcode`\^^\=\other
+ \catcode`\^^]=\other
+ \catcode`\^^^=\other
+ \catcode`\^^_=\other
+ % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+ % in xref tags, i.e., node names. But since ^^e4 notation isn't
+ % supported in the main text, it doesn't seem desirable. Furthermore,
+ % that is not enough: for node names that actually contain a ^
+ % character, we would end up writing a line like this: 'xrdef {'hat
+ % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+ % argument, and \hat is not an expandable control sequence. It could
+ % all be worked out, but why? Either we support ^^ or we don't.
+ %
+ % The other change necessary for this was to define \auxhat:
+ % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+ % and then to call \auxhat in \setq.
+ %
+ \catcode`\^=\other
+ %
+ % Special characters. Should be turned off anyway, but...
+ \catcode`\~=\other
+ \catcode`\[=\other
+ \catcode`\]=\other
+ \catcode`\"=\other
+ \catcode`\_=\other
+ \catcode`\|=\other
+ \catcode`\<=\other
+ \catcode`\>=\other
+ \catcode`\$=\other
+ \catcode`\#=\other
+ \catcode`\&=\other
+ \catcode`\%=\other
+ \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+ %
+ % This is to support \ in node names and titles, since the \
+ % characters end up in a \csname. It's easier than
+ % leaving it active and making its active definition an actual \
+ % character. What I don't understand is why it works in the *value*
+ % of the xrdef. Seems like it should be a catcode12 \, and that
+ % should not typeset properly. But it works, so I'm moving on for
+ % now. --karl, 15jan04.
+ \catcode`\\=\other
+ %
+ % Make the characters 128-255 be printing characters.
+ {%
+ \count1=128
+ \def\loop{%
+ \catcode\count1=\other
+ \advance\count1 by 1
+ \ifnum \count1<256 \loop \fi
+ }%
+ }%
+ %
+ % @ is our escape character in .aux files, and we need braces.
+ \catcode`\{=1
+ \catcode`\}=2
+ \catcode`\@=0
+}
+
+\def\readdatafile#1{%
+\begingroup
+ \setupdatafile
+ \input\jobname.#1
+\endgroup}
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \let\indent=\ptexindent
+ \let\noindent=\ptexnoindent
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read. --karl, 16nov96.
+%
+\gdef\dofootnote{%
+ \insert\footins\bgroup
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \hsize=\pagewidth
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ \smallfonts \rm
+ %
+ % Because we use hanging indentation in footnotes, a @noindent appears
+ % to exdent this text, so make it be a no-op. makeinfo does not use
+ % hanging indentation so @noindent can still be needed within footnote
+ % text after an @example or the like (not that this is good style).
+ \let\noindent = \relax
+ %
+ % Hang the footnote text off the number. Use \everypar in case the
+ % footnote extends for more than one paragraph.
+ \everypar = {\hang}%
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished. Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes. --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+ \ifx \insert\ptexinsert
+ \let\insert\saveinsert
+ \else
+ \let\checkinserts\relax
+ \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+ \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+ \afterassignment\next
+ % swallow the left brace
+ \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+ \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+ {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+ \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-)
+ \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+ \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+ \next
+}
+\def\newsaveinsX #1{%
+ \csname newbox\endcsname #1%
+ \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+ \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image. We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front. If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+ % Do not bother showing banner with epsf.tex v2.7k (available in
+ % doc/epsf.tex and on ctan).
+ \def\epsfannounce{\toks0 = }%
+ \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+ work. It is also included in the Texinfo distribution, or you can get
+ it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+ \ifx\epsfbox\undefined
+ \ifwarnednoepsf \else
+ \errhelp = \noepsfhelp
+ \errmessage{epsf.tex not found, images will be ignored}%
+ \global\warnednoepsftrue
+ \fi
+ \else
+ \imagexxx #1,,,,,\finish
+ \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+ \catcode`\^^M = 5 % in case we're inside an example
+ \normalturnoffactive % allow _ et al. in names
+ % If the image is by itself, center it.
+ \ifvmode
+ \imagevmodetrue
+ \nobreak\bigskip
+ % Usually we'll have text after the image which will insert
+ % \parskip glue, so insert it here too to equalize the space
+ % above and below.
+ \nobreak\vskip\parskip
+ \nobreak
+ \line\bgroup
+ \fi
+ %
+ % Output the image.
+ \ifpdf
+ \dopdfimage{#1}{#2}{#3}%
+ \else
+ % \epsfbox itself resets \epsf?size at each figure.
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+ \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+ \epsfbox{#1.eps}%
+ \fi
+ %
+ \ifimagevmode \egroup \bigbreak \fi % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc. We don't actually implement floating yet, we always include the
+% float "here". But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc. Can't contain commas. If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label. Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored. It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+ \let\thiscaption=\empty
+ \let\thisshortcaption=\empty
+ %
+ % don't lose footnotes inside @float.
+ %
+ % BEWARE: when the floats start float, we have to issue warning whenever an
+ % insert appears inside a float which could possibly float. --kasal, 26may04
+ %
+ \startsavinginserts
+ %
+ % We can't be used inside a paragraph.
+ \par
+ %
+ \vtop\bgroup
+ \def\floattype{#1}%
+ \def\floatlabel{#2}%
+ \def\floatloc{#3}% we do nothing with this yet.
+ %
+ \ifx\floattype\empty
+ \let\safefloattype=\empty
+ \else
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ \fi
+ %
+ % If label is given but no type, we handle that as the empty type.
+ \ifx\floatlabel\empty \else
+ % We want each FLOATTYPE to be numbered separately (Figure 1,
+ % Table 1, Figure 2, ...). (And if no label, no number.)
+ %
+ \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+ \global\advance\floatno by 1
+ %
+ {%
+ % This magic value for \thissection is output by \setref as the
+ % XREFLABEL-title value. \xrefX uses it to distinguish float
+ % labels (which have a completely different output format) from
+ % node and anchor labels. And \xrdef uses it to construct the
+ % lists of floats.
+ %
+ \edef\thissection{\floatmagic=\safefloattype}%
+ \setref{\floatlabel}{Yfloat}%
+ }%
+ \fi
+ %
+ % start with \parskip glue, I guess.
+ \vskip\parskip
+ %
+ % Don't suppress indentation if a float happens to start a section.
+ \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption: Foo 1.1
+% @float Foo & @caption{Cap}: Foo: Cap
+% @float Foo & no caption: Foo
+% @float ,lbl & Caption{Cap}: 1.1: Cap
+% @float ,lbl & no caption: 1.1
+% @float & @caption{Cap}: Cap
+% @float & no caption:
+%
+\def\Efloat{%
+ \let\floatident = \empty
+ %
+ % In all cases, if we have a float type, it comes first.
+ \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+ %
+ % If we have an xref label, the number comes next.
+ \ifx\floatlabel\empty \else
+ \ifx\floattype\empty \else % if also had float type, need tie first.
+ \appendtomacro\floatident{\tie}%
+ \fi
+ % the number.
+ \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+ \fi
+ %
+ % Start the printed caption with what we've constructed in
+ % \floatident, but keep it separate; we need \floatident again.
+ \let\captionline = \floatident
+ %
+ \ifx\thiscaption\empty \else
+ \ifx\floatident\empty \else
+ \appendtomacro\captionline{: }% had ident, so need a colon between
+ \fi
+ %
+ % caption text.
+ \appendtomacro\captionline{\scanexp\thiscaption}%
+ \fi
+ %
+ % If we have anything to print, print it, with space before.
+ % Eventually this needs to become an \insert.
+ \ifx\captionline\empty \else
+ \vskip.5\parskip
+ \captionline
+ %
+ % Space below caption.
+ \vskip\parskip
+ \fi
+ %
+ % If have an xref label, write the list of floats info. Do this
+ % after the caption, to avoid chance of it being a breakpoint.
+ \ifx\floatlabel\empty \else
+ % Write the text that goes in the lof to the aux file as
+ % \floatlabel-lof. Besides \floatident, we include the short
+ % caption if specified, else the full caption if specified, else nothing.
+ {%
+ \atdummies
+ %
+ % since we read the caption text in the macro world, where ^^M
+ % is turned into a normal character, we have to scan it back, so
+ % we don't write the literal three characters "^^M" into the aux file.
+ \scanexp{%
+ \xdef\noexpand\gtemp{%
+ \ifx\thisshortcaption\empty
+ \thiscaption
+ \else
+ \thisshortcaption
+ \fi
+ }%
+ }%
+ \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+ \ifx\gtemp\empty \else : \gtemp \fi}}%
+ }%
+ \fi
+ \egroup % end of \vtop
+ %
+ % place the captured inserts
+ %
+ % BEWARE: when the floats start floating, we have to issue warning
+ % whenever an insert appears inside a float which could possibly
+ % float. --kasal, 26may04
+ %
+ \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+ \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use. Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+ \ifx#1\relax
+ % Haven't seen this figure type before.
+ \csname newcount\endcsname #1%
+ %
+ % Remember to reset this floatno at the next chap.
+ \expandafter\gdef\expandafter\resetallfloatnos
+ \expandafter{\resetallfloatnos #1=0 }%
+ \fi
+ \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value. We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref. That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string. If so, #2 will be the
+% (safe) float type for this float. We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+ \def\temp{#1}%
+ \def\iffloattype{#2}%
+ \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+ \def\floattype{#1}% floattype
+ {%
+ % the floattype might have accents or other special characters,
+ % but we need to use it in a control sequence name.
+ \indexnofonts
+ \turnoffactive
+ \xdef\safefloattype{\floattype}%
+ }%
+ %
+ % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+ \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+ \ifhavexrefs
+ % if the user said @listoffloats foo but never @float foo.
+ \message{\linenumber No `\safefloattype' floats to list.}%
+ \fi
+ \else
+ \begingroup
+ \leftskip=\tocindent % indent these entries like a toc
+ \let\do=\listoffloatsdo
+ \csname floatlist\safefloattype\endcsname
+ \endgroup
+ \fi
+}
+
+% This is called on each entry in a list of floats. We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file. We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+ % Can't fully expand XR#1-lof because it can contain anything. Just
+ % pass the control sequence. On the other hand, XR#1-pg is just the
+ % page number, and we want to fully expand that so we can get a link
+ % in pdf output.
+ \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+ %
+ % use the same \entry macro we use to generate the TOC and index.
+ \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+ \writeentry
+}}
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename. If done too late, it may not override everything
+% properly. Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+ \tex % read txi-??.tex file in plain TeX.
+ % Read the file if it exists.
+ \openin 1 txi-#1.tex
+ \ifeof 1
+ \errhelp = \nolanghelp
+ \errmessage{Cannot read language file txi-#1.tex}%
+ \else
+ \input txi-#1.tex
+ \fi
+ \closein 1
+ \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty. Maybe you need to install it? In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+ \ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+ \else
+ \emergencystretch = .15\hsize
+ \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth;
+% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip;
+% 7) physical page height; 8) physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading. The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+ \voffset = #3\relax
+ \topskip = #6\relax
+ \splittopskip = \topskip
+ %
+ \vsize = #1\relax
+ \advance\vsize by \topskip
+ \outervsize = \vsize
+ \advance\outervsize by 2\topandbottommargin
+ \pageheight = \vsize
+ %
+ \hsize = #2\relax
+ \outerhsize = \hsize
+ \advance\outerhsize by 0.5in
+ \pagewidth = \hsize
+ %
+ \normaloffset = #4\relax
+ \bindingoffset = #5\relax
+ %
+ \ifpdf
+ \pdfpageheight #7\relax
+ \pdfpagewidth #8\relax
+ \fi
+ %
+ \setleading{\textleading}
+ %
+ \parindent = \defaultparindent
+ \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % If page is nothing but text, make it come out even.
+ \internalpagesizes{46\baselineskip}{6in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{36pt}%
+ {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.25 trim size.
+\def\smallbook{{\globaldefs = 1
+ \parskip = 2pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.5in}{5in}%
+ {\voffset}{.25in}%
+ {\bindingoffset}{16pt}%
+ {9.25in}{7in}%
+ %
+ \lispnarrowing = 0.3in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .5cm
+}}
+
+% Use @smallerbook to reset parameters for 6x9 trim size.
+% (Just testing, parameters still in flux.)
+\def\smallerbook{{\globaldefs = 1
+ \parskip = 1.5pt plus 1pt
+ \textleading = 12pt
+ %
+ \internalpagesizes{7.4in}{4.8in}%
+ {-.2in}{-.4in}%
+ {0pt}{14pt}%
+ {9in}{6in}%
+ %
+ \lispnarrowing = 0.25in
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = .4cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+ \parskip = 3pt plus 2pt minus 1pt
+ \textleading = 13.2pt
+ %
+ % Double-side printing via postscript on Laserjet 4050
+ % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+ % To change the settings for a different printer or situation, adjust
+ % \normaloffset until the front-side and back-side texts align. Then
+ % do the same for \bindingoffset. You can set these for testing in
+ % your texinfo source file like this:
+ % @tex
+ % \global\normaloffset = -6mm
+ % \global\bindingoffset = 10mm
+ % @end tex
+ \internalpagesizes{51\baselineskip}{160mm}
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{44pt}%
+ {297mm}{210mm}%
+ %
+ \tolerance = 700
+ \hfuzz = 1pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+ \parskip = 2pt plus 1pt minus 0.1pt
+ \textleading = 12.5pt
+ %
+ \internalpagesizes{160mm}{120mm}%
+ {\voffset}{\hoffset}%
+ {\bindingoffset}{8pt}%
+ {210mm}{148mm}%
+ %
+ \lispnarrowing = 0.2in
+ \tolerance = 800
+ \hfuzz = 1.2pt
+ \contentsrightmargin = 0pt
+ \defbodyindent = 2mm
+ \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{237mm}{150mm}%
+ {\voffset}{4.6mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ %
+ % Must explicitly reset to 0 because we call \afourpaper.
+ \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+ \afourpaper
+ \internalpagesizes{241mm}{165mm}%
+ {\voffset}{-2.95mm}%
+ {\bindingoffset}{7mm}%
+ {297mm}{210mm}%
+ \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+ \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+ \globaldefs = 1
+ %
+ \parskip = 3pt plus 2pt minus 1pt
+ \setleading{\textleading}%
+ %
+ \dimen0 = #1
+ \advance\dimen0 by \voffset
+ %
+ \dimen2 = \hsize
+ \advance\dimen2 by \normaloffset
+ %
+ \internalpagesizes{#1}{\hsize}%
+ {\voffset}{\normaloffset}%
+ {\bindingoffset}{44pt}%
+ {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font. Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts. But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+\let\realunder=_
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+% Used sometimes to turn off (effectively) the active characters even after
+% parsing them.
+\def\turnoffactive{%
+ \normalturnoffactive
+ \otherbackslash
+}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work
+
+% \realbackslash is an actual character `\' with catcode other, and
+% \doublebackslash is two of them (for the pdf outlines).
+{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}}
+
+% In texinfo, backslash is an active character; it prints the backslash
+% in fixed width font.
+\catcode`\\=\active
+@def@normalbackslash{{@tt@backslashcurfont}}
+% On startup, @fixbackslash assigns:
+% @let \ = @normalbackslash
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+@gdef@rawbackslash{@let\=@backslashcurfont}
+@gdef@otherbackslash{@let\=@realbackslash}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.
+%
+@def@normalturnoffactive{%
+ @let\=@normalbackslash
+ @let"=@normaldoublequote
+ @let~=@normaltilde
+ @let^=@normalcaret
+ @let_=@normalunderscore
+ @let|=@normalverticalbar
+ @let<=@normalless
+ @let>=@normalgreater
+ @let+=@normalplus
+ @let$=@normaldollar %$ font-lock fix
+ @unsepspaces
+}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\' in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also turn back on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+ @ifx\@eatinput @let\ = @normalbackslash @fi
+ @catcode`+=@active
+ @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+ arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
--- /dev/null
+@set UPDATED 29 June 2011
+@set UPDATED-MONTH June 2011
+@set EDITION 1.5.0
+@set VERSION 1.5.0
--- /dev/null
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2006-10-14.15
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" "" $nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+if test -z "$doit"; then
+ doit_exec=exec
+else
+ doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+posix_glob=
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chmodcmd=$chmodprog
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+ or: $0 [OPTION]... SRCFILES... DIRECTORY
+ or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+ or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c (ignored)
+-d create directories instead of installing files.
+-g GROUP $chgrpprog installed files to GROUP.
+-m MODE $chmodprog installed files to MODE.
+-o USER $chownprog installed files to USER.
+-s $stripprog installed files.
+-t DIRECTORY install into DIRECTORY.
+-T report an error if DSTFILE is a directory.
+--help display this help and exit.
+--version display version info and exit.
+
+Environment variables override the default commands:
+ CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+ case $1 in
+ -c) shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ --help) echo "$usage"; exit $?;;
+
+ -m) mode=$2
+ shift
+ shift
+ case $mode in
+ *' '* | *' '* | *'
+'* | *'*'* | *'?'* | *'['*)
+ echo "$0: invalid mode: $mode" >&2
+ exit 1;;
+ esac
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd=$stripprog
+ shift
+ continue;;
+
+ -t) dstarg=$2
+ shift
+ shift
+ continue;;
+
+ -T) no_target_directory=true
+ shift
+ continue;;
+
+ --version) echo "$0 $scriptversion"; exit $?;;
+
+ --) shift
+ break;;
+
+ -*) echo "$0: invalid option: $1" >&2
+ exit 1;;
+
+ *) break;;
+ esac
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+ # When -d is used, all remaining arguments are directories to create.
+ # When -t is used, the destination is already specified.
+ # Otherwise, the last argument is the destination. Remove it from $@.
+ for arg
+ do
+ if test -n "$dstarg"; then
+ # $@ is not empty: it contains at least $arg.
+ set fnord "$@" "$dstarg"
+ shift # fnord
+ fi
+ shift # arg
+ dstarg=$arg
+ done
+fi
+
+if test $# -eq 0; then
+ if test -z "$dir_arg"; then
+ echo "$0: no input file specified." >&2
+ exit 1
+ fi
+ # It's OK to call `install-sh -d' without argument.
+ # This can happen when creating conditional directories.
+ exit 0
+fi
+
+if test -z "$dir_arg"; then
+ trap '(exit $?); exit' 1 2 13 15
+
+ # Set umask so as not to create temps with too-generous modes.
+ # However, 'strip' requires both read and write access to temps.
+ case $mode in
+ # Optimize common cases.
+ *644) cp_umask=133;;
+ *755) cp_umask=22;;
+
+ *[0-7])
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw='% 200'
+ fi
+ cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+ *)
+ if test -z "$stripcmd"; then
+ u_plus_rw=
+ else
+ u_plus_rw=,u+rw
+ fi
+ cp_umask=$mode$u_plus_rw;;
+ esac
+fi
+
+for src
+do
+ # Protect names starting with `-'.
+ case $src in
+ -*) src=./$src ;;
+ esac
+
+ if test -n "$dir_arg"; then
+ dst=$src
+ dstdir=$dst
+ test -d "$dstdir"
+ dstdir_status=$?
+ else
+
+ # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+ # might cause directories to be created, which would be especially bad
+ # if $src (and thus $dsttmp) contains '*'.
+ if test ! -f "$src" && test ! -d "$src"; then
+ echo "$0: $src does not exist." >&2
+ exit 1
+ fi
+
+ if test -z "$dstarg"; then
+ echo "$0: no destination specified." >&2
+ exit 1
+ fi
+
+ dst=$dstarg
+ # Protect names starting with `-'.
+ case $dst in
+ -*) dst=./$dst ;;
+ esac
+
+ # If destination is a directory, append the input filename; won't work
+ # if double slashes aren't ignored.
+ if test -d "$dst"; then
+ if test -n "$no_target_directory"; then
+ echo "$0: $dstarg: Is a directory" >&2
+ exit 1
+ fi
+ dstdir=$dst
+ dst=$dstdir/`basename "$src"`
+ dstdir_status=0
+ else
+ # Prefer dirname, but fall back on a substitute if dirname fails.
+ dstdir=`
+ (dirname "$dst") 2>/dev/null ||
+ expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$dst" : 'X\(//\)[^/]' \| \
+ X"$dst" : 'X\(//\)$' \| \
+ X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+ echo X"$dst" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'
+ `
+
+ test -d "$dstdir"
+ dstdir_status=$?
+ fi
+ fi
+
+ obsolete_mkdir_used=false
+
+ if test $dstdir_status != 0; then
+ case $posix_mkdir in
+ '')
+ # Create intermediate dirs using mode 755 as modified by the umask.
+ # This is like FreeBSD 'install' as of 1997-10-28.
+ umask=`umask`
+ case $stripcmd.$umask in
+ # Optimize common cases.
+ *[2367][2367]) mkdir_umask=$umask;;
+ .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+ *[0-7])
+ mkdir_umask=`expr $umask + 22 \
+ - $umask % 100 % 40 + $umask % 20 \
+ - $umask % 10 % 4 + $umask % 2
+ `;;
+ *) mkdir_umask=$umask,go-w;;
+ esac
+
+ # With -d, create the new directory with the user-specified mode.
+ # Otherwise, rely on $mkdir_umask.
+ if test -n "$dir_arg"; then
+ mkdir_mode=-m$mode
+ else
+ mkdir_mode=
+ fi
+
+ posix_mkdir=false
+ case $umask in
+ *[123567][0-7][0-7])
+ # POSIX mkdir -p sets u+wx bits regardless of umask, which
+ # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+ ;;
+ *)
+ tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+ if (umask $mkdir_umask &&
+ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+ then
+ if test -z "$dir_arg" || {
+ # Check for POSIX incompatibilities with -m.
+ # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+ # other-writeable bit of parent directory when it shouldn't.
+ # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+ ls_ld_tmpdir=`ls -ld "$tmpdir"`
+ case $ls_ld_tmpdir in
+ d????-?r-*) different_mode=700;;
+ d????-?--*) different_mode=755;;
+ *) false;;
+ esac &&
+ $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+ ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+ test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+ }
+ }
+ then posix_mkdir=:
+ fi
+ rmdir "$tmpdir/d" "$tmpdir"
+ else
+ # Remove any dirs left behind by ancient mkdir implementations.
+ rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+ fi
+ trap '' 0;;
+ esac;;
+ esac
+
+ if
+ $posix_mkdir && (
+ umask $mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+ )
+ then :
+ else
+
+ # The umask is ridiculous, or mkdir does not conform to POSIX,
+ # or it failed possibly due to a race condition. Create the
+ # directory the slow way, step by step, checking for races as we go.
+
+ case $dstdir in
+ /*) prefix=/ ;;
+ -*) prefix=./ ;;
+ *) prefix= ;;
+ esac
+
+ case $posix_glob in
+ '')
+ if (set -f) 2>/dev/null; then
+ posix_glob=true
+ else
+ posix_glob=false
+ fi ;;
+ esac
+
+ oIFS=$IFS
+ IFS=/
+ $posix_glob && set -f
+ set fnord $dstdir
+ shift
+ $posix_glob && set +f
+ IFS=$oIFS
+
+ prefixes=
+
+ for d
+ do
+ test -z "$d" && continue
+
+ prefix=$prefix$d
+ if test -d "$prefix"; then
+ prefixes=
+ else
+ if $posix_mkdir; then
+ (umask=$mkdir_umask &&
+ $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+ # Don't fail if two instances are running concurrently.
+ test -d "$prefix" || exit 1
+ else
+ case $prefix in
+ *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+ *) qprefix=$prefix;;
+ esac
+ prefixes="$prefixes '$qprefix'"
+ fi
+ fi
+ prefix=$prefix/
+ done
+
+ if test -n "$prefixes"; then
+ # Don't fail if two instances are running concurrently.
+ (umask $mkdir_umask &&
+ eval "\$doit_exec \$mkdirprog $prefixes") ||
+ test -d "$dstdir" || exit 1
+ obsolete_mkdir_used=true
+ fi
+ fi
+ fi
+
+ if test -n "$dir_arg"; then
+ { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+ { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+ { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+ else
+
+ # Make a couple of temp file names in the proper directory.
+ dsttmp=$dstdir/_inst.$$_
+ rmtmp=$dstdir/_rm.$$_
+
+ # Trap to clean up those temp files at exit.
+ trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+ # Copy the file name to the temp name.
+ (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+ # and set any options; do chmod last to preserve setuid bits.
+ #
+ # If any of these fail, we abort the whole thing. If we want to
+ # ignore errors from any of these, just make sure not to ignore
+ # errors from the above "$doit $cpprog $src $dsttmp" command.
+ #
+ { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+ && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+ && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+ && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+ # Now rename the file to the real destination.
+ { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
+ || {
+ # The rename failed, perhaps because mv can't rename something else
+ # to itself, or perhaps because mv is so ancient that it does not
+ # support -f.
+
+ # Now remove or move aside any old file at destination location.
+ # We try this two ways since rm can't unlink itself on some
+ # systems and the destination file might be busy for other
+ # reasons. In this case, the final cleanup might fail but the new
+ # file should still install successfully.
+ {
+ if test -f "$dst"; then
+ $doit $rmcmd -f "$dst" 2>/dev/null \
+ || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
+ && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
+ || {
+ echo "$0: cannot unlink or rename $dst" >&2
+ (exit 1); exit 1
+ }
+ else
+ :
+ fi
+ } &&
+
+ # Now rename the file to the real destination.
+ $doit $mvcmd "$dsttmp" "$dst"
+ }
+ } || exit 1
+
+ trap '' 0
+ fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions. There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+# --config show all configuration variables
+# --debug enable verbose shell tracing
+# -n, --dry-run display commands without modifying any files
+# --features display basic configuration information and exit
+# --mode=MODE use operation mode MODE
+# --preserve-dup-deps don't remove duplicate dependency libraries
+# --quiet, --silent don't print informational messages
+# --tag=TAG use configuration variables from tag TAG
+# -v, --verbose print informational messages (default)
+# --version print version information
+# -h, --help print short or long help message
+#
+# MODE must be one of the following:
+#
+# clean remove files from the build directory
+# compile compile a source file into a libtool object
+# execute automatically set library path, then run a program
+# finish complete the installation of libtool libraries
+# install install libraries or executables
+# link create a library or an executable
+# uninstall remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+# host-triplet: $host
+# shell: $SHELL
+# compiler: $LTCC
+# compiler flags: $LTCFLAGS
+# linker: $LD (gnu? $with_gnu_ld)
+# $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2
+# automake: $automake_version
+# autoconf: $autoconf_version
+#
+# Report bugs to <bug-libtool@gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION="2.2.6b Debian-2.2.6b-2"
+TIMESTAMP=""
+package_revision=1.3017
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ $lt_var=C
+ export $lt_var
+ lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+ lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+ fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" $lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+ -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+ [\\/]*|[A-Za-z]:\\*) ;;
+ *[\\/]*)
+ progdir=$func_dirname_result
+ progdir=`cd "$progdir" && pwd`
+ progpath="$progdir/$progname"
+ ;;
+ *)
+ save_IFS="$IFS"
+ IFS=:
+ for progdir in $PATH; do
+ IFS="$save_IFS"
+ test -x "$progdir/$progname" && break
+ done
+ IFS="$save_IFS"
+ test -n "$progdir" || progdir=`pwd`
+ progpath="$progdir/$progname"
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same. If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'. `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+ s/$bs4/&\\
+/g
+ s/^$bs2$dollar/$bs&/
+ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+ s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+ $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+ $opt_verbose && func_echo ${1+"$@"}
+
+ # A bug in bash halts the script if the last line of a function
+ # fails when set -e is in force, so we need another command to
+ # work around that:
+ :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+ $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+ $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+ # bash bug again:
+ :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+ func_error ${1+"$@"}
+ exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+ func_error ${1+"$@"}
+ func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information." ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+ $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+ my_directory_path="$1"
+ my_dir_list=
+
+ if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+ # Protect directory names starting with `-'
+ case $my_directory_path in
+ -*) my_directory_path="./$my_directory_path" ;;
+ esac
+
+ # While some portion of DIR does not yet exist...
+ while test ! -d "$my_directory_path"; do
+ # ...make a list in topmost first order. Use a colon delimited
+ # list incase some portion of path contains whitespace.
+ my_dir_list="$my_directory_path:$my_dir_list"
+
+ # If the last portion added has no slash in it, the list is done
+ case $my_directory_path in */*) ;; *) break ;; esac
+
+ # ...otherwise throw away the child directory and loop
+ my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+ done
+ my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+ save_mkdir_p_IFS="$IFS"; IFS=':'
+ for my_dir in $my_dir_list; do
+ IFS="$save_mkdir_p_IFS"
+ # mkdir can fail with a `File exist' error if two processes
+ # try to create one of the directories concurrently. Don't
+ # stop in that case!
+ $MKDIR "$my_dir" 2>/dev/null || :
+ done
+ IFS="$save_mkdir_p_IFS"
+
+ # Bail out if we (or some other process) failed to create a directory.
+ test -d "$my_directory_path" || \
+ func_fatal_error "Failed to create \`$1'"
+ fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible. If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+ my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+ if test "$opt_dry_run" = ":"; then
+ # Return a directory name, but don't create it in dry-run mode
+ my_tmpdir="${my_template}-$$"
+ else
+
+ # If mktemp works, use that first and foremost
+ my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+ if test ! -d "$my_tmpdir"; then
+ # Failing that, at least try and use $RANDOM to avoid a race
+ my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+ save_mktempdir_umask=`umask`
+ umask 0077
+ $MKDIR "$my_tmpdir"
+ umask $save_mktempdir_umask
+ fi
+
+ # If we're not in dry-run mode, bomb out on failure
+ test -d "$my_tmpdir" || \
+ func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+ fi
+
+ $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+ case $1 in
+ *[\\\`\"\$]*)
+ func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+ *)
+ func_quote_for_eval_unquoted_result="$1" ;;
+ esac
+
+ case $func_quote_for_eval_unquoted_result in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting, command substitution and and variable
+ # expansion for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+ ;;
+ *)
+ func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+ esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+ case $1 in
+ *[\\\`\"]*)
+ my_arg=`$ECHO "X$1" | $Xsed \
+ -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+ *)
+ my_arg="$1" ;;
+ esac
+
+ case $my_arg in
+ # Double-quote args containing shell metacharacters to delay
+ # word splitting and command substitution for a subsequent eval.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ my_arg="\"$my_arg\""
+ ;;
+ esac
+
+ func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$my_cmd"
+ my_status=$?
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
+# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it. Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+ my_cmd="$1"
+ my_fail_exp="${2-:}"
+
+ ${opt_silent-false} || {
+ func_quote_for_expand "$my_cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+
+ if ${opt_dry_run-false}; then :; else
+ eval "$lt_user_locale
+ $my_cmd"
+ my_status=$?
+ eval "$lt_safe_locale"
+ if test "$my_status" -eq 0; then :; else
+ eval "(exit $my_status); $my_fail_exp"
+ fi
+ fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+ $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+ s/^# //
+ s/^# *$//
+ s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+ $SED -n '/^# Usage:/,/# -h/ {
+ s/^# //
+ s/^# *$//
+ s/\$progname/'$progname'/
+ p
+ }' < "$progpath"
+ $ECHO
+ $ECHO "run \`$progname --help | more' for full usage"
+ exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+ $SED -n '/^# Usage:/,/# Report bugs to/ {
+ s/^# //
+ s/^# *$//
+ s*\$progname*'$progname'*
+ s*\$host*'"$host"'*
+ s*\$SHELL*'"$SHELL"'*
+ s*\$LTCC*'"$LTCC"'*
+ s*\$LTCFLAGS*'"$LTCFLAGS"'*
+ s*\$LD*'"$LD"'*
+ s/\$with_gnu_ld/'"$with_gnu_ld"'/
+ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+ p
+ }' < "$progpath"
+ exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+ func_error "missing argument for $1"
+ exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell, and then maybe $ECHO will work.
+ exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+ func_error ${1+"$@"}
+ func_error "See the $PACKAGE documentation for more information."
+ func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+ re_begincf='^# ### BEGIN LIBTOOL'
+ re_endcf='^# ### END LIBTOOL'
+
+ # Default configuration.
+ $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+ # Now print the configurations for the tags.
+ for tagname in $taglist; do
+ $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+ done
+
+ exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+ $ECHO "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ $ECHO "enable shared libraries"
+ else
+ $ECHO "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ $ECHO "enable static libraries"
+ else
+ $ECHO "disable static libraries"
+ fi
+
+ exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag. We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+ # Global variable:
+ tagname="$1"
+
+ re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+ re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+ sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+ # Validate tagname.
+ case $tagname in
+ *[!-_A-Za-z0-9,/]*)
+ func_fatal_error "invalid tag name: $tagname"
+ ;;
+ esac
+
+ # Don't test for the "default" C tag, as we know it's
+ # there but not specially marked.
+ case $tagname in
+ CC) ;;
+ *)
+ if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+ taglist="$taglist $tagname"
+
+ # Evaluate the configuration. Be careful to quote the path
+ # and the sed script, to avoid splitting on whitespace, but
+ # also don't use non-portable quotes within backquotes within
+ # quotes we have to do it in 2 steps:
+ extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+ eval "$extractedcf"
+ else
+ func_error "ignoring unknown tag $tagname"
+ fi
+ ;;
+ esac
+}
+
+# Parse options once, thoroughly. This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+ # Shorthand for --mode=foo, only valid as the first argument
+ case $1 in
+ clean|clea|cle|cl)
+ shift; set dummy --mode clean ${1+"$@"}; shift
+ ;;
+ compile|compil|compi|comp|com|co|c)
+ shift; set dummy --mode compile ${1+"$@"}; shift
+ ;;
+ execute|execut|execu|exec|exe|ex|e)
+ shift; set dummy --mode execute ${1+"$@"}; shift
+ ;;
+ finish|finis|fini|fin|fi|f)
+ shift; set dummy --mode finish ${1+"$@"}; shift
+ ;;
+ install|instal|insta|inst|ins|in|i)
+ shift; set dummy --mode install ${1+"$@"}; shift
+ ;;
+ link|lin|li|l)
+ shift; set dummy --mode link ${1+"$@"}; shift
+ ;;
+ uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+ shift; set dummy --mode uninstall ${1+"$@"}; shift
+ ;;
+ esac
+
+ # Parse non-mode specific arguments:
+ while test "$#" -gt 0; do
+ opt="$1"
+ shift
+
+ case $opt in
+ --config) func_config ;;
+
+ --debug) preserve_args="$preserve_args $opt"
+ func_echo "enabling shell trace mode"
+ opt_debug='set -x'
+ $opt_debug
+ ;;
+
+ -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ execute_dlfiles="$execute_dlfiles $1"
+ shift
+ ;;
+
+ --dry-run | -n) opt_dry_run=: ;;
+ --features) func_features ;;
+ --finish) mode="finish" ;;
+
+ --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ case $1 in
+ # Valid mode arguments:
+ clean) ;;
+ compile) ;;
+ execute) ;;
+ finish) ;;
+ install) ;;
+ link) ;;
+ relink) ;;
+ uninstall) ;;
+
+ # Catch anything else as an error
+ *) func_error "invalid argument for $opt"
+ exit_cmd=exit
+ break
+ ;;
+ esac
+
+ mode="$1"
+ shift
+ ;;
+
+ --preserve-dup-deps)
+ opt_duplicate_deps=: ;;
+
+ --quiet|--silent) preserve_args="$preserve_args $opt"
+ opt_silent=:
+ ;;
+
+ --verbose| -v) preserve_args="$preserve_args $opt"
+ opt_silent=false
+ ;;
+
+ --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break
+ preserve_args="$preserve_args $opt $1"
+ func_enable_tag "$1" # tagname is set here
+ shift
+ ;;
+
+ # Separate optargs to long options:
+ -dlopen=*|--mode=*|--tag=*)
+ func_opt_split "$opt"
+ set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+ shift
+ ;;
+
+ -\?|-h) func_usage ;;
+ --help) opt_help=: ;;
+ --version) func_version ;;
+
+ -*) func_fatal_help "unrecognized option \`$opt'" ;;
+
+ *) nonopt="$opt"
+ break
+ ;;
+ esac
+ done
+
+
+ case $host in
+ *cygwin* | *mingw* | *pw32* | *cegcc*)
+ # don't eliminate duplications in $postdeps and $predeps
+ opt_duplicate_compiler_generated_deps=:
+ ;;
+ *)
+ opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+ ;;
+ esac
+
+ # Having warned about all mis-specified options, bail out if
+ # anything was wrong.
+ $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+ if test "$package_revision" != "$macro_revision"; then
+ if test "$VERSION" != "$macro_version"; then
+ if test -z "$macro_version"; then
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+ fi
+ else
+ cat >&2 <<_LT_EOF
+$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+ fi
+
+ exit $EXIT_MISMATCH
+ fi
+}
+
+
+## ----------- ##
+## Main. ##
+## ----------- ##
+
+$opt_help || {
+ # Sanity checks first:
+ func_check_version_match
+
+ if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ func_fatal_configuration "not configured to build any kind of library"
+ fi
+
+ test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+ # Darwin sucks
+ eval std_shrext=\"$shrext_cmds\"
+
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ func_error "unrecognized option \`-dlopen'"
+ $ECHO "$help" 1>&2
+ exit $EXIT_FAILURE
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+ test -f "$1" &&
+ $SED -e 4q "$1" 2>/dev/null \
+ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs. To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway. Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+ lalib_p=no
+ if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+ for lalib_p_l in 1 2 3 4
+ do
+ read lalib_p_line
+ case "$lalib_p_line" in
+ \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+ esac
+ done
+ exec 0<&5 5<&-
+ fi
+ test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+ func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+ func_ltwrapper_exec_suffix=
+ case $1 in
+ *.exe) ;;
+ *) func_ltwrapper_exec_suffix=.exe ;;
+ esac
+ $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+ func_ltwrapper_scriptname_result=""
+ if func_ltwrapper_executable_p "$1"; then
+ func_dirname_and_basename "$1" "" "."
+ func_stripname '' '.exe' "$func_basename_result"
+ func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+ fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+ func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+ $opt_debug
+ save_ifs=$IFS; IFS='~'
+ for cmd in $1; do
+ IFS=$save_ifs
+ eval cmd=\"$cmd\"
+ func_show_eval "$cmd" "${2-:}"
+ done
+ IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)! Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+ $opt_debug
+ case $1 in
+ */* | *\\*) . "$1" ;;
+ *) . "./$1" ;;
+ esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+ $opt_debug
+ if test -n "$available_tags" && test -z "$tagname"; then
+ CC_quoted=
+ for arg in $CC; do
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case $@ in
+ # Blanks in the command may have been stripped by the calling shell,
+ # but not from the CC environment variable when configure was run.
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+ # Blanks at the start of $base_compile will cause this to fail
+ # if we don't check for them as well.
+ *)
+ for z in $available_tags; do
+ if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+ # Evaluate the configuration.
+ eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+ CC_quoted=
+ for arg in $CC; do
+ # Double-quote args containing other shell metacharacters.
+ func_quote_for_eval "$arg"
+ CC_quoted="$CC_quoted $func_quote_for_eval_result"
+ done
+ case "$@ " in
+ " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+ # The compiler in the base compile command matches
+ # the one in the tagged configuration.
+ # Assume this is the tagged configuration we want.
+ tagname=$z
+ break
+ ;;
+ esac
+ fi
+ done
+ # If $tagname still isn't set, then no tagged configuration
+ # was found and let the user know that the "--tag" command
+ # line option must be used.
+ if test -z "$tagname"; then
+ func_echo "unable to infer tagged configuration"
+ func_fatal_error "specify a tag with \`--tag'"
+# else
+# func_verbose "using $tagname tagged configuration"
+ fi
+ ;;
+ esac
+ fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+ write_libobj=${1}
+ if test "$build_libtool_libs" = yes; then
+ write_lobj=\'${2}\'
+ else
+ write_lobj=none
+ fi
+
+ if test "$build_old_libs" = yes; then
+ write_oldobj=\'${3}\'
+ else
+ write_oldobj=none
+ fi
+
+ $opt_dry_run || {
+ cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+ $MV "${write_libobj}T" "${write_libobj}"
+ }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+ $opt_debug
+ # Get the compilation command and the source file.
+ base_compile=
+ srcfile="$nonopt" # always keep a non-empty value in "srcfile"
+ suppress_opt=yes
+ suppress_output=
+ arg_mode=normal
+ libobj=
+ later=
+ pie_flag=
+
+ for arg
+ do
+ case $arg_mode in
+ arg )
+ # do not "continue". Instead, add this to base_compile
+ lastarg="$arg"
+ arg_mode=normal
+ ;;
+
+ target )
+ libobj="$arg"
+ arg_mode=normal
+ continue
+ ;;
+
+ normal )
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ test -n "$libobj" && \
+ func_fatal_error "you cannot specify \`-o' more than once"
+ arg_mode=target
+ continue
+ ;;
+
+ -pie | -fpie | -fPIE)
+ pie_flag="$pie_flag $arg"
+ continue
+ ;;
+
+ -shared | -static | -prefer-pic | -prefer-non-pic)
+ later="$later $arg"
+ continue
+ ;;
+
+ -no-suppress)
+ suppress_opt=no
+ continue
+ ;;
+
+ -Xcompiler)
+ arg_mode=arg # the next one goes into the "base_compile" arg list
+ continue # The current "srcfile" will either be retained or
+ ;; # replaced later. I would guess that would be a bug.
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$arg"
+ lastarg="$lastarg $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$lastarg"
+ lastarg=$func_stripname_result
+
+ # Add the arguments to base_compile.
+ base_compile="$base_compile $lastarg"
+ continue
+ ;;
+
+ *)
+ # Accept the current argument as the source file.
+ # The previous "srcfile" becomes the current argument.
+ #
+ lastarg="$srcfile"
+ srcfile="$arg"
+ ;;
+ esac # case $arg
+ ;;
+ esac # case $arg_mode
+
+ # Aesthetically quote the previous argument.
+ func_quote_for_eval "$lastarg"
+ base_compile="$base_compile $func_quote_for_eval_result"
+ done # for arg
+
+ case $arg_mode in
+ arg)
+ func_fatal_error "you must specify an argument for -Xcompile"
+ ;;
+ target)
+ func_fatal_error "you must specify a target with \`-o'"
+ ;;
+ *)
+ # Get the name of the library object.
+ test -z "$libobj" && {
+ func_basename "$srcfile"
+ libobj="$func_basename_result"
+ }
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ case $libobj in
+ *.[cCFSifmso] | \
+ *.ada | *.adb | *.ads | *.asm | \
+ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+ *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+ func_xform "$libobj"
+ libobj=$func_xform_result
+ ;;
+ esac
+
+ case $libobj in
+ *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+ *)
+ func_fatal_error "cannot determine name of library object from \`$libobj'"
+ ;;
+ esac
+
+ func_infer_tag $base_compile
+
+ for arg in $later; do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ continue
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+ esac
+ done
+
+ func_quote_for_eval "$libobj"
+ test "X$libobj" != "X$func_quote_for_eval_result" \
+ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \
+ && func_warning "libobj name \`$libobj' may not contain shell special characters."
+ func_dirname_and_basename "$obj" "/" ""
+ objname="$func_basename_result"
+ xdir="$func_dirname_result"
+ lobj=${xdir}$objdir/$objname
+
+ test -z "$base_compile" && \
+ func_fatal_help "you must specify a compilation command"
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $lobj $libobj ${libobj}T"
+ else
+ removelist="$lobj $libobj ${libobj}T"
+ fi
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2* | cegcc*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ else
+ output_obj=
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+ func_echo "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ $ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+ removelist="$removelist $output_obj"
+ $ECHO "$srcfile" > "$lockfile"
+ fi
+
+ $opt_dry_run || $RM $removelist
+ removelist="$removelist $lockfile"
+ trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+ func_quote_for_eval "$srcfile"
+ qsrcfile=$func_quote_for_eval_result
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ command="$base_compile $qsrcfile $pic_flag"
+ else
+ # Don't build PIC code
+ command="$base_compile $qsrcfile"
+ fi
+
+ func_mkdir_p "$xdir$objdir"
+
+ if test -z "$output_obj"; then
+ # Place PIC objects in $objdir
+ command="$command -o $lobj"
+ fi
+
+ func_show_eval_locale "$command" \
+ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+ func_show_eval '$MV "$output_obj" "$lobj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+
+ # Allow error messages only from the first compilation.
+ if test "$suppress_opt" = yes; then
+ suppress_output=' >/dev/null 2>&1'
+ fi
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $qsrcfile$pie_flag"
+ else
+ command="$base_compile $qsrcfile $pic_flag"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ func_show_eval_locale "$command" \
+ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+ if test "$need_locks" = warn &&
+ test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+ $ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $opt_dry_run || $RM $removelist
+ exit $EXIT_FAILURE
+ fi
+
+ # Just move the object if needed
+ if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+ func_show_eval '$MV "$output_obj" "$obj"' \
+ 'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+ fi
+ fi
+
+ $opt_dry_run || {
+ func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ removelist=$lockfile
+ $RM "$lockfile"
+ fi
+ }
+
+ exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+ # We need to display help for each of the modes.
+ case $mode in
+ "")
+ # Generic help is extracted from the usage comments
+ # at the start of this file.
+ func_help
+ ;;
+
+ clean)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ compile)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -no-suppress do not suppress compiler output for multiple passes
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -shared do not build a \`.o' file suitable for static linking
+ -static only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+ execute)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+ finish)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+ install)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+ -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+ link)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -objectlist FILE Use a list of object files found in FILE to specify objects
+ -precious-files-regex REGEX
+ don't remove output files matching REGEX
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -shared only do dynamic linking of libtool libraries
+ -shrext SUFFIX override the standard shared library file extension
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+ -weak LIBNAME declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+ uninstall)
+ $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+ *)
+ func_fatal_help "invalid operation mode \`$mode'"
+ ;;
+ esac
+
+ $ECHO
+ $ECHO "Try \`$progname --help' for more information about other modes."
+
+ exit $?
+}
+
+ # Now that we've collected a possible --mode arg, show help if necessary
+ $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+ $opt_debug
+ # The first argument is the command name.
+ cmd="$nonopt"
+ test -z "$cmd" && \
+ func_fatal_help "you must specify a COMMAND"
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ test -f "$file" \
+ || func_fatal_help "\`$file' is not a file"
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+ func_source "$file"
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && \
+ func_warning "\`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ if test ! -f "$dir/$dlname"; then
+ func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+ fi
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ ;;
+
+ *)
+ func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if func_ltwrapper_script_p "$file"; then
+ func_source "$file"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ elif func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ func_source "$func_ltwrapper_scriptname_result"
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ func_quote_for_eval "$file"
+ args="$args $func_quote_for_eval_result"
+ done
+
+ if test "X$opt_dry_run" = Xfalse; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved environment variables
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ else
+ $lt_unset $lt_var
+ fi"
+ done
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+ $ECHO "export $shlibpath_var"
+ fi
+ $ECHO "$cmd$args"
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+ $opt_debug
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ $opt_silent && exit $EXIT_SUCCESS
+
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ $ECHO "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ $ECHO " $libdir"
+ done
+ $ECHO
+ $ECHO "If you ever happen to want to link against installed libraries"
+ $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+ $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ $ECHO "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ $ECHO " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ $ECHO " - add LIBDIR to the \`$runpath_var' environment variable"
+ $ECHO " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ $ECHO " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ $ECHO " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ $ECHO
+
+ $ECHO "See any operating system documentation about shared libraries for"
+ case $host in
+ solaris2.[6789]|solaris2.1[0-9])
+ $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+ $ECHO "pages."
+ ;;
+ *)
+ $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+ ;;
+ esac
+ $ECHO "X----------------------------------------------------------------------" | $Xsed
+ exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+ $opt_debug
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+ # Aesthetically quote it.
+ func_quote_for_eval "$nonopt"
+ install_prog="$func_quote_for_eval_result "
+ arg=$1
+ shift
+ else
+ install_prog=
+ arg=$nonopt
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog$func_quote_for_eval_result"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest=$arg
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f)
+ case " $install_prog " in
+ *[\\\ /]cp\ *) ;;
+ *) prev=$arg ;;
+ esac
+ ;;
+ -g | -m | -o)
+ prev=$arg
+ ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*)
+ ;;
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest=$arg
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ func_quote_for_eval "$arg"
+ install_prog="$install_prog $func_quote_for_eval_result"
+ done
+
+ test -z "$install_prog" && \
+ func_fatal_help "you must specify an install program"
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prev' option requires an argument"
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ func_fatal_help "no file or destination specified"
+ else
+ func_fatal_help "you must specify a destination"
+ fi
+ fi
+
+ # Strip any trailing slash from the destination.
+ func_stripname '' '/' "$dest"
+ dest=$func_stripname_result
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ func_dirname_and_basename "$dest" "" "."
+ destdir="$func_dirname_result"
+ destname="$func_basename_result"
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files; shift
+ test "$#" -gt 1 && \
+ func_fatal_help "\`$dest' is not a directory"
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ func_fatal_help "\`$destdir' must be an absolute directory name"
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$file" \
+ || func_fatal_help "\`$file' is not a valid libtool archive"
+
+ library_names=
+ old_library=
+ relink_command=
+ func_source "$file"
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ func_dirname "$file" "/" ""
+ dir="$func_dirname_result"
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ # Determine the prefix the user has applied to our future dir.
+ inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+ # Don't allow the user to place us outside of our expected
+ # location b/c this prevents finding dependent libraries that
+ # are installed to the same prefix.
+ # At present, this check doesn't affect windows .dll's that
+ # are installed into $libdir/../bin (currently, that works fine)
+ # but it's something to keep an eye on.
+ test "$inst_prefix_dir" = "$destdir" && \
+ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+ if test -n "$inst_prefix_dir"; then
+ # Stick the inst_prefix_dir data into the link command.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ else
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+ fi
+
+ func_warning "relinking \`$file'"
+ func_show_eval "$relink_command" \
+ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names; shift
+ if test -n "$1"; then
+ realname="$1"
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+ 'exit $?'
+ tstripme="$stripme"
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ case $realname in
+ *.dll.a)
+ tstripme=""
+ ;;
+ esac
+ ;;
+ esac
+ if test -n "$tstripme" && test -n "$striplib"; then
+ func_show_eval "$striplib $destdir/$realname" 'exit $?'
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ # Try `ln -sf' first, because the `ln' binary might depend on
+ # the symlink we replace! Solaris /bin/ln does not understand -f,
+ # so we also need to try rm && ln -s.
+ for linkname
+ do
+ test "$linkname" != "$realname" \
+ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ func_execute_cmds "$postinstall_cmds" 'exit $?'
+ fi
+
+ # Install the pseudo-library for information purposes.
+ func_basename "$file"
+ name="$func_basename_result"
+ instname="$dir/$name"i
+ func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ func_lo2o "$destfile"
+ staticdest=$func_lo2o_result
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ func_fatal_help "cannot copy a libtool object to \`$destfile'"
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ test -n "$destfile" && \
+ func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ func_lo2o "$file"
+ staticobj=$func_lo2o_result
+ func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+ fi
+ exit $EXIT_SUCCESS
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ func_basename "$file"
+ destfile="$func_basename_result"
+ destfile="$destdir/$destfile"
+ fi
+
+ # If the file is missing, and there is a .exe on the end, strip it
+ # because it is most likely a libtool script we actually want to
+ # install
+ stripped_ext=""
+ case $file in
+ *.exe)
+ if test ! -f "$file"; then
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ stripped_ext=".exe"
+ fi
+ ;;
+ esac
+
+ # Do a test to see if this is really a libtool program.
+ case $host in
+ *cygwin* | *mingw*)
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ wrapper=$func_ltwrapper_scriptname_result
+ else
+ func_stripname '' '.exe' "$file"
+ wrapper=$func_stripname_result
+ fi
+ ;;
+ *)
+ wrapper=$file
+ ;;
+ esac
+ if func_ltwrapper_script_p "$wrapper"; then
+ notinst_deplibs=
+ relink_command=
+
+ func_source "$wrapper"
+
+ # Check the variables that should have been set.
+ test -z "$generated_by_libtool_version" && \
+ func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ func_source "$lib"
+ fi
+ libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ func_warning "\`$lib' has not been installed in \`$libdir'"
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ func_source "$wrapper"
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ $opt_dry_run || {
+ if test "$finalize" = yes; then
+ tmpdir=`func_mktempdir`
+ func_basename "$file$stripped_ext"
+ file="$func_basename_result"
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $opt_silent || {
+ func_quote_for_expand "$relink_command"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ if eval "$relink_command"; then :
+ else
+ func_error "error: relink \`$file' with the above command before installing it"
+ $opt_dry_run || ${RM}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ func_warning "cannot relink \`$file'"
+ fi
+ }
+ else
+ # Install the binary that we compiled earlier.
+ file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyway
+ case $install_prog,$host in
+ */usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ func_stripname '' '.exe' "$destfile"
+ destfile=$func_stripname_result
+ ;;
+ esac
+ ;;
+ esac
+ func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+ $opt_dry_run || if test -n "$outputname"; then
+ ${RM}r "$tmpdir"
+ fi
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ func_basename "$file"
+ name="$func_basename_result"
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+ if test -n "$stripme" && test -n "$old_striplib"; then
+ func_show_eval "$old_striplib $oldlib" 'exit $?'
+ fi
+
+ # Do each command in the postinstall commands.
+ func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+ done
+
+ test -n "$future_libdirs" && \
+ func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ $opt_dry_run && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+ else
+ exit $EXIT_SUCCESS
+ fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+ $opt_debug
+ my_outputname="$1"
+ my_originator="$2"
+ my_pic_p="${3-no}"
+ my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+ my_dlsyms=
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ my_dlsyms="${my_outputname}S.c"
+ else
+ func_error "not configured to extract global symbols from dlpreopened files"
+ fi
+ fi
+
+ if test -n "$my_dlsyms"; then
+ case $my_dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${my_outputname}.nm"
+
+ func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+ # Parse the name list into a source file.
+ func_verbose "creating $output_objdir/$my_dlsyms"
+
+ $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ func_verbose "generating symbol list for \`$output'"
+
+ $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for progfile in $progfiles; do
+ func_verbose "extracting global C symbols from \`$progfile'"
+ $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $opt_dry_run || {
+ eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $opt_dry_run || {
+ eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ }
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$outputname.exp"
+ $opt_dry_run || {
+ $RM $export_symbols
+ eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ else
+ $opt_dry_run || {
+ eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+ eval '$MV "$nlist"T "$nlist"'
+ case $host in
+ *cygwin | *mingw* | *cegcc* )
+ eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+ eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+ ;;
+ esac
+ }
+ fi
+ fi
+
+ for dlprefile in $dlprefiles; do
+ func_verbose "extracting global C symbols from \`$dlprefile'"
+ func_basename "$dlprefile"
+ name="$func_basename_result"
+ $opt_dry_run || {
+ eval '$ECHO ": $name " >> "$nlist"'
+ eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+ }
+ done
+
+ $opt_dry_run || {
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $MV "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if $GREP -v "^: " < "$nlist" |
+ if sort -k 3 </dev/null >/dev/null 2>&1; then
+ sort -k 3
+ else
+ sort +2
+ fi |
+ uniq > "$nlist"S; then
+ :
+ else
+ $GREP -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+ else
+ $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+ fi
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols. */
+typedef struct {
+ const char *name;
+ void *address;
+} lt_dlsymlist;
+"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+ runtime relocations are performed -- see ld's documentation
+ on pseudo-relocs. */"
+ lt_dlsym_const= ;;
+ *osf5*)
+ echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+ lt_dlsym_const= ;;
+ *)
+ lt_dlsym_const=const ;;
+ esac
+
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+ { \"$my_originator\", (void *) 0 },"
+
+ case $need_lib_prefix in
+ no)
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ *)
+ eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+ ;;
+ esac
+ $ECHO >> "$output_objdir/$my_dlsyms" "\
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ } # !$opt_dry_run
+
+ pic_flag_for_symtable=
+ case "$compile_command " in
+ *" -static "*) ;;
+ *)
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+ *-*-hpux*)
+ pic_flag_for_symtable=" $pic_flag" ;;
+ *)
+ if test "X$my_pic_p" != Xno; then
+ pic_flag_for_symtable=" $pic_flag"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ symtab_cflags=
+ for arg in $LTCFLAGS; do
+ case $arg in
+ -pie | -fpie | -fPIE) ;;
+ *) symtab_cflags="$symtab_cflags $arg" ;;
+ esac
+ done
+
+ # Now compile the dynamic symbol file.
+ func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+ # Clean up the generated files.
+ func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+ # Transform the symbol file into the correct name.
+ symfileobj="$output_objdir/${my_outputname}S.$objext"
+ case $host in
+ *cygwin* | *mingw* | *cegcc* )
+ if test -f "$output_objdir/$my_outputname.def"; then
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+ else
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ fi
+ ;;
+ *)
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+ ;;
+ esac
+ ;;
+ *)
+ func_fatal_error "unknown suffix for \`$my_dlsyms'"
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+ $opt_debug
+ win32_libid_type="unknown"
+ win32_fileres=`file -L $1 2>/dev/null`
+ case $win32_fileres in
+ *ar\ archive\ import\ library*) # definitely import
+ win32_libid_type="x86 archive import"
+ ;;
+ *ar\ archive*) # could be an import, or static
+ if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+ $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+ win32_nmres=`eval $NM -f posix -A $1 |
+ $SED -n -e '
+ 1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
+ case $win32_nmres in
+ import*) win32_libid_type="x86 archive import";;
+ *) win32_libid_type="x86 archive static";;
+ esac
+ fi
+ ;;
+ *DLL*)
+ win32_libid_type="x86 DLL"
+ ;;
+ *executable*) # but shell scripts are "executable" too...
+ case $win32_fileres in
+ *MS\ Windows\ PE\ Intel*)
+ win32_libid_type="x86 DLL"
+ ;;
+ esac
+ ;;
+ esac
+ $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+ $opt_debug
+ f_ex_an_ar_dir="$1"; shift
+ f_ex_an_ar_oldlib="$1"
+ func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+ if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+ fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+ $opt_debug
+ my_gentop="$1"; shift
+ my_oldlibs=${1+"$@"}
+ my_oldobjs=""
+ my_xlib=""
+ my_xabs=""
+ my_xdir=""
+
+ for my_xlib in $my_oldlibs; do
+ # Extract the objects.
+ case $my_xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+ *) my_xabs=`pwd`"/$my_xlib" ;;
+ esac
+ func_basename "$my_xlib"
+ my_xlib="$func_basename_result"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ func_arith $extracted_serial + 1
+ extracted_serial=$func_arith_result
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
+
+ func_mkdir_p "$my_xdir"
+
+ case $host in
+ *-darwin*)
+ func_verbose "Extracting $my_xabs"
+ # Do not bother doing anything if just a dry run
+ $opt_dry_run || {
+ darwin_orig_dir=`pwd`
+ cd $my_xdir || exit $?
+ darwin_archive=$my_xabs
+ darwin_curdir=`pwd`
+ darwin_base_archive=`basename "$darwin_archive"`
+ darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+ if test -n "$darwin_arches"; then
+ darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+ darwin_arch=
+ func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+ for darwin_arch in $darwin_arches ; do
+ func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+ cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+ func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+ cd "$darwin_curdir"
+ $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+ done # $darwin_arches
+ ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+ darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+ darwin_file=
+ darwin_files=
+ for darwin_file in $darwin_filelist; do
+ darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+ $LIPO -create -output "$darwin_file" $darwin_files
+ done # $darwin_filelist
+ $RM -rf unfat-$$
+ cd "$darwin_orig_dir"
+ else
+ cd $darwin_orig_dir
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ fi # $darwin_arches
+ } # !$opt_dry_run
+ ;;
+ *)
+ func_extract_an_archive "$my_xdir" "$my_xabs"
+ ;;
+ esac
+ my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+ done
+
+ func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+ func_emit_wrapper_part1_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part1_arg1=$1
+ fi
+
+ $ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# Be Bourne compatible
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ generated_by_libtool_version='$macro_version'
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$ECHO are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ ECHO=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$ECHO works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$ECHO will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $ECHO "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+ done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+ func_emit_wrapper_part2_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_part2_arg1=$1
+ fi
+
+ $ECHO "\
+
+ # Usually 'no', except on cygwin/mingw when embedded into
+ # the cwrapper.
+ WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+ if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+ # special case for '.'
+ if test \"\$thisdir\" = \".\"; then
+ thisdir=\`pwd\`
+ fi
+ # remove .libs from thisdir
+ case \"\$thisdir\" in
+ *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+ $objdir ) thisdir=. ;;
+ esac
+ fi
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ $ECHO "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" ||
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $MKDIR \"\$progdir\"
+ else
+ $RM \"\$progdir/\$file\"
+ fi"
+
+ $ECHO "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $ECHO \"\$relink_command_output\" >&2
+ $RM \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $RM \"\$progdir/\$program\";
+ $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $RM \"\$progdir/\$file\"
+ fi"
+ else
+ $ECHO "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ $ECHO "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $ECHO "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $ECHO "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $ECHO "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2* | *-cegcc*)
+ $ECHO "\
+ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $ECHO "\
+ exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $ECHO "\
+ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+ \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+ $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable. Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take. If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory. This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+ func_emit_wrapper_arg1=no
+ if test -n "$1" ; then
+ func_emit_wrapper_arg1=$1
+ fi
+
+ # split this up so that func_emit_cwrapperexe_src
+ # can call each part independently.
+ func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+ func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin. Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+ func_to_host_path_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ case $build in
+ *mingw* ) # actually, msys
+ # awkward: cmd appends spaces to result
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_path_tmp1=`cygpath -w "$1"`
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # Unfortunately, winepath does not exit with a non-zero
+ # error code, so we are forced to check the contents of
+ # stdout. On the other hand, if the command is not
+ # found, the shell will set an exit code of 127 and print
+ # *an error message* to stdout. So we must check for both
+ # error code of zero AND non-empty stdout, which explains
+ # the odd construction:
+ func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+ if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+ func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ else
+ # Allow warning below.
+ func_to_host_path_result=""
+ fi
+ ;;
+ esac
+ if test -z "$func_to_host_path_result" ; then
+ func_error "Could not determine host path corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback:
+ func_to_host_path_result="$1"
+ fi
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+# $build $host
+# mingw (msys) mingw [e.g. native]
+# cygwin mingw
+# *nix + wine mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+ func_to_host_pathlist_result="$1"
+ if test -n "$1" ; then
+ case $host in
+ *mingw* )
+ lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+ # Remove leading and trailing path separator characters from
+ # ARG. msys behavior is inconsistent here, cygpath turns them
+ # into '.;' and ';.', and winepath ignores them completely.
+ func_to_host_pathlist_tmp2="$1"
+ # Once set for this call, this variable should not be
+ # reassigned. It is used in tha fallback case.
+ func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e 's|^:*||' -e 's|:*$||'`
+ case $build in
+ *mingw* ) # Actually, msys.
+ # Awkward: cmd appends spaces to result.
+ lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+ func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ *cygwin* )
+ func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+ $SED -e "$lt_sed_naive_backslashify"`
+ ;;
+ * )
+ # unfortunately, winepath doesn't convert pathlists
+ func_to_host_pathlist_result=""
+ func_to_host_pathlist_oldIFS=$IFS
+ IFS=:
+ for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+ IFS=$func_to_host_pathlist_oldIFS
+ if test -n "$func_to_host_pathlist_f" ; then
+ func_to_host_path "$func_to_host_pathlist_f"
+ if test -n "$func_to_host_path_result" ; then
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_to_host_pathlist_result="$func_to_host_path_result"
+ else
+ func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+ fi
+ fi
+ fi
+ IFS=:
+ done
+ IFS=$func_to_host_pathlist_oldIFS
+ ;;
+ esac
+ if test -z "$func_to_host_pathlist_result" ; then
+ func_error "Could not determine the host path(s) corresponding to"
+ func_error " '$1'"
+ func_error "Continuing, but uninstalled executables may not work."
+ # Fallback. This may break if $1 contains DOS-style drive
+ # specifications. The fix is not to complicate the expression
+ # below, but for the user to provide a working wine installation
+ # with winepath so that path translation in the cross-to-mingw
+ # case works properly.
+ lt_replace_pathsep_nix_to_dos="s|:|;|g"
+ func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+ $SED -e "$lt_replace_pathsep_nix_to_dos"`
+ fi
+ # Now, add the leading and trailing path separators back
+ case "$1" in
+ :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+ ;;
+ esac
+ case "$1" in
+ *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+ cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+ Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+ The $output program cannot be directly executed until all the libtool
+ libraries that it depends on are installed.
+
+ This wrapper executable should never be moved out of the build directory.
+ If it is, it will not operate correctly.
+
+ Currently, it simply execs the wrapper *script* "$SHELL $output",
+ but could eventually absorb all of the scripts functionality and
+ exec $objdir/$outputname directly.
+*/
+EOF
+ cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+# include <io.h>
+# define HAVE_SETENV
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+# define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+ defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+# define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+# define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+ if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ (void) vfprintf (stderr, fmt, args);
+ va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+ func_emit_wrapper_part1 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+ cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+ func_emit_wrapper_part2 yes |
+ $SED -e 's/\([\\"]\)/\\\1/g' \
+ -e 's/^/ "/' -e 's/$/\\n"/'
+ echo ";"
+
+ cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ func_to_host_pathlist "$temp_rpath"
+ cat <<EOF
+const char * LIB_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * LIB_PATH_VALUE = "";
+EOF
+ fi
+
+ if test -n "$dllsearchpath"; then
+ func_to_host_pathlist "$dllsearchpath:"
+ cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE = "$func_to_host_pathlist_result";
+EOF
+ else
+ cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE = "";
+EOF
+ fi
+
+ if test "$fast_install" = yes; then
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+ else
+ cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+ fi
+
+
+ cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH 5
+
+static const size_t opt_prefix_len = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt = LTWRAPPER_OPTION_PREFIX "env-set";
+ /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt = LTWRAPPER_OPTION_PREFIX "env-prepend";
+ /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt = LTWRAPPER_OPTION_PREFIX "env-append";
+ /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+ char **newargz;
+ int newargc;
+ char *tmp_pathspec;
+ char *actual_cwrapper_path;
+ char *actual_cwrapper_name;
+ char *target_name;
+ char *lt_argv_zero;
+ intptr_t rval = 127;
+
+ int i;
+
+ program_name = (char *) xstrdup (base_name (argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) argv[0] : %s\n", argv[0]));
+ LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+ /* very simple arg parsing; don't want to rely on getopt */
+ for (i = 1; i < argc; i++)
+ {
+ if (strcmp (argv[i], dumpscript_opt) == 0)
+ {
+EOF
+ case "$host" in
+ *mingw* | *cygwin* )
+ # make stdout use "unix" line endings
+ echo " setmode(1,_O_BINARY);"
+ ;;
+ esac
+
+ cat <<"EOF"
+ printf ("%s", script_text_part1);
+ printf ("%s", script_text_part2);
+ return 0;
+ }
+ }
+
+ newargz = XMALLOC (char *, argc + 1);
+ tmp_pathspec = find_executable (argv[0]);
+ if (tmp_pathspec == NULL)
+ lt_fatal ("Couldn't find %s", argv[0]);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+ tmp_pathspec));
+
+ actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+ LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+ actual_cwrapper_path));
+ XFREE (tmp_pathspec);
+
+ actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+ strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+ /* wrapper name transforms */
+ strendzap (actual_cwrapper_name, ".exe");
+ tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+ XFREE (actual_cwrapper_name);
+ actual_cwrapper_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ /* target_name transforms -- use actual target program name; might have lt- prefix */
+ target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+ strendzap (target_name, ".exe");
+ tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+ XFREE (target_name);
+ target_name = tmp_pathspec;
+ tmp_pathspec = 0;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+ target_name));
+EOF
+
+ cat <<EOF
+ newargz[0] =
+ XMALLOC (char, (strlen (actual_cwrapper_path) +
+ strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+ strcpy (newargz[0], actual_cwrapper_path);
+ strcat (newargz[0], "$objdir");
+ strcat (newargz[0], "/");
+EOF
+
+ cat <<"EOF"
+ /* stop here, and copy so we don't have to do this twice */
+ tmp_pathspec = xstrdup (newargz[0]);
+
+ /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+ strcat (newargz[0], actual_cwrapper_name);
+
+ /* DO want the lt- prefix here if it exists, so use target_name */
+ lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+ XFREE (tmp_pathspec);
+ tmp_pathspec = NULL;
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ {
+ char* p;
+ while ((p = strchr (newargz[0], '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+ {
+ *p = '/';
+ }
+ }
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+ XFREE (target_name);
+ XFREE (actual_cwrapper_path);
+ XFREE (actual_cwrapper_name);
+
+ lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+ lt_setenv ("DUALCASE", "1"); /* for MSK sh */
+ lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+ lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+ newargc=0;
+ for (i = 1; i < argc; i++)
+ {
+ if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+ {
+ if (argv[i][env_set_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_set_opt_len + 1;
+ lt_opt_process_env_set (p);
+ }
+ else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_set (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_set_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+ {
+ if (argv[i][env_prepend_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_prepend_opt_len + 1;
+ lt_opt_process_env_prepend (p);
+ }
+ else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_prepend_opt);
+ continue;
+ }
+ if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+ {
+ if (argv[i][env_append_opt_len] == '=')
+ {
+ const char *p = argv[i] + env_append_opt_len + 1;
+ lt_opt_process_env_append (p);
+ }
+ else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+ {
+ lt_opt_process_env_append (argv[++i]); /* don't copy */
+ }
+ else
+ lt_fatal ("%s missing required argument", env_append_opt);
+ continue;
+ }
+ if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+ {
+ /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+ namespace, but it is not one of the ones we know about and
+ have already dealt with, above (inluding dump-script), then
+ report an error. Otherwise, targets might begin to believe
+ they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+ namespace. The first time any user complains about this, we'll
+ need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+ or a configure.ac-settable value.
+ */
+ lt_fatal ("Unrecognized option in %s namespace: '%s'",
+ ltwrapper_option_prefix, argv[i]);
+ }
+ /* otherwise ... */
+ newargz[++newargc] = xstrdup (argv[i]);
+ }
+ newargz[++newargc] = NULL;
+
+ LTWRAPPER_DEBUGPRINTF (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+ for (i = 0; i < newargc; i++)
+ {
+ LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+ }
+
+EOF
+
+ case $host_os in
+ mingw*)
+ cat <<"EOF"
+ /* execv doesn't actually work on mingw as expected on unix */
+ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+ if (rval == -1)
+ {
+ /* failed to start process */
+ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+ return 127;
+ }
+ return rval;
+EOF
+ ;;
+ *)
+ cat <<"EOF"
+ execv (lt_argv_zero, newargz);
+ return rval; /* =127, but avoids unused variable warning */
+EOF
+ ;;
+ esac
+
+ cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+ void *p = (void *) malloc (num);
+ if (!p)
+ lt_fatal ("Memory exhausted");
+
+ return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+ return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+ string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+ const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ /* Skip over the disk name in MSDOS pathnames. */
+ if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+ name += 2;
+#endif
+
+ for (base = name; *name; name++)
+ if (IS_DIR_SEPARATOR (*name))
+ base = name + 1;
+ return base;
+}
+
+int
+check_executable (const char *path)
+{
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if ((stat (path, &st) >= 0)
+ && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+ return 1;
+ else
+ return 0;
+}
+
+int
+make_executable (const char *path)
+{
+ int rval = 0;
+ struct stat st;
+
+ LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n",
+ path ? (*path ? path : "EMPTY!") : "NULL!"));
+ if ((!path) || (!*path))
+ return 0;
+
+ if (stat (path, &st) >= 0)
+ {
+ rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+ }
+ return rval;
+}
+
+/* Searches for the full path of the wrapper. Returns
+ newly allocated full path name if found, NULL otherwise
+ Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+ int has_slash = 0;
+ const char *p;
+ const char *p_next;
+ /* static buffer for getcwd */
+ char tmp[LT_PATHMAX + 1];
+ int tmp_len;
+ char *concat_name;
+
+ LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n",
+ wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+ if ((wrapper == NULL) || (*wrapper == '\0'))
+ return NULL;
+
+ /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ else
+ {
+#endif
+ if (IS_DIR_SEPARATOR (wrapper[0]))
+ {
+ concat_name = xstrdup (wrapper);
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+ }
+#endif
+
+ for (p = wrapper; *p; p++)
+ if (*p == '/')
+ {
+ has_slash = 1;
+ break;
+ }
+ if (!has_slash)
+ {
+ /* no slashes; search PATH */
+ const char *path = getenv ("PATH");
+ if (path != NULL)
+ {
+ for (p = path; *p; p = p_next)
+ {
+ const char *q;
+ size_t p_len;
+ for (q = p; *q; q++)
+ if (IS_PATH_SEPARATOR (*q))
+ break;
+ p_len = q - p;
+ p_next = (*q == '\0' ? q : q + 1);
+ if (p_len == 0)
+ {
+ /* empty path: current directory */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name =
+ XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+ }
+ else
+ {
+ concat_name =
+ XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, p, p_len);
+ concat_name[p_len] = '/';
+ strcpy (concat_name + p_len + 1, wrapper);
+ }
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ }
+ }
+ /* not found in PATH; assume curdir */
+ }
+ /* Relative path | not found in path: prepend cwd */
+ if (getcwd (tmp, LT_PATHMAX) == NULL)
+ lt_fatal ("getcwd failed");
+ tmp_len = strlen (tmp);
+ concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+ memcpy (concat_name, tmp, tmp_len);
+ concat_name[tmp_len] = '/';
+ strcpy (concat_name + tmp_len + 1, wrapper);
+
+ if (check_executable (concat_name))
+ return concat_name;
+ XFREE (concat_name);
+ return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+ return xstrdup (pathspec);
+#else
+ char buf[LT_PATHMAX];
+ struct stat s;
+ char *tmp_pathspec = xstrdup (pathspec);
+ char *p;
+ int has_symlinks = 0;
+ while (strlen (tmp_pathspec) && !has_symlinks)
+ {
+ LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+ tmp_pathspec));
+ if (lstat (tmp_pathspec, &s) == 0)
+ {
+ if (S_ISLNK (s.st_mode) != 0)
+ {
+ has_symlinks = 1;
+ break;
+ }
+
+ /* search backwards for last DIR_SEPARATOR */
+ p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+ while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ p--;
+ if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+ {
+ /* no more DIR_SEPARATORS left */
+ break;
+ }
+ *p = '\0';
+ }
+ else
+ {
+ char *errstr = strerror (errno);
+ lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+ }
+ }
+ XFREE (tmp_pathspec);
+
+ if (!has_symlinks)
+ {
+ return xstrdup (pathspec);
+ }
+
+ tmp_pathspec = realpath (pathspec, buf);
+ if (tmp_pathspec == 0)
+ {
+ lt_fatal ("Could not follow symlinks for %s", pathspec);
+ }
+ return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+ size_t len, patlen;
+
+ assert (str != NULL);
+ assert (pat != NULL);
+
+ len = strlen (str);
+ patlen = strlen (pat);
+
+ if (patlen <= len)
+ {
+ str += len - patlen;
+ if (strcmp (str, pat) == 0)
+ *str = '\0';
+ }
+ return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+ const char *message, va_list ap)
+{
+ fprintf (stderr, "%s: %s: ", program_name, mode);
+ vfprintf (stderr, message, ap);
+ fprintf (stderr, ".\n");
+
+ if (exit_status >= 0)
+ exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+ va_list ap;
+ va_start (ap, message);
+ lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+ va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+ {
+#ifdef HAVE_SETENV
+ /* always make a copy, for consistency with !HAVE_SETENV */
+ char *str = xstrdup (value);
+ setenv (name, str, 1);
+#else
+ int len = strlen (name) + 1 + strlen (value) + 1;
+ char *str = XMALLOC (char, len);
+ sprintf (str, "%s=%s", name, value);
+ if (putenv (str) != EXIT_SUCCESS)
+ {
+ XFREE (str);
+ }
+#endif
+ }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+ char *new_value;
+ if (orig_value && *orig_value)
+ {
+ int orig_value_len = strlen (orig_value);
+ int add_len = strlen (add);
+ new_value = XMALLOC (char, add_len + orig_value_len + 1);
+ if (to_end)
+ {
+ strcpy (new_value, orig_value);
+ strcpy (new_value + orig_value_len, add);
+ }
+ else
+ {
+ strcpy (new_value, add);
+ strcpy (new_value + add_len, orig_value);
+ }
+ }
+ else
+ {
+ new_value = xstrdup (add);
+ }
+ return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+ const char *p;
+ int len;
+ if (!arg || !*arg)
+ return 1;
+
+ p = strchr (arg, (int)'=');
+
+ if (!p)
+ return 1;
+
+ *value = xstrdup (++p);
+
+ len = strlen (arg) - strlen (*value);
+ *name = XMALLOC (char, len);
+ strncpy (*name, arg, len-1);
+ (*name)[len - 1] = '\0';
+
+ return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+ }
+
+ lt_setenv (name, value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+ char *name = NULL;
+ char *value = NULL;
+ char *new_value = NULL;
+
+ if (lt_split_name_value (arg, &name, &value) != 0)
+ {
+ XFREE (name);
+ XFREE (value);
+ lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+ }
+
+ new_value = lt_extend_str (getenv (name), value, 1);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ XFREE (name);
+ XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ /* some systems can't cope with a ':'-terminated path #' */
+ int len = strlen (new_value);
+ while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+ {
+ new_value[len-1] = '\0';
+ }
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+ LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+ (name ? name : "<NULL>"),
+ (value ? value : "<NULL>")));
+
+ if (name && *name && value && *value)
+ {
+ char *new_value = lt_extend_str (getenv (name), value, 0);
+ lt_setenv (name, new_value);
+ XFREE (new_value);
+ }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+ $opt_debug
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invocation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args=$nonopt
+ base_compile="$nonopt $@"
+ compile_command=$nonopt
+ finalize_command=$nonopt
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+ inst_prefix_dir=
+ new_inherited_linker_flags=
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ non_pic_objects=
+ precious_files_regex=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+ vinfo_number=no
+ weak_libs=
+ single_module="${wl}-single_module"
+ func_infer_tag $base_compile
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -shared)
+ test "$build_libtool_libs" != yes && \
+ func_fatal_configuration "can not build a shared library"
+ build_old_libs=no
+ break
+ ;;
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ func_warning "complete static linking is impossible in this configuration"
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ -static)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=built
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test "$#" -gt 0; do
+ arg="$1"
+ shift
+ func_quote_for_eval "$arg"
+ qarg=$func_quote_for_eval_unquoted_result
+ func_append libtool_args " $func_quote_for_eval_result"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ func_append compile_command " @OUTPUT@"
+ func_append finalize_command " @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ func_append compile_command " @SYMFILE@"
+ func_append finalize_command " @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ test -f "$arg" \
+ || func_fatal_error "symbol file \`$arg' does not exist"
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ framework)
+ case $host in
+ *-*-darwin*)
+ case "$deplibs " in
+ *" $qarg.ltframework "*) ;;
+ *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+ ;;
+ esac
+ ;;
+ esac
+ prev=
+ continue
+ ;;
+ inst_prefix)
+ inst_prefix_dir="$arg"
+ prev=
+ continue
+ ;;
+ objectlist)
+ if test -f "$arg"; then
+ save_arg=$arg
+ moreargs=
+ for fil in `cat "$save_arg"`
+ do
+# moreargs="$moreargs $fil"
+ arg=$fil
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ done
+ else
+ func_fatal_error "link input file \`$arg' does not exist"
+ fi
+ arg=$save_arg
+ prev=
+ continue
+ ;;
+ precious_regex)
+ precious_files_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ shrext)
+ shrext_cmds="$arg"
+ prev=
+ continue
+ ;;
+ weak)
+ weak_libs="$weak_libs $arg"
+ prev=
+ continue
+ ;;
+ xcclinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ func_append compile_command " $qarg"
+ func_append finalize_command " $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ func_append compile_command " $wl$qarg"
+ func_append finalize_command " $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n "$prev"
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ # See comment for -static flag below, for more details.
+ func_append compile_command " $link_static_flag"
+ func_append finalize_command " $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ func_fatal_error "more than one -exported-symbols argument is not allowed"
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -framework)
+ prev=framework
+ continue
+ ;;
+
+ -inst-prefix-dir)
+ prev=inst_prefix
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix* | /*-*-irix*)
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ func_stripname '-L' '' "$arg"
+ dir=$func_stripname_result
+ if test -z "$dir"; then
+ if test "$#" -gt 0; then
+ func_fatal_error "require no space between \`-L' and \`$1'"
+ else
+ func_fatal_error "need path for \`-L' option"
+ fi
+ fi
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ test -z "$absdir" && \
+ func_fatal_error "cannot determine absolute directory name of \`$dir'"
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ ::) dllsearchpath=$dir;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C and math libraries are in the System framework
+ deplibs="$deplibs System.ltframework"
+ continue
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ # Tru64 UNIX uses -model [arg] to determine the layout of C++
+ # classes, name mangling, and exception handling.
+ # Darwin uses the -arch flag to determine output architecture.
+ -model|-arch|-isysroot)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ prev=xcompiler
+ continue
+ ;;
+
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ compiler_flags="$compiler_flags $arg"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ case "$new_inherited_linker_flags " in
+ *" $arg "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+ esac
+ continue
+ ;;
+
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # and Darwin in order for the loader to find any dlls it needs.
+ func_warning "\`-no-install' is ignored for $host"
+ func_warning "assuming \`-no-fast-install' instead"
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -objectlist)
+ prev=objectlist
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -precious-files-regex)
+ prev=precious_regex
+ continue
+ ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ func_stripname '-R' '' "$arg"
+ dir=$func_stripname_result
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ func_fatal_error "only absolute run-paths are allowed"
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -shared)
+ # The effects of -shared are defined in a previous loop.
+ continue
+ ;;
+
+ -shrext)
+ prev=shrext
+ continue
+ ;;
+
+ -static | -static-libtool-libs)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -version-number)
+ prev=vinfo
+ vinfo_number=yes
+ continue
+ ;;
+
+ -weak)
+ prev=weak
+ continue
+ ;;
+
+ -Wc,*)
+ func_stripname '-Wc,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Wl,*)
+ func_stripname '-Wl,' '' "$arg"
+ args=$func_stripname_result
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ func_quote_for_eval "$flag"
+ arg="$arg $wl$func_quote_for_eval_result"
+ compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+ linker_flags="$linker_flags $func_quote_for_eval_result"
+ done
+ IFS="$save_ifs"
+ func_stripname ' ' '' "$arg"
+ arg=$func_stripname_result
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ -XCClinker)
+ prev=xcclinker
+ continue
+ ;;
+
+ # -msg_* for osf cc
+ -msg_*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+ # -r[0-9][0-9]* specifies the processor on the SGI compiler
+ # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+ # +DA*, +DD* enable 64-bit mode on the HP compiler
+ # -q* pass through compiler args for the IBM compiler
+ # -m*, -t[45]*, -txscale* pass through architecture-specific
+ # compiler args for GCC
+ # -F/path gives path to uninstalled frameworks, gcc on darwin
+ # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+ # @file GCC response files
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ compiler_flags="$compiler_flags $arg"
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+
+ *.$objext)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A libtool-controlled object.
+
+ # Check to see that this really is a libtool object.
+ if func_lalib_unsafe_p "$arg"; then
+ pic_object=
+ non_pic_object=
+
+ # Read the .lo file
+ func_source "$arg"
+
+ if test -z "$pic_object" ||
+ test -z "$non_pic_object" ||
+ test "$pic_object" = none &&
+ test "$non_pic_object" = none; then
+ func_fatal_error "cannot find name of object for \`$arg'"
+ fi
+
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ if test "$pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ pic_object="$xdir$pic_object"
+
+ if test "$prev" = dlfiles; then
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $pic_object"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ # CHECK ME: I think I busted this. -Ossama
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles $pic_object"
+ prev=
+ fi
+
+ # A PIC object.
+ func_append libobjs " $pic_object"
+ arg="$pic_object"
+ fi
+
+ # Non-PIC object.
+ if test "$non_pic_object" != none; then
+ # Prepend the subdirectory the object is found in.
+ non_pic_object="$xdir$non_pic_object"
+
+ # A standard non-PIC object
+ func_append non_pic_objects " $non_pic_object"
+ if test -z "$pic_object" || test "$pic_object" = none ; then
+ arg="$non_pic_object"
+ fi
+ else
+ # If the PIC object exists, use it instead.
+ # $xdir was prepended to $pic_object above.
+ non_pic_object="$pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ fi
+ else
+ # Only an error if not doing a dry-run.
+ if $opt_dry_run; then
+ # Extract subdirectory from the argument.
+ func_dirname "$arg" "/" ""
+ xdir="$func_dirname_result"
+
+ func_lo2o "$arg"
+ pic_object=$xdir$objdir/$func_lo2o_result
+ non_pic_object=$xdir$func_lo2o_result
+ func_append libobjs " $pic_object"
+ func_append non_pic_objects " $non_pic_object"
+ else
+ func_fatal_error "\`$arg' is not a valid libtool object"
+ fi
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ func_quote_for_eval "$arg"
+ arg="$func_quote_for_eval_result"
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+ done # argument parsing loop
+
+ test -n "$prev" && \
+ func_fatal_help "the \`$prevarg' option requires an argument"
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ func_append compile_command " $arg"
+ func_append finalize_command " $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ func_basename "$output"
+ outputname="$func_basename_result"
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ func_dirname "$output" "/" ""
+ output_objdir="$func_dirname_result$objdir"
+ # Create the object directory.
+ func_mkdir_p "$output_objdir"
+
+ # Determine the type of output
+ case $output in
+ "")
+ func_fatal_help "you must specify an output file"
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ if $opt_duplicate_deps ; then
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ libs="$libs $deplib"
+ done
+
+ if test "$linkmode" = lib; then
+ libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+ # Compute libraries that are listed more than once in $predeps
+ # $postdeps and mark them as special (i.e., whose duplicates are
+ # not to be eliminated).
+ pre_post_deps=
+ if $opt_duplicate_compiler_generated_deps; then
+ for pre_post_dep in $predeps $postdeps; do
+ case "$pre_post_deps " in
+ *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+ esac
+ pre_post_deps="$pre_post_deps $pre_post_dep"
+ done
+ fi
+ pre_post_deps=
+ fi
+
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+
+ case $linkmode in
+ lib)
+ passes="conv dlpreopen link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+
+ for pass in $passes; do
+ # The preopen pass in lib mode reverses $deplibs; put it back here
+ # so that -L comes before libs that need it for instance...
+ if test "$linkmode,$pass" = "lib,link"; then
+ ## FIXME: Find the place where the list is rebuilt in the wrong
+ ## order, and fix it there properly
+ tmp_deplibs=
+ for deplib in $deplibs; do
+ tmp_deplibs="$deplib $tmp_deplibs"
+ done
+ deplibs="$tmp_deplibs"
+ fi
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan"; then
+ libs="$deplibs"
+ deplibs=
+ fi
+ if test "$linkmode" = prog; then
+ case $pass in
+ dlopen) libs="$dlfiles" ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link)
+ libs="$deplibs %DEPLIBS%"
+ test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs"
+ ;;
+ esac
+ fi
+ if test "$linkmode,$pass" = "lib,dlpreopen"; then
+ # Collect and forward deplibs of preopened libtool libs
+ for lib in $dlprefiles; do
+ # Ignore non-libtool-libs
+ dependency_libs=
+ case $lib in
+ *.la) func_source "$lib" ;;
+ esac
+
+ # Collect preopened libtool deplibs, except any this library
+ # has declared as weak libs
+ for deplib in $dependency_libs; do
+ deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+ case " $weak_libs " in
+ *" $deplib_base "*) ;;
+ *) deplibs="$deplibs $deplib" ;;
+ esac
+ done
+ done
+ libs="$dlprefiles"
+ fi
+ if test "$pass" = dlopen; then
+ # Collect dlpreopened libraries
+ save_deplibs="$deplibs"
+ deplibs=
+ fi
+
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags $deplib"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -l*)
+ if test "$linkmode" != lib && test "$linkmode" != prog; then
+ func_warning "\`-l' is ignored for archives/objects"
+ continue
+ fi
+ func_stripname '-l' '' "$deplib"
+ name=$func_stripname_result
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
+ for search_ext in .la $std_shrext .so .a; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}${search_ext}"
+ if test -f "$lib"; then
+ if test "$search_ext" = ".la"; then
+ found=yes
+ else
+ found=no
+ fi
+ break 2
+ fi
+ done
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ else # deplib is a libtool library
+ # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+ # We need to do some special things here, and not later.
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $deplib "*)
+ if func_lalib_p "$lib"; then
+ library_names=
+ old_library=
+ func_source "$lib"
+ for l in $old_library $library_names; do
+ ll="$l"
+ done
+ if test "X$ll" = "X$old_library" ; then # only static version available
+ found=no
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+ lib=$ladir/$old_library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ fi
+ ;;
+ *) ;;
+ esac
+ fi
+ fi
+ ;; # -l
+ *.ltframework)
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ if test "$linkmode" = lib ; then
+ case "$new_inherited_linker_flags " in
+ *" $deplib "*) ;;
+ * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+ esac
+ fi
+ fi
+ continue
+ ;;
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ *)
+ func_warning "\`-L' is ignored for archives/objects"
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ func_stripname '-R' '' "$deplib"
+ dir=$func_stripname_result
+ # Make sure the xrpath contains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ # Linking convenience modules into shared libraries is allowed,
+ # but linking other static libraries is non-portable.
+ case " $dlpreconveniencelibs " in
+ *" $deplib "*) ;;
+ *)
+ valid_a_lib=no
+ case $deplibs_check_method in
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+ | $EGREP "$match_pattern_regex" > /dev/null; then
+ valid_a_lib=yes
+ fi
+ ;;
+ pass_all)
+ valid_a_lib=yes
+ ;;
+ esac
+ if test "$valid_a_lib" != yes; then
+ $ECHO
+ $ECHO "*** Warning: Trying to link with static lib archive $deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because the file extensions .$libext of this argument makes me believe"
+ $ECHO "*** that it is just a static archive that I should not use here."
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the"
+ $ECHO "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ ;;
+ esac
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ elif test "$linkmode" = prog; then
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+ fi
+
+ # Check to see that this really is a libtool archive.
+ func_lalib_unsafe_p "$lib" \
+ || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+ func_dirname "$lib" "" "."
+ ladir="$func_dirname_result"
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ inherited_linker_flags=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variables installed, or shouldnotlink
+ installed=yes
+ shouldnotlink=no
+ avoidtemprpath=
+
+
+ # Read the .la file
+ func_source "$lib"
+
+ # Convert "-framework foo" to "foo.ltframework"
+ if test -n "$inherited_linker_flags"; then
+ tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+ for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+ case " $new_inherited_linker_flags " in
+ *" $tmp_inherited_linker_flag "*) ;;
+ *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+ esac
+ done
+ fi
+ dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ func_fatal_error "\`$lib' is not a convenience library"
+ fi
+ continue
+ fi # $pass = conv
+
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ func_fatal_error "cannot find name of link library for \`$lib'"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+ fi
+ if test -z "$dlname" ||
+ test "$dlopen_support" != yes ||
+ test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload. We also need to preload any
+ # dependent libraries so libltdl's deplib preloader doesn't
+ # bomb out in the load deplibs phase.
+ dlprefiles="$dlprefiles $lib $dependency_libs"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ func_warning "cannot determine absolute directory name of \`$ladir'"
+ func_warning "passing it literally to the linker, although it might fail"
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ func_basename "$lib"
+ laname="$func_basename_result"
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ func_warning "library \`$lib' was moved."
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+ else
+ if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ dir="$ladir"
+ absdir="$abs_ladir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi
+ fi # $installed = yes
+ func_stripname 'lib' '.la' "$laname"
+ name=$func_stripname_result
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir" && test "$linkmode" = prog; then
+ func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Keep a list of preopened convenience libraries to check
+ # that they are being used correctly in the link pass.
+ test -z "$libdir" && \
+ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen finds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs" # used for prog,scan pass
+ fi
+ continue
+ fi
+
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) func_stripname '-L' '' "$deplib"
+ newlib_search_path="$newlib_search_path $func_stripname_result"
+ ;;
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ if test "$linkmode,$pass" = "prog,link"; then
+ if test -n "$library_names" &&
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath:" in
+ *"$absdir:"*) ;;
+ *) temp_rpath="$temp_rpath$absdir:" ;;
+ esac
+ fi
+
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+ fi
+
+ link_static=no # Whether the deplib will be linked statically
+ use_static_libs=$prefer_static_libs
+ if test "$use_static_libs" = built && test "$installed" = yes; then
+ use_static_libs=no
+ fi
+ if test -n "$library_names" &&
+ { test "$use_static_libs" = no || test -z "$old_library"; }; then
+ case $host in
+ *cygwin* | *mingw* | *cegcc*)
+ # No point in relinking DLLs because paths are not encoded
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=no
+ ;;
+ *)
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+ ;;
+ esac
+ # This is a shared library
+
+ # Warn about portability, can't link against -module's on some
+ # systems (darwin). Don't bleat about dlopened modules though!
+ dlopenmodule=""
+ for dlpremoduletest in $dlprefiles; do
+ if test "X$dlpremoduletest" = "X$lib"; then
+ dlopenmodule="$dlpremoduletest"
+ break
+ fi
+ done
+ if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+ $ECHO
+ if test "$linkmode" = prog; then
+ $ECHO "*** Warning: Linking the executable $output against the loadable module"
+ else
+ $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+ fi
+ $ECHO "*** $linklib is not portable!"
+ fi
+ if test "$linkmode" = lib &&
+ test "$hardcode_into_libs" = yes; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin* | mingw* | *cegcc*)
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ func_basename "$soroot"
+ soname="$func_basename_result"
+ func_stripname 'lib' '.dll' "$soname"
+ newlib=libimp-$func_stripname_result.a
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ func_verbose "extracting exported symbol list from \`$soname'"
+ func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ func_verbose "generating import library for \`$soname'"
+ func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ case $host in
+ *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+ *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+ *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+ *-*-unixware7*) add_dir="-L$dir" ;;
+ *-*-darwin* )
+ # if the lib is a (non-dlopened) module then we can not
+ # link against it, someone is ignoring the earlier warnings
+ if /usr/bin/file -L $add 2> /dev/null |
+ $GREP ": [^:]* bundle" >/dev/null ; then
+ if test "X$dlopenmodule" != "X$lib"; then
+ $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+ if test -z "$old_library" ; then
+ $ECHO
+ $ECHO "*** And there doesn't seem to be a static archive available"
+ $ECHO "*** The link will probably fail, sorry"
+ else
+ add="$dir/$old_library"
+ fi
+ elif test -n "$old_library"; then
+ add="$dir/$old_library"
+ fi
+ fi
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ func_fatal_configuration "unsupported hardcode properties"
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes &&
+ test "$hardcode_minus_L" != yes &&
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes &&
+ test "$hardcode_direct_absolute" = no; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ elif test "$hardcode_automatic" = yes; then
+ if test -n "$inst_prefix_dir" &&
+ test -f "$inst_prefix_dir$libdir/$linklib" ; then
+ add="$inst_prefix_dir$libdir/$linklib"
+ else
+ add="$libdir/$linklib"
+ fi
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ # Try looking first in the location we're being installed to.
+ if test -n "$inst_prefix_dir"; then
+ case $libdir in
+ [\\/]*)
+ add_dir="$add_dir -L$inst_prefix_dir$libdir"
+ ;;
+ esac
+ fi
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ $ECHO
+ $ECHO "*** Warning: This system can not link to static lib archive $lib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ $ECHO "*** But as you try to build a module library, libtool will still create "
+ $ECHO "*** a static module, that should work as long as the dlopening application"
+ $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes ||
+ test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) func_stripname '-R' '' "$libdir"
+ temp_xrpath=$func_stripname_result
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ if $opt_duplicate_deps ; then
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ fi
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ path=
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ func_dirname "$deplib" "" "."
+ dir="$func_dirname_result"
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ func_warning "cannot determine absolute directory name of \`$dir'"
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if $GREP "^installed=no" $deplib > /dev/null; then
+ case $host in
+ *-*-darwin*)
+ depdepl=
+ eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ if test -n "$deplibrary_names" ; then
+ for tmp in $deplibrary_names ; do
+ depdepl=$tmp
+ done
+ if test -f "$absdir/$objdir/$depdepl" ; then
+ depdepl="$absdir/$objdir/$depdepl"
+ darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ if test -z "$darwin_install_name"; then
+ darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+ fi
+ compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+ linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+ path=
+ fi
+ fi
+ ;;
+ *)
+ path="-L$absdir/$objdir"
+ ;;
+ esac
+ else
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ test "$absdir" != "$libdir" && \
+ func_warning "\`$deplib' seems to be moved"
+
+ path="-L$absdir"
+ fi
+ ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$path $deplibs" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = link; then
+ if test "$linkmode" = "prog"; then
+ compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+ finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+ else
+ compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ fi
+ fi
+ dependency_libs="$newdependency_libs"
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ if test "$pass" != conv; then
+ # Make sure lib_search_path contains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ # FIXME: Pedantically, this is the right thing to do, so
+ # that some nasty dependency loop isn't accidentally
+ # broken:
+ #new_libs="$deplib $new_libs"
+ # Pragmatically, this seems to cause very few problems in
+ # practice:
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ -R*) ;;
+ *)
+ # And here is the reason: when a library appears more
+ # than once as an explicit dependence of a library, or
+ # is implicitly linked in more than once by the
+ # compiler, it is considered special, and multiple
+ # occurrences thereof are not removed. Compare this
+ # with having the same library being listed as a
+ # dependency of multiple other libraries: in this case,
+ # we know (pedantically, we assume) the library does not
+ # need to be listed more than once, so we keep only the
+ # last copy. This is not always right, but it is rare
+ # enough that we require users that really mean to play
+ # such unportable linking tricks to link the library
+ # using -Wl,-lname, so that libtool does not consider it
+ # for duplicate removal.
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ # Last step: remove runtime libs from dependency_libs
+ # (they stay in deplibs)
+ tmp_libs=
+ for i in $dependency_libs ; do
+ case " $predeps $postdeps $compiler_lib_search_path " in
+ *" $i "*)
+ i=""
+ ;;
+ esac
+ if test -n "$i" ; then
+ tmp_libs="$tmp_libs $i"
+ fi
+ done
+ dependency_libs=$tmp_libs
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ fi
+ if test "$linkmode" = prog || test "$linkmode" = lib; then
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for archives"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for archives" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for archives"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for archives"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for archives"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for archives"
+
+ test -n "$export_symbols$export_symbols_regex" && \
+ func_warning "\`-export-symbols' is ignored for archives"
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ func_stripname 'lib' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ test "$module" = no && \
+ func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ func_stripname '' '.la' "$outputname"
+ name=$func_stripname_result
+ eval shared_ext=\"$shrext_cmds\"
+ eval libname=\"$libname_spec\"
+ else
+ func_stripname '' '.la' "$outputname"
+ libname=$func_stripname_result
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+ else
+ $ECHO
+ $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+ $ECHO "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ test "$dlself" != no && \
+ func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+ set dummy $rpath
+ shift
+ test "$#" -gt 1 && \
+ func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+ install_libdir="$1"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ # Some compilers have problems with a `.al' extension so
+ # convenience libraries should have the same extension an
+ # archive normally would.
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for convenience libraries"
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ shift
+ IFS="$save_ifs"
+
+ test -n "$7" && \
+ func_fatal_help "too many parameters to \`-version-info'"
+
+ # convert absolute version numbers to libtool ages
+ # this retains compatibility with .la files and attempts
+ # to make the code below a bit more comprehensible
+
+ case $vinfo_number in
+ yes)
+ number_major="$1"
+ number_minor="$2"
+ number_revision="$3"
+ #
+ # There are really only two kinds -- those that
+ # use the current revision as the major version
+ # and those that subtract age and use age as
+ # a minor version. But, then there is irix
+ # which has an extra 1 added just for fun
+ #
+ case $version_type in
+ darwin|linux|osf|windows|none)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_revision"
+ ;;
+ freebsd-aout|freebsd-elf|sunos)
+ current="$number_major"
+ revision="$number_minor"
+ age="0"
+ ;;
+ irix|nonstopux)
+ func_arith $number_major + $number_minor
+ current=$func_arith_result
+ age="$number_minor"
+ revision="$number_minor"
+ lt_irix_increment=no
+ ;;
+ *)
+ func_fatal_configuration "$modename: unknown library version type \`$version_type'"
+ ;;
+ esac
+ ;;
+ no)
+ current="$1"
+ revision="$2"
+ age="$3"
+ ;;
+ esac
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "CURRENT \`$current' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $revision in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "REVISION \`$revision' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ case $age in
+ 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+ *)
+ func_error "AGE \`$age' must be a nonnegative integer"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ func_error "AGE \`$age' is greater than the current interface number \`$current'"
+ func_fatal_error "\`$vinfo' is not valid version information"
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ func_arith $current + 1
+ minor_current=$func_arith_result
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ irix | nonstopux)
+ if test "X$lt_irix_increment" = "Xno"; then
+ func_arith $current - $age
+ else
+ func_arith $current - $age + 1
+ fi
+ major=$func_arith_result
+
+ case $version_type in
+ nonstopux) verstring_prefix=nonstopux ;;
+ *) verstring_prefix=sgi ;;
+ esac
+ verstring="$verstring_prefix$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ func_arith $revision - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring_prefix$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ func_arith $current - $age
+ major=.$func_arith_result
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ func_arith $current - $loop
+ iface=$func_arith_result
+ func_arith $loop - 1
+ loop=$func_arith_result
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ qnx)
+ major=".$current"
+ versuffix=".$current"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ func_arith $current - $age
+ major=$func_arith_result
+ versuffix="-$major"
+ ;;
+
+ *)
+ func_fatal_configuration "unknown library version type \`$version_type'"
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ func_warning "undefined symbols not allowed in $host shared libraries"
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ fi
+
+ func_generate_dlsyms "$libname" "$libname" "yes"
+ libobjs="$libobjs $symfileobj"
+ test "X$libobjs" = "X " && libobjs=
+
+ if test "$mode" != relink; then
+ # Remove our outputs, but don't remove object files since they
+ # may have been created when compiling PIC objects.
+ removelist=
+ tempremovelist=`$ECHO "$output_objdir/*"`
+ for p in $tempremovelist; do
+ case $p in
+ *.$objext | *.gcno)
+ ;;
+ $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+ if test "X$precious_files_regex" != "X"; then
+ if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+ then
+ continue
+ fi
+ fi
+ removelist="$removelist $p"
+ ;;
+ *) ;;
+ esac
+ done
+ test -n "$removelist" && \
+ func_show_eval "${RM}r \$removelist"
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ #for path in $notinst_path; do
+ # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+ # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+ # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+ #done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles contains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles contains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs System.ltframework"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *-*-sco3.2v5* | *-*-sco5v6*)
+ # Causes problems with __ctype
+ ;;
+ *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+ # Compiler inserts libc in the correct place for threads to work
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behavior.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $opt_dry_run || $RM conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which I believe you do not have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+ $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+ fi
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ else
+ # Error occurred in the first compile. Let's try to salvage
+ # the situation: Compile a separate program for each library.
+ for i in $deplibs; do
+ case $i in
+ -l*)
+ func_stripname -l '' "$i"
+ name=$func_stripname_result
+ $opt_dry_run || $RM conftest
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+ ldd_output=`ldd conftest`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $i "*)
+ newdeplibs="$newdeplibs $i"
+ i=""
+ ;;
+ esac
+ fi
+ if test -n "$i" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+ set dummy $deplib_matches; shift
+ deplib_match=$1
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+ $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+ fi
+ fi
+ else
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning! Library $i is needed by this library but I was not able to"
+ $ECHO "*** make it link in! You will probably need to install it or some"
+ $ECHO "*** library that it depends on before this library will be fully"
+ $ECHO "*** functional. Installing it before continuing would be even better."
+ fi
+ ;;
+ *)
+ newdeplibs="$newdeplibs $i"
+ ;;
+ esac
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method; shift
+ file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null |
+ $GREP " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+ $SED -e 10q |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a file magic. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method; shift
+ match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+ for a_deplib in $deplibs; do
+ case $a_deplib in
+ -l*)
+ func_stripname -l '' "$a_deplib"
+ name=$func_stripname_result
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ case " $predeps $postdeps " in
+ *" $a_deplib "*)
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ ;;
+ esac
+ fi
+ if test -n "$a_deplib" ; then
+ libname=`eval "\\$ECHO \"$libname_spec\""`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ potlib="$potent_lib" # see symlink-check above in file_magic test
+ if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+ $EGREP "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ fi
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ $ECHO
+ $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+ $ECHO "*** I have the capability to make that library automatically link in when"
+ $ECHO "*** you link to this library. But I can only do this if you have a"
+ $ECHO "*** shared version of the library, which you do not appear to have"
+ $ECHO "*** because I did check the linker path looking for a file starting"
+ if test -z "$potlib" ; then
+ $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+ else
+ $ECHO "*** with $libname and none of the candidates passed a file format test"
+ $ECHO "*** using a regex pattern. Last file checked: $potlib"
+ fi
+ fi
+ ;;
+ *)
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ ;;
+ esac
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+ if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+ for i in $predeps $postdeps ; do
+ # can't use Xsed below, because $i might contain '/'
+ tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+ done
+ fi
+ if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' |
+ $GREP . >/dev/null; then
+ $ECHO
+ if test "X$deplibs_check_method" = "Xnone"; then
+ $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ $ECHO "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library with the System framework
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ $ECHO
+ $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+ $ECHO "*** dependencies of module $libname. Therefore, libtool will create"
+ $ECHO "*** a static module, that should work as long as the dlopening"
+ $ECHO "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ $ECHO
+ $ECHO "*** However, this would only work if libtool was able to extract symbol"
+ $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ $ECHO "*** not find such a program. So, this module is probably useless."
+ $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ $ECHO "*** The inter-library dependencies that have been dropped here will be"
+ $ECHO "*** automatically added whenever a program is linked with this library"
+ $ECHO "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ $ECHO
+ $ECHO "*** Since this library must not contain undefined symbols,"
+ $ECHO "*** because either the platform does not support them or"
+ $ECHO "*** it was explicitly requested with -no-undefined,"
+ $ECHO "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ case $host in
+ *-*-darwin*)
+ newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ deplibs="$new_libs"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ if test -n "$hardcode_libdir_flag_spec_ld"; then
+ eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ else
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval shared_ext=\"$shrext_cmds\"
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ shift
+ realname="$1"
+ shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ if test -z "$dlname"; then
+ dlname=$soname
+ fi
+
+ lib="$output_objdir/$realname"
+ linknames=
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ test "X$libobjs" = "X " && libobjs=
+
+ delfiles=
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+ export_symbols="$output_objdir/$libname.uexp"
+ delfiles="$delfiles $export_symbols"
+ fi
+
+ orig_export_symbols=
+ case $host_os in
+ cygwin* | mingw* | cegcc*)
+ if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+ # exporting using user supplied symfile
+ if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+ # and it's NOT already a .def file. Must figure out
+ # which of the given symbols are data symbols and tag
+ # them as such. So, trigger use of export_symbols_cmds.
+ # export_symbols gets reassigned inside the "prepare
+ # the list of exported symbols" if statement, so the
+ # include_expsyms logic still works.
+ orig_export_symbols="$export_symbols"
+ export_symbols=
+ always_export_symbols=yes
+ fi
+ fi
+ ;;
+ esac
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ cmds=$export_symbols_cmds
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ func_len " $cmd"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ func_show_eval "$cmd" 'exit $?'
+ skipped_export=false
+ else
+ # The command line is too long to execute in one step.
+ func_verbose "using reloadable object file for export list..."
+ skipped_export=:
+ # Break out early, otherwise skipped_export may be
+ # set to false by a later but shorter cmd.
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+
+ tmp_deplibs=
+ for test_deplib in $deplibs; do
+ case " $convenience " in
+ *" $test_deplib "*) ;;
+ *)
+ tmp_deplibs="$tmp_deplibs $test_deplib"
+ ;;
+ esac
+ done
+ deplibs="$tmp_deplibs"
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec" &&
+ test "$compiler_needs_object" = yes &&
+ test -z "$libobjs"; then
+ # extract the archives, so we have objects to list.
+ # TODO: could optimize this to just extract one archive.
+ whole_archive_flag_spec=
+ fi
+ if test -n "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ else
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ eval test_cmds=\"$module_expsym_cmds\"
+ cmds=$module_expsym_cmds
+ else
+ eval test_cmds=\"$module_cmds\"
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval test_cmds=\"$archive_expsym_cmds\"
+ cmds=$archive_expsym_cmds
+ else
+ eval test_cmds=\"$archive_cmds\"
+ cmds=$archive_cmds
+ fi
+ fi
+
+ if test "X$skipped_export" != "X:" &&
+ func_len " $test_cmds" &&
+ len=$func_len_result &&
+ test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ :
+ else
+ # The command line is too long to link in one step, link piecewise
+ # or, if using GNU ld and skipped_export is not :, use a linker
+ # script.
+
+ # Save the value of $output and $libobjs because we want to
+ # use them later. If we have whole_archive_flag_spec, we
+ # want to use save_libobjs as it was before
+ # whole_archive_flag_spec was expanded, because we can't
+ # assume the linker understands whole_archive_flag_spec.
+ # This may have to be revisited, in case too many
+ # convenience libraries get linked in and end up exceeding
+ # the spec.
+ if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+ save_libobjs=$libobjs
+ fi
+ save_output=$output
+ output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+ # Clear the reloadable object creation command queue and
+ # initialize k to one.
+ test_cmds=
+ concat_cmds=
+ objlist=
+ last_robj=
+ k=1
+
+ if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+ output=${output_objdir}/${output_la}.lnkscript
+ func_verbose "creating GNU ld script: $output"
+ $ECHO 'INPUT (' > $output
+ for obj in $save_libobjs
+ do
+ $ECHO "$obj" >> $output
+ done
+ $ECHO ')' >> $output
+ delfiles="$delfiles $output"
+ elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+ output=${output_objdir}/${output_la}.lnk
+ func_verbose "creating linker input file list: $output"
+ : > $output
+ set x $save_libobjs
+ shift
+ firstobj=
+ if test "$compiler_needs_object" = yes; then
+ firstobj="$1 "
+ shift
+ fi
+ for obj
+ do
+ $ECHO "$obj" >> $output
+ done
+ delfiles="$delfiles $output"
+ output=$firstobj\"$file_list_spec$output\"
+ else
+ if test -n "$save_libobjs"; then
+ func_verbose "creating reloadable object files..."
+ output=$output_objdir/$output_la-${k}.$objext
+ eval test_cmds=\"$reload_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+
+ # Loop over the list of objects to be linked.
+ for obj in $save_libobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ if test "X$objlist" = X ||
+ test "$len" -lt "$max_cmd_len"; then
+ func_append objlist " $obj"
+ else
+ # The command $test_cmds is almost too long, add a
+ # command to the queue.
+ if test "$k" -eq 1 ; then
+ # The first file doesn't have a previous command to add.
+ eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+ else
+ # All subsequent reloadable object files will link in
+ # the last one created.
+ eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+ fi
+ last_robj=$output_objdir/$output_la-${k}.$objext
+ func_arith $k + 1
+ k=$func_arith_result
+ output=$output_objdir/$output_la-${k}.$objext
+ objlist=$obj
+ func_len " $last_robj"
+ func_arith $len0 + $func_len_result
+ len=$func_arith_result
+ fi
+ done
+ # Handle the remaining objects by creating one last
+ # reloadable object file. All subsequent reloadable object
+ # files will link in the last one created.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+ fi
+ delfiles="$delfiles $output"
+
+ else
+ output=
+ fi
+
+ if ${skipped_export-false}; then
+ func_verbose "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $opt_dry_run || $RM $export_symbols
+ libobjs=$output
+ # Append the command to create the export file.
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+ if test -n "$last_robj"; then
+ eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+ fi
+ fi
+
+ test -n "$save_libobjs" &&
+ func_verbose "creating a temporary reloadable object file: $output"
+
+ # Loop through the commands generated above and execute them.
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $concat_cmds; do
+ IFS="$save_ifs"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+ func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+
+ if ${skipped_export-false}; then
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ tmp_export_symbols="$export_symbols"
+ test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+ $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+ fi
+
+ if test -n "$orig_export_symbols"; then
+ # The given exports_symbols file has to be filtered, so filter it.
+ func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+ # FIXME: $output_objdir/$libname.filter potentially contains lots of
+ # 's' commands which not all seds can handle. GNU sed should be fine
+ # though. Also, the filter scales superlinearly with the number of
+ # global variables. join(1) would be nice here, but unfortunately
+ # isn't a blessed tool.
+ $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+ delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+ export_symbols=$output_objdir/$libname.def
+ $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+ fi
+ fi
+
+ libobjs=$output
+ # Restore the value of output.
+ output=$save_output
+
+ if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+ # Expand the library linking commands again to reset the
+ # value of $libobjs for piecewise linking.
+
+ # Do each of the archive commands.
+ if test "$module" = yes && test -n "$module_cmds" ; then
+ if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+ cmds=$module_expsym_cmds
+ else
+ cmds=$module_cmds
+ fi
+ else
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ cmds=$archive_expsym_cmds
+ else
+ cmds=$archive_cmds
+ fi
+ fi
+ fi
+
+ if test -n "$delfiles"; then
+ # Append the command to remove temporary files to $cmds.
+ eval cmds=\"\$cmds~\$RM $delfiles\"
+ fi
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ libobjs="$libobjs $func_extract_archives_result"
+ test "X$libobjs" = "X " && libobjs=
+ fi
+
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ eval cmd=\"$cmd\"
+ $opt_silent || {
+ func_quote_for_expand "$cmd"
+ eval "func_echo $func_quote_for_expand_result"
+ }
+ $opt_dry_run || eval "$cmd" || {
+ lt_exit=$?
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ ( cd "$output_objdir" && \
+ $RM "${realname}T" && \
+ $MV "${realname}U" "$realname" )
+ fi
+
+ exit $lt_exit
+ }
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+ if test -n "$convenience"; then
+ if test -z "$whole_archive_flag_spec"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ func_warning "\`-dlopen' is ignored for objects"
+ fi
+
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ func_warning "\`-l' and \`-L' are ignored for objects" ;;
+ esac
+
+ test -n "$rpath" && \
+ func_warning "\`-rpath' is ignored for objects"
+
+ test -n "$xrpath" && \
+ func_warning "\`-R' is ignored for objects"
+
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for objects"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for objects"
+
+ case $output in
+ *.lo)
+ test -n "$objs$old_deplibs" && \
+ func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+ libobj=$output
+ func_lo2o "$libobj"
+ obj=$func_lo2o_result
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $opt_dry_run || $RM $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+ else
+ gentop="$output_objdir/${obj}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $convenience
+ reload_conv_objs="$reload_objs $func_extract_archives_result"
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ # $show "echo timestamp > $libobj"
+ # $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+ exit $EXIT_SUCCESS
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ func_execute_cmds "$reload_cmds" 'exit $?'
+ fi
+
+ if test -n "$gentop"; then
+ func_show_eval '${RM}r "$gentop"'
+ fi
+
+ exit $EXIT_SUCCESS
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result.exe;;
+ esac
+ test -n "$vinfo" && \
+ func_warning "\`-version-info' is ignored for programs"
+
+ test -n "$release" && \
+ func_warning "\`-release' is ignored for programs"
+
+ test "$preload" = yes \
+ && test "$dlopen_support" = unknown \
+ && test "$dlopen_self" = unknown \
+ && test "$dlopen_self_static" = unknown && \
+ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody replace the C library is the System framework
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+ ;;
+ esac
+
+ case $host in
+ *-*-darwin*)
+ # Don't allow lazy linking, it breaks C++ global constructors
+ # But is supposedly fixed on 10.4 or later (yay!).
+ if test "$tagname" = CXX ; then
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+ 10.[0123])
+ compile_command="$compile_command ${wl}-bind_at_load"
+ finalize_command="$finalize_command ${wl}-bind_at_load"
+ ;;
+ esac
+ fi
+ # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+ compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+ ;;
+ esac
+
+
+ # move library search paths that coincide with paths to not yet
+ # installed libraries to the beginning of the library search list
+ new_libs=
+ for path in $notinst_path; do
+ case " $new_libs " in
+ *" -L$path/$objdir "*) ;;
+ *)
+ case " $compile_deplibs " in
+ *" -L$path/$objdir "*)
+ new_libs="$new_libs -L$path/$objdir" ;;
+ esac
+ ;;
+ esac
+ done
+ for deplib in $compile_deplibs; do
+ case $deplib in
+ -L*)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ ;;
+ *) new_libs="$new_libs $deplib" ;;
+ esac
+ done
+ compile_deplibs="$new_libs"
+
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+ testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ ::) dllsearchpath=$libdir;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ case :$dllsearchpath: in
+ *":$testbindir:"*) ;;
+ ::) dllsearchpath=$testbindir;;
+ *) dllsearchpath="$dllsearchpath:$testbindir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+ # template prelinking step
+ if test -n "$prelink_cmds"; then
+ func_execute_cmds "$prelink_cmds" 'exit $?'
+ fi
+
+ wrappers_required=yes
+ case $host in
+ *cegcc | *mingw32ce* )
+ # Disable wrappers for cegcc, we are cross compiling anyway.
+ wrappers_required=no
+ ;;
+ *cygwin* | *mingw* )
+ if test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ *)
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ wrappers_required=no
+ fi
+ ;;
+ esac
+ if test "$wrappers_required" = no; then
+ # Replace the output file specification.
+ compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ exit_status=0
+ func_show_eval "$link_command" 'exit_status=$?'
+
+ # Delete the generated files.
+ if test -f "$output_objdir/${outputname}S.${objext}"; then
+ func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+ fi
+
+ exit $exit_status
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $opt_dry_run || $RM $output
+ # Link the executable and exit
+ func_show_eval "$link_command" 'exit $?'
+ exit $EXIT_SUCCESS
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ func_warning "this platform does not like uninstalled shared libraries"
+ func_warning "\`$output' will be relinked during installation"
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ func_show_eval "$link_command" 'exit $?'
+
+ # Now create the wrapper script.
+ func_verbose "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $ECHO for shipping.
+ if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+ case $progpath in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+ esac
+ qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if not in dry run mode.
+ $opt_dry_run || {
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) func_stripname '' '.exe' "$output"
+ output=$func_stripname_result ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*)
+ exeext=.exe
+ func_stripname '' '.exe' "$outputname"
+ outputname=$func_stripname_result ;;
+ *) exeext= ;;
+ esac
+ case $host in
+ *cygwin* | *mingw* )
+ func_dirname_and_basename "$output" "" "."
+ output_name=$func_basename_result
+ output_path=$func_dirname_result
+ cwrappersource="$output_path/$objdir/lt-$output_name.c"
+ cwrapper="$output_path/$output_name.exe"
+ $RM $cwrappersource $cwrapper
+ trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_cwrapperexe_src > $cwrappersource
+
+ # The wrapper executable is built using the $host compiler,
+ # because it contains $host paths and files. If cross-
+ # compiling, it, like the target executable, must be
+ # executed on the $host or under an emulation environment.
+ $opt_dry_run || {
+ $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+ $STRIP $cwrapper
+ }
+
+ # Now, create the wrapper script for func_source use:
+ func_ltwrapper_scriptname $cwrapper
+ $RM $func_ltwrapper_scriptname_result
+ trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+ $opt_dry_run || {
+ # note: this script will not be executed, so do not chmod.
+ if test "x$build" = "x$host" ; then
+ $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+ else
+ func_emit_wrapper no > $func_ltwrapper_scriptname_result
+ fi
+ }
+ ;;
+ * )
+ $RM $output
+ trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+ func_emit_wrapper no > $output
+ chmod +x $output
+ ;;
+ esac
+ }
+ exit $EXIT_SUCCESS
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save $symfileobj"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$old_deplibs $non_pic_objects"
+ if test "$preload" = yes && test -f "$symfileobj"; then
+ oldobjs="$oldobjs $symfileobj"
+ fi
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $addlibs
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ cmds=$old_archive_from_new_cmds
+ else
+
+ # Add any objects from preloaded convenience libraries
+ if test -n "$dlprefiles"; then
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+
+ func_extract_archives $gentop $dlprefiles
+ oldobjs="$oldobjs $func_extract_archives_result"
+ fi
+
+ # POSIX demands no paths to be encoded in archives. We have
+ # to avoid creating archives with duplicate basenames if we
+ # might have to extract them afterwards, e.g., when creating a
+ # static archive out of a convenience library, or when linking
+ # the entirety of a libtool archive into another (currently
+ # not supported by libtool).
+ if (for obj in $oldobjs
+ do
+ func_basename "$obj"
+ $ECHO "$func_basename_result"
+ done | sort | sort -uc >/dev/null 2>&1); then
+ :
+ else
+ $ECHO "copying selected object files to avoid basename conflicts..."
+ gentop="$output_objdir/${outputname}x"
+ generated="$generated $gentop"
+ func_mkdir_p "$gentop"
+ save_oldobjs=$oldobjs
+ oldobjs=
+ counter=1
+ for obj in $save_oldobjs
+ do
+ func_basename "$obj"
+ objbase="$func_basename_result"
+ case " $oldobjs " in
+ " ") oldobjs=$obj ;;
+ *[\ /]"$objbase "*)
+ while :; do
+ # Make sure we don't pick an alternate name that also
+ # overlaps.
+ newobj=lt$counter-$objbase
+ func_arith $counter + 1
+ counter=$func_arith_result
+ case " $oldobjs " in
+ *[\ /]"$newobj "*) ;;
+ *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+ esac
+ done
+ func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+ oldobjs="$oldobjs $gentop/$newobj"
+ ;;
+ *) oldobjs="$oldobjs $obj" ;;
+ esac
+ done
+ fi
+ eval cmds=\"$old_archive_cmds\"
+
+ func_len " $cmds"
+ len=$func_len_result
+ if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+ cmds=$old_archive_cmds
+ else
+ # the command line is too long to link in one step, link in parts
+ func_verbose "using piecewise archive linking..."
+ save_RANLIB=$RANLIB
+ RANLIB=:
+ objlist=
+ concat_cmds=
+ save_oldobjs=$oldobjs
+ oldobjs=
+ # Is there a better way of finding the last object in the list?
+ for obj in $save_oldobjs
+ do
+ last_oldobj=$obj
+ done
+ eval test_cmds=\"$old_archive_cmds\"
+ func_len " $test_cmds"
+ len0=$func_len_result
+ len=$len0
+ for obj in $save_oldobjs
+ do
+ func_len " $obj"
+ func_arith $len + $func_len_result
+ len=$func_arith_result
+ func_append objlist " $obj"
+ if test "$len" -lt "$max_cmd_len"; then
+ :
+ else
+ # the above command should be used before it gets too long
+ oldobjs=$objlist
+ if test "$obj" = "$last_oldobj" ; then
+ RANLIB=$save_RANLIB
+ fi
+ test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+ objlist=
+ len=$len0
+ fi
+ done
+ RANLIB=$save_RANLIB
+ oldobjs=$objlist
+ if test "X$oldobjs" = "X" ; then
+ eval cmds=\"\$concat_cmds\"
+ else
+ eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+ fi
+ fi
+ fi
+ func_execute_cmds "$cmds" 'exit $?'
+ done
+
+ test -n "$generated" && \
+ func_show_eval "${RM}r$generated"
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ func_verbose "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ func_quote_for_eval "$var_value"
+ relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+ relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ if test "$hardcode_automatic" = yes ; then
+ relink_command=
+ fi
+
+ # Only create the output if not a dry run.
+ $opt_dry_run || {
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ func_basename "$deplib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$deplib' is not a valid libtool archive"
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+
+ for lib in $dlfiles; do
+ case $lib in
+ *.la)
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlfiles="$newdlfiles $libdir/$name"
+ ;;
+ *) newdlfiles="$newdlfiles $lib" ;;
+ esac
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ *.la)
+ # Only pass preopened files to the pseudo-archive (for
+ # eventual linking with the app. that links it) if we
+ # didn't already link the preopened objects directly into
+ # the library:
+ func_basename "$lib"
+ name="$func_basename_result"
+ eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ test -z "$libdir" && \
+ func_fatal_error "\`$lib' is not a valid libtool archive"
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ ;;
+ esac
+ done
+ dlprefiles="$newdlprefiles"
+ else
+ newdlfiles=
+ for lib in $dlfiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlfiles="$newdlfiles $abs"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ case $lib in
+ [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+ *) abs=`pwd`"/$lib" ;;
+ esac
+ newdlprefiles="$newdlprefiles $abs"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $RM $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $ECHO >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ }
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+ ;;
+ esac
+ exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+ func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+ $opt_debug
+ RM="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) RM="$RM $arg"; rmforce=yes ;;
+ -*) RM="$RM $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ test -z "$RM" && \
+ func_fatal_help "you must specify an RM program"
+
+ rmdirs=
+
+ origobjdir="$objdir"
+ for file in $files; do
+ func_dirname "$file" "" "."
+ dir="$func_dirname_result"
+ if test "X$dir" = X.; then
+ objdir="$origobjdir"
+ else
+ objdir="$dir/$origobjdir"
+ fi
+ func_basename "$file"
+ name="$func_basename_result"
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if { test -L "$file"; } >/dev/null 2>&1 ||
+ { test -h "$file"; } >/dev/null 2>&1 ||
+ test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if func_lalib_p "$file"; then
+ func_source $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+ case "$mode" in
+ clean)
+ case " $library_names " in
+ # " " in the beginning catches empty $dlname
+ *" $dlname "*) ;;
+ *) rmfiles="$rmfiles $objdir/$dlname" ;;
+ esac
+ test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+ ;;
+ uninstall)
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ ;;
+ esac
+ fi
+ ;;
+
+ *.lo)
+ # Possibly a libtool object, so verify it.
+ if func_lalib_p "$file"; then
+
+ # Read the .lo file
+ func_source $dir/$name
+
+ # Add PIC object to the list of files to remove.
+ if test -n "$pic_object" &&
+ test "$pic_object" != none; then
+ rmfiles="$rmfiles $dir/$pic_object"
+ fi
+
+ # Add non-PIC object to the list of files to remove.
+ if test -n "$non_pic_object" &&
+ test "$non_pic_object" != none; then
+ rmfiles="$rmfiles $dir/$non_pic_object"
+ fi
+ fi
+ ;;
+
+ *)
+ if test "$mode" = clean ; then
+ noexename=$name
+ case $file in
+ *.exe)
+ func_stripname '' '.exe' "$file"
+ file=$func_stripname_result
+ func_stripname '' '.exe' "$name"
+ noexename=$func_stripname_result
+ # $file with .exe has already been added to rmfiles,
+ # add $file without .exe
+ rmfiles="$rmfiles $file"
+ ;;
+ esac
+ # Do a test to see if this is a libtool program.
+ if func_ltwrapper_p "$file"; then
+ if func_ltwrapper_executable_p "$file"; then
+ func_ltwrapper_scriptname "$file"
+ relink_command=
+ func_source $func_ltwrapper_scriptname_result
+ rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+ else
+ relink_command=
+ func_source $dir/$noexename
+ fi
+
+ # note $name still contains .exe if it was in $file originally
+ # as does the version of $file that was added into $rmfiles
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ if test "X$noexename" != "X$name" ; then
+ rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+ fi
+ fi
+ fi
+ ;;
+ esac
+ func_show_eval "$RM $rmfiles" 'exit_status=1'
+ done
+ objdir="$origobjdir"
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ func_show_eval "rmdir $dir >/dev/null 2>&1"
+ fi
+ done
+
+ exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+ func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+ help="$generic_help"
+ func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+ func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+ eval exec "$exec_cmd"
+ exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries. Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them. This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration. But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
--- /dev/null
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * gpg-error.m4: New. Take from current gpg-error master.
+ * Makefile.am (EXTRA_DIST): Add gpg-error.m4.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * noexecstack.m4: Replace non portable grep -q. Reported by
+ Albert Chin.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * noexecstack.m4: Change default to enable it.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: New.
+
+ * noexecstack.m4: New. Taken from gnupg 1.4
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * fallback.m4: Removed again.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * fallback.m4: New file from Pth.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * sys_socket_h.m4, socklen.m4, onceonly.m4: New files from gnulib.
+
+2004-04-06 Werner Koch <wk@gnupg.org>
+
+ * libtool.m4: Updated from 1.5.4
+
+2003-12-08 Werner Koch <wk@gnupg.org>
+
+ * libtool.m4: New.
--- /dev/null
+EXTRA_DIST = libtool.m4 onceonly.m4 socklen.m4 sys_socket_h.m4 noexecstack.m4
+EXTRA_DIST += gpg-error.m4
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = m4
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = libtool.m4 onceonly.m4 socklen.m4 sys_socket_h.m4 \
+ noexecstack.m4 gpg-error.m4
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu m4/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# gpg-error.m4 - autoconf macro to detect libgpg-error.
+# Copyright (C) 2002, 2003, 2004 g10 Code GmbH
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+dnl AM_PATH_GPG_ERROR([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS
+dnl
+AC_DEFUN([AM_PATH_GPG_ERROR],
+[ AC_ARG_WITH(gpg-error-prefix,
+ AC_HELP_STRING([--with-gpg-error-prefix=PFX],
+ [prefix where GPG Error is installed (optional)]),
+ gpg_error_config_prefix="$withval", gpg_error_config_prefix="")
+ if test x$gpg_error_config_prefix != x ; then
+ if test x${GPG_ERROR_CONFIG+set} != xset ; then
+ GPG_ERROR_CONFIG=$gpg_error_config_prefix/bin/gpg-error-config
+ fi
+ fi
+
+ AC_PATH_TOOL(GPG_ERROR_CONFIG, gpg-error-config, no)
+ min_gpg_error_version=ifelse([$1], ,0.0,$1)
+ AC_MSG_CHECKING(for GPG Error - version >= $min_gpg_error_version)
+ ok=no
+ if test "$GPG_ERROR_CONFIG" != "no" ; then
+ req_major=`echo $min_gpg_error_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_gpg_error_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ gpg_error_config_version=`$GPG_ERROR_CONFIG $gpg_error_config_args --version`
+ major=`echo $gpg_error_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $gpg_error_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -ge "$req_minor"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags`
+ GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs`
+ AC_MSG_RESULT([yes ($gpg_error_config_version)])
+ ifelse([$2], , :, [$2])
+ if test x"$host" != x ; then
+ gpg_error_config_host=`$GPG_ERROR_CONFIG $gpg_error_config_args --host 2>/dev/null || echo none`
+ if test x"$gpg_error_config_host" != xnone ; then
+ if test x"$gpg_error_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script $GPG_ERROR_CONFIG was
+*** built for $gpg_error_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-gpg-error-prefix
+*** to specify a matching config script.
+***]])
+ fi
+ fi
+ fi
+ else
+ GPG_ERROR_CFLAGS=""
+ GPG_ERROR_LIBS=""
+ AC_MSG_RESULT(no)
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(GPG_ERROR_CFLAGS)
+ AC_SUBST(GPG_ERROR_LIBS)
+])
--- /dev/null
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+ [m4_default([$3],
+ [m4_fatal([Libtool version $1 or higher is required],
+ 63)])],
+ [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+ *\ * | *\ *)
+ AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename. Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+ case $cc_temp in
+ compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+ distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ _LT_PATH_MAGIC
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+ [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+ [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+ [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME. Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+ [m4_ifval([$1], [$1], [$2])])
+ lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+ m4_ifval([$4],
+ [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+ lt_dict_add_subkey([lt_decl_dict], [$2],
+ [tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+ [0], [m4_fatal([$0: too few arguments: $#])],
+ [1], [m4_fatal([$0: too few arguments: $#: $1])],
+ [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+ [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+ [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+ m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+ m4_if([$2], [],
+ m4_quote(lt_decl_varnames),
+ m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+ lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'. VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly. In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+# <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+ [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+# # Some comment about what VAR is for.
+# visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+ [description])))[]dnl
+m4_pushdef([_libtool_name],
+ m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+ [0], [_libtool_name=[$]$1],
+ [1], [_libtool_name=$lt_[]$1],
+ [2], [_libtool_name=$lt_[]$1],
+ [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script. Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+ m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+ [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'. Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+ dnl If the libtool generation code has been placed in $CONFIG_LT,
+ dnl instead of duplicating it all over again into config.status,
+ dnl then we will have config.status run $CONFIG_LT later, so it
+ dnl needs to know what name is stored there:
+ [AC_CONFIG_COMMANDS([libtool],
+ [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+ dnl If the libtool generation code is destined for config.status,
+ dnl expand the accumulated commands and init code now:
+ [AC_CONFIG_COMMANDS([libtool],
+ [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+ case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+ *[[\\\\\\\`\\"\\\$]]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+ lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+ ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+ echo
+ AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+ -h, --help print this help, then exit
+ -V, --version print version number, then exit
+ -q, --quiet do not print progress messages
+ -d, --debug don't remove temporary files
+
+Report bugs to <bug-libtool@gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+ case $[1] in
+ --version | --v* | -V )
+ echo "$lt_cl_version"; exit 0 ;;
+ --help | --h* | -h )
+ echo "$lt_cl_help"; exit 0 ;;
+ --debug | --d* | -d )
+ debug=: ;;
+ --quiet | --q* | --silent | --s* | -q )
+ lt_cl_silent=: ;;
+
+ -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+ *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+ esac
+ shift
+done
+
+if $lt_cl_silent; then
+ exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure. Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+ lt_cl_success=:
+ test "$silent" = yes &&
+ lt_config_lt_args="$lt_config_lt_args --quiet"
+ exec AS_MESSAGE_LOG_FD>/dev/null
+ $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+ exec AS_MESSAGE_LOG_FD>>config.log
+ $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars. Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+ m4_if(_LT_TAG, [C], [
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+ _LT_PROG_LTMAIN
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ _LT_PROG_XSI_SHELLFNS
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+# autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+ [C], [_LT_LANG(C)],
+ [C++], [_LT_LANG(CXX)],
+ [Java], [_LT_LANG(GCJ)],
+ [Fortran 77], [_LT_LANG(F77)],
+ [Fortran], [_LT_LANG(FC)],
+ [Windows Resource], [_LT_LANG(RC)],
+ [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+ [_LT_LANG($1)],
+ [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+ [LT_SUPPORTED_TAG([$1])dnl
+ m4_append([_LT_TAGS], [$1 ])dnl
+ m4_define([_LT_LANG_]$1[_enabled], [])dnl
+ _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [LT_LANG(CXX)],
+ [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+ [LT_LANG(F77)],
+ [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+ [LT_LANG(FC)],
+ [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+ [LT_LANG(GCJ)],
+ [m4_ifdef([AC_PROG_GCJ],
+ [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([A][M_PROG_GCJ],
+ [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+ m4_ifdef([LT_PROG_GCJ],
+ [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+ [LT_LANG(RC)],
+ [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+ case $host_os in
+ rhapsody* | darwin*)
+ AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+ AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+ AC_CHECK_TOOL([LIPO], [lipo], [:])
+ AC_CHECK_TOOL([OTOOL], [otool], [:])
+ AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+ _LT_DECL([], [DSYMUTIL], [1],
+ [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+ _LT_DECL([], [NMEDIT], [1],
+ [Tool to change global to local symbols on Mac OS X])
+ _LT_DECL([], [LIPO], [1],
+ [Tool to manipulate fat objects and archives on Mac OS X])
+ _LT_DECL([], [OTOOL], [1],
+ [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+ _LT_DECL([], [OTOOL64], [1],
+ [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+ AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+ [lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi])
+ AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+ [lt_cv_ld_exported_symbols_list],
+ [lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [lt_cv_ld_exported_symbols_list=yes],
+ [lt_cv_ld_exported_symbols_list=no])
+ LDFLAGS="$save_LDFLAGS"
+ ])
+ case $host_os in
+ rhapsody* | darwin1.[[012]])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[[012]]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+ m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_automatic, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=echo
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ m4_if([$1], [CXX],
+[ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+],[])
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+ [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+ # Yippee, $ECHO works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<_LT_EOF
+[$]*
+_LT_EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+ if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+ { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+ then
+ break
+ fi
+ done
+ fi
+
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+ else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ IFS="$lt_save_ifs"
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$dir/echo"
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+
+ if test "X$ECHO" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ ECHO='print -r'
+ elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ ECHO='printf %s\n'
+ if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ ECHO=echo
+ fi
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+ [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+ [AS_HELP_STRING([--disable-libtool-lock],
+ [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_PUSH(C)
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_POP])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+ [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+ [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$3"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ fi
+ $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$5], , :, [$5])
+else
+ m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+# [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+ [$2=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $3"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&AS_MESSAGE_LOG_FD
+ $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ $2=yes
+ fi
+ else
+ $2=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+ m4_if([$4], , :, [$4])
+else
+ m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+ = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+ AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+ AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+ [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}]
+_LT_EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_dlunknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ])
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+ [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+ [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+ [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+ [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&AS_MESSAGE_LOG_FD
+ echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+ fi
+ fi
+ chmod u+w . 2>&AS_MESSAGE_LOG_FD
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+ [Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+ [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+ test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+ test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+ test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+ # Linking always hardcodes the temporary library directory.
+ _LT_TAGVAR(hardcode_action, $1)=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ _LT_TAGVAR(hardcode_action, $1)=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+ test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+ [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+ [], [
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+ if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+ sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[[4-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[[45]]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+ if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+ # It is most probably a Windows format PATH printed by
+ # mingw gcc, but we are running on Cygwin. Gcc prints its search
+ # path with ; separators, and with drive letters. We can handle the
+ # drive letters (cygwin fileutils understands them), so leave them,
+ # especially as we might pass files found there to a mingw objdump,
+ # which wouldn't understand a cygwinified path. Ahh.
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+ else
+ sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+ fi
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[[123]]*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+interix[[3-9]]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # Some binutils ld are patched to set DT_RUNPATH
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+ [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+ [shlibpath_overrides_runpath=yes])])
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsdelf*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='NetBSD ld.elf_so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+ [Variables whose values should be saved in libtool wrapper scripts and
+ restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+ [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+ [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+ [[List of archive names. First name is the real one, the rest are links.
+ The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+ [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+ [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+ [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+ [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+ [[As "finish_cmds", except a single script fragment to be evaled but
+ not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+ [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+ [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+ [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] | ?:[\\/]*])
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="m4_if([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+ [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+ [AS_HELP_STRING([--with-gnu-ld],
+ [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+ [test "$withval" = no || with_gnu_ld=yes],
+ [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by $CC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | ?:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+ lt_cv_ld_reload_flag,
+ [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[[45]]*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ if ( file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[[3-9]]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+ [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+ [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+ AC_SUBST([DUMPBIN])
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+ [lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&AS_MESSAGE_LOG_FD
+ (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+ cat conftest.out >&AS_MESSAGE_LOG_FD
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+ # These system don't have libm, or don't need it
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, cos, LIBM="-lm")
+ ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+ _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+ lt_cv_prog_compiler_rtti_exceptions,
+ [-fno-rtti -fno-exceptions], [],
+ [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+ [Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[[ABCDEGRST]]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[[BCDEGRST]]'
+ ;;
+osf*)
+ symcode='[[BCDEGQRST]]'
+ ;;
+solaris*)
+ symcode='[[BDRT]]'
+ ;;
+sco3.2v5*)
+ symcode='[[DT]]'
+ ;;
+sysv4.2uw2*)
+ symcode='[[DT]]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[[ABDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK ['"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx]"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+ fi
+ else
+ echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+ [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+ [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+ [lt_cv_sys_global_symbol_to_c_name_address], [1],
+ [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+ [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+ [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[[4-9]]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ fi
+ ;;
+ aCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xlc* | xlC*)
+ # IBM XL 8.0 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd* | netbsdelf*-gnu)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+],
+[
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ else
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ m4_if([$1], [GCJ], [],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # PIC (with -KPIC) is the default.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+ ccc*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All Alpha code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+ xl*)
+ # IBM XL C 8.0/Fortran 10.1 on PPC
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C 5.9
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ ;;
+ *Sun\ F*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ # All OSF/1 code is PIC.
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ rdos*)
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ unicos*)
+ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+ ;;
+
+ *)
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+ ;;
+ esac
+ fi
+])
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ ;;
+ *)
+ _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+ ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+ [How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+ _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+ [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+ [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+ [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+ "" | " "*) ;;
+ *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+ esac],
+ [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+ _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+ [Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+ _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+ $lt_tmp_static_flag,
+ [],
+ [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+ [Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix[[4-9]]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ ;;
+ pw32*)
+ _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+ runpath_var=
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(archive_cmds, $1)=
+ _LT_TAGVAR(archive_expsym_cmds, $1)=
+ _LT_TAGVAR(compiler_needs_object, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ _LT_TAGVAR(hardcode_automatic, $1)=no
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ _LT_TAGVAR(hardcode_minus_L, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+ _LT_TAGVAR(inherit_rpath, $1)=no
+ _LT_TAGVAR(link_all_deplibs, $1)=unknown
+ _LT_TAGVAR(module_cmds, $1)=
+ _LT_TAGVAR(module_expsym_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+ _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+ _LT_TAGVAR(thread_safe_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ _LT_TAGVAR(include_expsyms, $1)=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ linux* | k*bsd*-gnu)
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ ;;
+ esac
+
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[[3-9]]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ tmp_sharedflag='--shared' ;;
+ xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+
+ if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+ runpath_var=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ else
+ _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=no
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)=''
+ ;;
+ m68k)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[[45]]*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+ # FIXME: Should let the user specify the lib program.
+ _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+ ;;
+
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ freebsd1*)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ AC_LINK_IFELSE(int foo(void) {},
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+ )
+ LDFLAGS="$save_LDFLAGS"
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ netbsd* | netbsdelf*-gnu)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ newsos6)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ else
+ case $host_os in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ os2*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ else
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ fi
+ _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ ;;
+
+ solaris*)
+ _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ ;;
+ motorola)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ sysv4.3*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+
+ *)
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+ [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+ # Assume -lc should be added
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $_LT_TAGVAR(archive_cmds, $1) in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+ pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+ _LT_TAGVAR(allow_undefined_flag, $1)=
+ if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+ then
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ else
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ fi
+ _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+ AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+ [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+ [enable_shared_with_static_runtimes], [0],
+ [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+ [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+ [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+ [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+ [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+ [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+ [Commands used to build a loadable module if different from building
+ a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+ [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+ [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+ [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+ [Flag to hardcode $libdir into a binary during linking.
+ This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+ [[If ld is used when linking, flag to hardcode $libdir into a binary
+ during linking. This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+ [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+ [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+ DIR into the resulting binary and the resulting library dependency is
+ "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+ library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+ [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+ [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+ into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+ [Set to "yes" if building a shared library automatically hardcodes DIR
+ into the library and all subsequent libraries and executables linked
+ against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+ [Set to yes if linker adds runtime paths of dependent libraries
+ to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+ [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+ [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+ [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+ [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+ [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+ [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+ [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+ [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+ LT_SYS_DLOPEN_SELF
+ _LT_CMD_STRIPLIB
+
+ # Report which library types will actually be built
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ AC_PROG_CXXCPP
+else
+ _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined. These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+ else
+ _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+ LT_PATH_LD
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ _LT_TAGVAR(whole_archive_flag_spec, $1)=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ _LT_TAGVAR(archive_cmds, $1)=''
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ _LT_TAGVAR(hardcode_direct, $1)=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ _LT_TAGVAR(always_export_symbols, $1)=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+ _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ _LT_SYS_MODULE_PATH_AIX
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+ # Exported symbols can be pulled into shared objects from archives
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+ # as there is no search path for DLLs.
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+ _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+ _LT_TAGVAR(always_export_symbols, $1)=no
+ _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+ _LT_DARWIN_LINKER_FEATURES($1)
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ freebsd[[12]]*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ freebsd-elf*)
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ hpux9*)
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ ;;
+ *)
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[[3-9]]*)
+ _LT_TAGVAR(hardcode_direct, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+ fi
+ fi
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ ;;
+ esac
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+ _LT_TAGVAR(inherit_rpath, $1)=yes
+ ;;
+
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+ _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $RANLIB $oldlib'
+ _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 will use weak symbols
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ xl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+ _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ _LT_TAGVAR(ld_shlibs, $1)=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ _LT_TAGVAR(hardcode_direct, $1)=yes
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+ _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=echo
+ else
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+ _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+ output_verbose_link_cmd='echo'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+ fi
+
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *)
+ _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+ _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+ _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+ _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+ _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+ _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+ _LT_TAGVAR(link_all_deplibs, $1)=yes
+ _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ _LT_TAGVAR(ld_shlibs, $1)=no
+ ;;
+ esac
+
+ AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+ test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+ _LT_TAGVAR(GCC, $1)="$GXX"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library. It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer*4 a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+ subroutine foo
+ implicit none
+ integer a
+ a=0
+ return
+ end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+ private int a;
+ public void bar (void) {
+ a = 0;
+ }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+ _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+ else
+ _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+ _LT_TAGVAR(predep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+ fi
+ else
+ if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+ _LT_TAGVAR(postdep_objects, $1)="$p"
+ else
+ _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ _LT_TAGVAR(predep_objects,$1)=
+ _LT_TAGVAR(postdep_objects,$1)=
+ _LT_TAGVAR(postdeps,$1)=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+ [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+ [Dependencies to place before and after the objects being linked to
+ create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+ [The library search path used internally by the compiler when linking
+ a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+ _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${F77-"f77"}
+ compiler=$CC
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+ GCC=$G77
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$G77"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+ _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="\
+ subroutine t
+ return
+ end
+"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code="\
+ program t
+ end
+"
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+ _LT_TAG_COMPILER
+
+ # save warnings/boilerplate of simple test code
+ _LT_COMPILER_BOILERPLATE
+ _LT_LINKER_BOILERPLATE
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC="$CC"
+ lt_save_GCC=$GCC
+ CC=${FC-"f95"}
+ compiler=$CC
+ GCC=$ac_cv_fc_compiler_gnu
+
+ _LT_TAGVAR(compiler, $1)=$CC
+ _LT_CC_BASENAME([$compiler])
+
+ if test -n "$compiler"; then
+ AC_MSG_CHECKING([if libtool supports shared libraries])
+ AC_MSG_RESULT([$can_build_shared])
+
+ AC_MSG_CHECKING([whether to build shared libraries])
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+ aix[[4-9]]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ AC_MSG_RESULT([$enable_shared])
+
+ AC_MSG_CHECKING([whether to build static libraries])
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ AC_MSG_RESULT([$enable_static])
+
+ _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+ _LT_TAGVAR(LD, $1)="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ _LT_SYS_HIDDEN_LIBDEPS($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_SYS_DYNAMIC_LINKER($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+ fi # test -n "$compiler"
+
+ GCC=$lt_save_GCC
+ CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+ _LT_COMPILER_NO_RTTI($1)
+ _LT_COMPILER_PIC($1)
+ _LT_COMPILER_C_O($1)
+ _LT_COMPILER_FILE_LOCKS($1)
+ _LT_LINKER_SHLIBS($1)
+ _LT_LINKER_HARDCODE_LIBPATH($1)
+
+ _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined. These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+ :
+ _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+ [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+ [AC_CHECK_TOOL(GCJ, gcj,)
+ test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+ AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible. Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+ [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into #
+# GNU Autoconf as AC_PROG_SED. When it is available in #
+# a released version of Autoconf we should remove this #
+# macro and use it instead. #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for lt_ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+ lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+ fi
+ done
+ done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+ test ! -f $lt_ac_sed && continue
+ cat /dev/null > conftest.in
+ lt_ac_count=0
+ echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+ # Check for GNU sed and select it if it is found.
+ if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+ lt_cv_path_SED=$lt_ac_sed
+ break
+ fi
+ while true; do
+ cat conftest.in conftest.in >conftest.tmp
+ mv conftest.tmp conftest.in
+ cp conftest.in conftest.nl
+ echo >>conftest.nl
+ $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+ cmp -s conftest.out conftest.nl || break
+ # 10000 chars as input seems more than enough
+ test $lt_ac_count -gt 10 && break
+ lt_ac_count=`expr $lt_ac_count + 1`
+ if test $lt_ac_count -gt $lt_ac_max; then
+ lt_ac_max=$lt_ac_count
+ lt_cv_path_SED=$lt_ac_sed
+ fi
+ done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "X${3}" \
+ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]+=\$[2]"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+ ;;
+ esac
+])
--- /dev/null
+# Helper functions for option handling. -*- Autoconf -*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it. Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+ _LT_MANGLE_DEFUN([$1], [$2]),
+ [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+ [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME. If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+ [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+ dnl
+ dnl Simply set some default values (i.e off) if boolean options were not
+ dnl specified:
+ _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+ ])
+ _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+ ])
+ dnl
+ dnl If no reference was made to various pairs of opposing options, then
+ dnl we run the default mode handler for the pair. For example, if neither
+ dnl `shared' nor `disable-shared' was passed, we enable building of shared
+ dnl archives by default:
+ _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+ _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+ _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+ [_LT_ENABLE_FAST_INSTALL])
+ ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS], [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+ [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+ [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+ _LT_DECL([build_libtool_libs], [enable_shared], [0],
+ [Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+ [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+ [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+ _LT_DECL([build_old_libs], [enable_static], [0],
+ [Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+ [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+ [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+ [p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac],
+ [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+ [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+ [AS_HELP_STRING([--with-pic],
+ [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+ [pic_mode="$withval"],
+ [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+ [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+ [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+ [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+ [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+ [m4_define([_LTDL_TYPE], [convenience])])
--- /dev/null
+# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+ [$#], [2], [[$2]],
+ [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+ [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+ [$#], 1, [],
+ [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+ m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+ [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+ [m4_foreach([_Lt_suffix],
+ ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+ [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+ [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+ [lt_append([$1], [$2], [$3])$4],
+ [$5])],
+ [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+ m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+ m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+ [$5],
+ [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+ [lt_join(m4_quote(m4_default([$4], [[, ]])),
+ lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+ [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
--- /dev/null
+# ltversion.m4 -- version numbers -*- Autoconf -*-
+#
+# Copyright (C) 2004 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3017 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6b])
+m4_define([LT_PACKAGE_REVISION], [1.3017])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6b'
+macro_revision='1.3017'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
--- /dev/null
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+# Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else. This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
--- /dev/null
+# noexecstack.m4
+dnl Copyright (C) 1995-2006 Free Software Foundation, Inc.
+dnl
+dnl This library is free software; you can redistribute it and/or
+dnl modify it under the terms of the GNU Lesser General Public
+dnl License as published by the Free Software Foundation; either
+dnl version 2.1 of the License, or (at your option) any later version.
+dnl
+dnl This library is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl Lesser General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU Lesser General Public
+dnl License along with this library; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+dnl Checks whether the stack can be marked nonexecutable by passing an
+dnl option to the C-compiler when acting on .s files. Returns that
+dnl option in NOEXECSTACK_FLAGS.
+dnl This macro is adapted from one found in GLIBC-2.3.5.
+AC_DEFUN([CL_AS_NOEXECSTACK],[
+AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([AM_PROG_AS])
+
+AC_MSG_CHECKING([whether non excutable stack support is requested])
+AC_ARG_ENABLE(noexecstack,
+ AC_HELP_STRING([--disable-noexecstack],
+ [disable non executable stack support]),
+ noexecstack_support=$enableval, noexecstack_support=yes)
+AC_MSG_RESULT($noexecstack_support)
+
+AC_CACHE_CHECK([whether assembler supports --noexecstack option],
+cl_cv_as_noexecstack, [dnl
+ cat > conftest.c <<EOF
+void foo() {}
+EOF
+ if AC_TRY_COMMAND([${CC} $CFLAGS $CPPFLAGS
+ -S -o conftest.s conftest.c >/dev/null]) \
+ && grep .note.GNU-stack conftest.s >/dev/null \
+ && AC_TRY_COMMAND([${CCAS} $CCASFLAGS $CPPFLAGS -Wa,--noexecstack
+ -c -o conftest.o conftest.s >/dev/null])
+ then
+ cl_cv_as_noexecstack=yes
+ else
+ cl_cv_as_noexecstack=no
+ fi
+ rm -f conftest*])
+ if test "$noexecstack_support" = yes -a "$cl_cv_as_noexecstack" = yes; then
+ NOEXECSTACK_FLAGS="-Wa,--noexecstack"
+ else
+ NOEXECSTACK_FLAGS=
+ fi
+ AC_SUBST(NOEXECSTACK_FLAGS)
+])
--- /dev/null
+# onceonly.m4 serial 4 (gettext-0.15)
+dnl Copyright (C) 2002-2003, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file defines some "once only" variants of standard autoconf macros.
+dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS
+dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS
+dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS
+dnl AC_REQUIRE([AC_HEADER_STDC]) like AC_HEADER_STDC
+dnl The advantage is that the check for each of the headers/functions/decls
+dnl will be put only once into the 'configure' file. It keeps the size of
+dnl the 'configure' file down, and avoids redundant output when 'configure'
+dnl is run.
+dnl The drawback is that the checks cannot be conditionalized. If you write
+dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi
+dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to
+dnl empty, and the check will be inserted before the body of the AC_DEFUNed
+dnl function.
+
+dnl This file is only needed in autoconf <= 2.59. Newer versions of autoconf
+dnl have this macro built-in. But about AC_CHECK_DECLS_ONCE: note that in
+dnl autoconf >= 2.60 the symbol separator is a comma, whereas here it is
+dnl whitespace.
+
+dnl Autoconf version 2.57 or newer is recommended.
+AC_PREREQ(2.54)
+
+# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of
+# AC_CHECK_HEADERS(HEADER1 HEADER2 ...).
+AC_DEFUN([AC_CHECK_HEADERS_ONCE], [
+ :
+ AC_FOREACH([gl_HEADER_NAME], [$1], [
+ AC_DEFUN([gl_CHECK_HEADER_]m4_quote(translit(m4_defn([gl_HEADER_NAME]),
+ [-./], [___])), [
+ AC_CHECK_HEADERS(gl_HEADER_NAME)
+ ])
+ AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(translit(gl_HEADER_NAME,
+ [-./], [___])))
+ ])
+])
+
+# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of
+# AC_CHECK_FUNCS(FUNC1 FUNC2 ...).
+AC_DEFUN([AC_CHECK_FUNCS_ONCE], [
+ :
+ AC_FOREACH([gl_FUNC_NAME], [$1], [
+ AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [
+ AC_CHECK_FUNCS(m4_defn([gl_FUNC_NAME]))
+ ])
+ AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]))
+ ])
+])
+
+# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of
+# AC_CHECK_DECLS(DECL1, DECL2, ...).
+AC_DEFUN([AC_CHECK_DECLS_ONCE], [
+ :
+ AC_FOREACH([gl_DECL_NAME], [$1], [
+ AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [
+ AC_CHECK_DECLS(m4_defn([gl_DECL_NAME]))
+ ])
+ AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]))
+ ])
+])
--- /dev/null
+# socklen.m4 serial 4
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Albert Chin, Windows fixes from Simon Josefsson.
+
+dnl Check for socklen_t: historically on BSD it is an int, and in
+dnl POSIX 1g it is a type of its own, but some platforms use different
+dnl types for the argument to getsockopt, getpeername, etc. So we
+dnl have to test to find something that will work.
+
+dnl On mingw32, socklen_t is in ws2tcpip.h ('int'), so we try to find
+dnl it there first. That file is included by gnulib's socket_.h, which
+dnl all users of this module should include. Cygwin must not include
+dnl ws2tcpip.h.
+AC_DEFUN([gl_TYPE_SOCKLEN_T],
+ [AC_REQUIRE([gl_HEADER_SYS_SOCKET])dnl
+ AC_CHECK_TYPE([socklen_t], ,
+ [AC_MSG_CHECKING([for socklen_t equivalent])
+ AC_CACHE_VAL([gl_cv_gl_cv_socklen_t_equiv],
+ [# Systems have either "struct sockaddr *" or
+ # "void *" as the second argument to getpeername
+ gl_cv_socklen_t_equiv=
+ for arg2 in "struct sockaddr" void; do
+ for t in int size_t "unsigned int" "long int" "unsigned long int"; do
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>
+ #include <sys/socket.h>
+
+ int getpeername (int, $arg2 *, $t *);],
+ [$t len;
+ getpeername (0, 0, &len);],
+ [gl_cv_socklen_t_equiv="$t"])
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ test "$gl_cv_socklen_t_equiv" != "" && break
+ done
+ ])
+ if test "$gl_cv_socklen_t_equiv" = ""; then
+ AC_MSG_ERROR([Cannot find a type to use in place of socklen_t])
+ fi
+ AC_MSG_RESULT([$gl_cv_socklen_t_equiv])
+ AC_DEFINE_UNQUOTED([socklen_t], [$gl_cv_socklen_t_equiv],
+ [type to use in place of socklen_t if not defined])],
+ [#include <sys/types.h>
+ #if HAVE_SYS_SOCKET_H
+ # include <sys/socket.h>
+ #elif HAVE_WS2TCPIP_H
+ # include <ws2tcpip.h>
+ #endif])])
--- /dev/null
+# sys_socket_h.m4 serial 2
+dnl Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Simon Josefsson.
+
+AC_DEFUN([gl_HEADER_SYS_SOCKET],
+[
+ AC_CHECK_HEADERS_ONCE([sys/socket.h])
+ if test $ac_cv_header_sys_socket_h = yes; then
+ SYS_SOCKET_H=''
+ else
+ dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+ dnl the check for those headers unconditional; yet cygwin reports
+ dnl that the headers are present but cannot be compiled (since on
+ dnl cygwin, all socket information should come from sys/socket.h).
+ AC_CHECK_HEADERS([winsock2.h ws2tcpip.h])
+ SYS_SOCKET_H='sys/socket.h'
+ fi
+ AC_SUBST(SYS_SOCKET_H)
+])
--- /dev/null
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program 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 General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+ # Try to run requested program, and just exit if it succeeds.
+ run=
+ shift
+ "$@" && exit 0
+ # Exit code 63 means version mismatch. This often happens
+ # when the user try to use an ancient version of a tool on
+ # a file that requires a minimum version. In this case we
+ # we should proceed has if the program had been absent, or
+ # if --run hadn't been passed.
+ if test $? = 63; then
+ run=:
+ msg="probably too old"
+ fi
+ ;;
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+ --run try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ help2man touch the output file
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ tar try tar, gnutar, gtar, then tar without non-portable flags
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+ exit $?
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing $scriptversion (GNU Automake)"
+ exit $?
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+esac
+
+# Now exit if we have it, but it failed. Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+ lex|yacc)
+ # Not GNU programs, they don't have --version.
+ ;;
+
+ tar)
+ if test -n "$run"; then
+ echo 1>&2 "ERROR: \`tar' requires --run"
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ exit 1
+ fi
+ ;;
+
+ *)
+ if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+ # We have it, but it failed.
+ exit 1
+ elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+ # Could not run --version or --help. This is probably someone
+ # running `$TOOL --version' or `$TOOL --help' to check whether
+ # $TOOL exists and not knowing $TOOL uses missing.
+ exit 1
+ fi
+ ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+ aclocal*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acinclude.m4' or \`${configure_ac}'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`${configure_ac}'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`acconfig.h' or \`${configure_ac}'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake*)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ autom4te)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them.
+ You can get \`$1' as part of \`Autoconf' from any GNU
+ archive site."
+
+ file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+ test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+ if test -f "$file"; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo "#! /bin/sh"
+ echo "# Created by GNU Automake missing as a replacement of"
+ echo "# $ $@"
+ echo "exit 0"
+ chmod +x $file
+ exit 1
+ fi
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' $msg. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ help2man)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a dependency of a manual page. You may need the
+ \`Help2man' package in order for those modifications to take
+ effect. You can get \`Help2man' from any GNU archive site."
+
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+ fi
+ if [ -f "$file" ]; then
+ touch $file
+ else
+ test -z "$file" || exec >$file
+ echo ".ab help2man is required to generate this page"
+ exit 1
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is $msg. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ # The file to touch is that specified with -o ...
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ # ... or it is the one specified with @setfilename ...
+ infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+ # ... or it is derived from the source name (dir/f.texi becomes f.info)
+ test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+ fi
+ # If the file does not exist, the user really needs makeinfo;
+ # let's fail without touching anything.
+ test -f $file || exit 1
+ touch $file
+ ;;
+
+ tar)
+ shift
+
+ # We have already tried tar in the generic part.
+ # Look for gnutar/gtar before invocation to avoid ugly error
+ # messages.
+ if (gnutar --version > /dev/null 2>&1); then
+ gnutar "$@" && exit 0
+ fi
+ if (gtar --version > /dev/null 2>&1); then
+ gtar "$@" && exit 0
+ fi
+ firstarg="$1"
+ if shift; then
+ case "$firstarg" in
+ *o*)
+ firstarg=`echo "$firstarg" | sed s/o//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ case "$firstarg" in
+ *h*)
+ firstarg=`echo "$firstarg" | sed s/h//`
+ tar "$firstarg" "$@" && exit 0
+ ;;
+ esac
+ fi
+
+ echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+ You may want to install GNU tar or Free paxutils, or check the
+ command line arguments."
+ exit 1
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+ You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequisites for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2006-05-11.19
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+nl='
+'
+IFS=" "" $nl"
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+ case $1 in
+ -h | --help | --h*) # -h for help
+ echo "$usage"
+ exit $?
+ ;;
+ -m) # -m PERM arg
+ shift
+ test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+ dirmode=$1
+ shift
+ ;;
+ --version)
+ echo "$0 $scriptversion"
+ exit $?
+ ;;
+ --) # stop option processing
+ shift
+ break
+ ;;
+ -*) # unknown option
+ echo "$usage" 1>&2
+ exit 1
+ ;;
+ *) # first non-opt arg
+ break
+ ;;
+ esac
+done
+
+for file
+do
+ if test -d "$file"; then
+ shift
+ else
+ break
+ fi
+done
+
+case $# in
+ 0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error. This is a problem when calling mkinstalldirs
+# from a parallel make. We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+ '')
+ if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+ echo "mkdir -p -- $*"
+ exec mkdir -p -- "$@"
+ else
+ # On NextStep and OpenStep, the `mkdir' command does not
+ # recognize any option. It will interpret all options as
+ # directories to create, and then abort because `.' already
+ # exists.
+ test -d ./-p && rmdir ./-p
+ test -d ./--version && rmdir ./--version
+ fi
+ ;;
+ *)
+ if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+ test ! -d ./--version; then
+ echo "mkdir -m $dirmode -p -- $*"
+ exec mkdir -m "$dirmode" -p -- "$@"
+ else
+ # Clean up after NextStep and OpenStep mkdir.
+ for d in ./-m ./-p ./--version "./$dirmode";
+ do
+ test -d $d && rmdir $d
+ done
+ fi
+ ;;
+esac
+
+for file
+do
+ case $file in
+ /*) pathcomp=/ ;;
+ *) pathcomp= ;;
+ esac
+ oIFS=$IFS
+ IFS=/
+ set fnord $file
+ shift
+ IFS=$oIFS
+
+ for d
+ do
+ test "x$d" = x && continue
+
+ pathcomp=$pathcomp$d
+ case $pathcomp in
+ -*) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ else
+ if test ! -z "$dirmode"; then
+ echo "chmod $dirmode $pathcomp"
+ lasterr=
+ chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+ if test ! -z "$lasterr"; then
+ errstatus=$lasterr
+ fi
+ fi
+ fi
+ fi
+
+ pathcomp=$pathcomp/
+ done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
--- /dev/null
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp): Allow comparing of opaque MPIs.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-02-22 Aurelien Jarno <aurel32@debian.org> (wk)
+
+ * longlong.h (umul_ppmm) <mips> [__GNUC__ >= 4.4]: Patch according
+ to recommended gcc 4.4 changes.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * config.links: Remove asm modules for all sparc64. This is
+ debian#560028.
+
+2009-05-26 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Allow zero-sized MPIs (i.e a
+ zero).
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c: Remove memory.h.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is
+ larger than the buffer (potential problem). Do not print error
+ messages.
+ (mpi_fromstr): Return an error instead of hitting an assert.
+ (gcry_mpi_scan) <PGP>: Fix potential double free problem.
+ (gcry_mpi_scan) <HEX>: Fix potential memory leak.
+ (do_get_buffer): Return NULL on memory allocation failure.
+ (gcry_mpi_print): Check result of do_get_buffer.
+ (gcry_mpi_aprint): Return error on a memory allocation failure.
+
+ * mpicoder.c: Re-indent.
+
+2008-12-03 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Fix last change. Asserts are really
+ useful!
+
+2008-12-02 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Re-indent.
+ (gcry_mpi_powm): Simplified allocation of the result to fix a
+ double free bug. This is bug#977. Reported by Haakon Ringberg.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): Actually implement.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_lshift): New.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * mpi-mod.c (gcry_mpi_mod): Remove
+ * mpi-inv.c (_gcry_mpi_invm): Remove _ prefix.
+ * mpiutil.c (_gcry_mpi_swap): Remove.
+ (_gcry_mpi_new): Remove.
+ (_gcry_mpi_snew): Remove.
+ (gcry_mpi_invm): Remove.
+ (gcry_mpi_copy): Remove and rename _version to this.
+ (gcry_mpi_set, gcry_mpi_set_ui): Merge with _ version.
+ * mpi-inv.c (gcry_mpi_invm): Remove _ prefix and return 1.
+ * mpi-mul.c (gcry_mpi_mul_2exp): Remove and rename _ version to this.
+
+2007-10-29 Werner Koch <wk@g10code.com>
+
+ * config.links: No Candadian Cross here, thus use $host instead of
+ $target.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Special rules for Apple
+ Darwin on ia32 from Gregor Riepl.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Rename assembler file links by suffixing "-asm".
+ * Makefile.am (CCASCOMPILE, LTCCASCOMPILE, CLEANFILES,
+ libmpi_la_LIBADD, libmpi_la_DEPENDENCIES, SUFFIXES, .S.o, .S.obj,
+ .S.lo): Removed variables and targets.
+ (mpih_add1, mpih_sub1, mpih_mul1, mpih_mul2, mpih_mul3,
+ mpih_lshift, mpih_rshift, mpih_udiv, mpih_udiv_qrnnd,
+ nodist_libmpi_la_SOURCES): New variables.
+ (DISTCLEANFILES): Rename assembler file links by suffixing "-asm".
+ Add variants for C file links.
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * config.links (path): Allowthe sue of colons as delimiters.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * pentium4/distfiles: Fixed.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * config.links: Create a file mod-source-info.h.
+ * Makefile.am (DISTCLEANFILES): Add that file.
+ * mpiutil.c (_gcry_mpi_get_hw_config): New.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * config.links: Add additional assembler search directories.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * ec.c: New.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (_gcry_mpi_lshift_limbs): Assign AP after the resize.
+
+ * mpi-div.c (gcry_mpi_mod, _gcry_mpi_mod): Moved to ..
+ * mpi-mod.c: .. new file.
+ (_gcry_mpi_barrett_init, _gcry_mpi_barrett_free): New.
+ (_gcry_mpi_mod_barrett): New.
+ (_gcry_mpi_mul_barrett): New.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi-div.c (_gcry_mpi_mod): New.
+ * mpiutil.c (_gcry_mpi_new, _gcry_mpi_snew): New.
+
+2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
+
+ * amd64/mpih-add1.S, amd64/mpih-add1.S, amd64/mpih-lshift.S
+ * amd64/mpih-mul1.S, amd64/mpih-mul2.S, amd64/mpih-mul3.S
+ * amd64/mpih-rshift.S, amd64/mpih-sub1.S: New.
+ * config.links: Add case for x86_64.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * mpi-pow.c (gcry_mpi_powm): Remove unused var ESIGN.
+
+ * mpiutil.c (gcry_mpi_get_flag): Let it return a value to silent
+ MIPSpro cc warning.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * mpicoder.c (_gcry_mpi_set_buffer): Made BUFFER a void*.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.S.o): Check for srcdir also in in CPP pass.
+ (INCLUDES): Removed.
+ (AM_CPPFLAGS, AM_CFLAGS): New, modified. Merged with Moritz'
+ changes.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Make sure that powerpc64 is
+ matched before a generic powerpc. Reported by Andreas Metzler.
+ Should fix Debian bug 284609.
+
+2006-08-25 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Don't shift if N == 0 but do a
+ plain copy.
+
+2006-08-04 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_rshift): Rewritten to remove the limitation
+ on N (which used to be less than BITS_PER_MPI_LIMB).
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit): Fixed
+ allocation. Reported by bpgcrypt at itaparica.org.
+ * mpiutil.c (_gcry_mpi_resize): Clear the new part of the resized
+ limb space.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Changed P to unsigned char*.
+
+ * mpicoder.c (gcry_mpi_scan): Changed arg BUFFER to void*.
+ (mpi_read_from_buffer): Made BUFFER arg const.
+ (gcry_mpi_scan): Removed now needless cast. Add cast for arg to
+ mpi_fromstr.
+ (gcry_mpi_print): Made TMP unsigned.
+
+ * Makefile.am (AM_CCASFLAGS): New.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-cmp.c (gcry_mpi_cmp_ui): Rewritten; correctly handle case of
+ zero limbs in U.
+
+2005-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (gcry_mpi_randomize): Store random data in secure
+ memory if the given MPI is secure - not the other way around (argl).
+
+2005-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Don't assume the compiler will pre-process the .S
+ files. Some compilers, like those from HP and IBM, don't do
+ this. So, we use the same solution gnupg-1.4.0 does. Preprocess
+ first and then compile.
+
+ * hppa1.1/mpih-mul3.S: Add "level 1.1" directive to disable
+ warning about using PA-RISC1.1 opcodes.
+ * hppa1.1/mpih-mul2.S: Likewise.
+ * hppa1.1/mpih-mul1.S: Likewise.
+ * hppa1.1/udiv-qrnnd.S: Likewise.
+
+2005-02-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Rewritten, fixed memory
+ corruption.
+
+2005-02-06 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_get_ui, gcry_mpi_get_ui): New functions.
+
+2005-01-05 Werner Koch <wk@g10code.com>
+
+ * hppa1.1/udiv-qrnnd.S: Reverted change of 2004-03-02 but kept the
+ .align directive.
+
+2004-12-16 Werner Koch <wk@g10code.com>
+
+ * config.links (mpi_optional_modules): Move entry for powerpc64
+ before generic powerpc. Suggested by Rafael Ávila de Espíndola.
+
+2004-03-02 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Alignment fix from Lamont Jones for
+ Debian. Taken from gnupg-1.3.
+
+ * longlong.h: Added PowerPC 64 bit code from GPM-4.1.2 but didn't
+ enable it yet. Some whitespace changes in HPPA to fix assembler
+ problems on HP-UX. From gnupg 1.3
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Better allocate
+ something even if NLIMBS is passed as 0.
+
+ * config.links: Updated system list to match gnupg 1.3.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h [M_DEBUG]: Removed this unused code.
+ (struct karatsuba_ctx): Added TSPACE_NLIMBS and TP_NLIMBS.
+ * mpiutil.c (_gcry_mpi_free_limb_space): Add arg NLIMBS and wipe
+ out the memory. Changed all callers.
+ * mpih-mul.c (_gcry_mpih_mul_karatsuba_case): Keep track of
+ allocated limbs.
+ * mpi-div.c (_gcry_mpi_tdiv_qr): Keep track of allocated limbs.
+ * mpi-mul.c (gcry_mpi_mul): Ditto.
+ * mpi-pow.c (gcry_mpi_powm): Ditto.
+
+ * Manifest: Empty new file. Also add Manifest files to all CPU
+ specific directories.
+ * Makefile.am: Added.
+
+ * mpiutil.c (gcry_mpi_randomize): Use gcry_create_nonce if WEAK
+ random has been requested.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * i386/mpih-rshift.S, i386/mpih-lshift.S: Use %dl and not %edx for
+ testb; this avoids an assembler warning.
+
+ * mpi-pow.c (gcry_mpi_powm): s/exp/expo/ to avoid shadowing warning.
+
+2003-08-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (SUFFIXES): New variable.
+ (.S.o, .S.lo, .S.obj): Rewritten.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h (__clz_tab): Renamed to _gcry_clz_tab.
+ * mpi-bit.c (__clz_tab): Likewise.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): New argument BUFLEN to replace the
+ use of the intial value of NBYTES. Changed BUFFER to unsigned.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_dump): New.
+ (_gcry_log_mpidump): Make use of gcry_mpi_dump.
+ (mpi_print): Removed.
+ (gcry_mpi_scan): Allocated mpi in secure memory when required.
+ (gcry_mpi_aprint): Changed BUFFER to unsigned char*.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c: Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * mpi-add.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi-bit.c: Likewise.
+ * mpi-cmp.c: Likewise.
+ * mpi-div.c: Likewise.
+ * mpi-gcd.c: Likewise.
+ * mpi-internal.h: Likewise.
+ * mpi-inv.c: Likewise.
+ * mpi-mpow.c: Likewise.
+ * mpi-mul.c: Likewise.
+ * mpi-pow.c: Likewise.
+ * mpi-scan.c: Likewise.
+ * mpicoder.c: Likewise.
+ * mpiutil.c: Likewise.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * mpicoder.c (gcry_mpi_scan): Adjust for libgpg-error.
+ (gcry_mpi_print): Likewise.
+ (gcry_mpi_aprint): Likewise.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * longlong.h, mpi-add.c, mpi-bit.c, mpi-cmp.c, mpi-div.c,
+ mpi-gcd.c, mpi-inline.c, mpi-inline.h, mpi-internal.h, mpi-inv.c,
+ mpi-mpow.c, mpi-mul.c, mpi-pow.c, mpi-scan.c, mpicoder.c,
+ mpih-div.c, mpih-mul.c, mpiutil.c, generic/mpi-asm-defs.h,
+ generic/mpih-add1.c, generic/mpih-lshift.c, generic/mpih-mul1.c,
+ generic/mpih-mul2.c, generic/mpih-mul3.c, generic/mpih-rshift.c,
+ generic/mpih-sub1.c, generic/udiv-w-sdiv.c, i386/syntax.h,
+ m68k/syntax.h, mips3/mpi-asm-defs.h, powerpc32/syntax.h: Edited
+ all preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_alloc_limb_space): Only try to allocate
+ memory in case the amount of bytes to allocate is non-zero.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * mpiutil.c (_gcry_mpi_resize): Allocate secure memory, in case
+ bit zero of `flags' is set.
+
+ * mpi-add.c (gcry_mpi_sub): Simplify function; always use a
+ temporary variable now.
+
+2003-04-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h (umul_ppmm): Support SH3 and SH4. Thanks to
+ kazuya.s@jp.yokogawa.com.
+
+2003-04-02 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_print): Fixed testing against possible
+ uninitialized LEN. Valgrinded by Nikos Mavroyanopoulos.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Removed some spaces between backslashes and newlines.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (gcry_mpi_mul_2exp): New. This was declared in
+ gcrypt.h but only implemented as internal function. Noted by Timo
+ but a few minutes to late for today's release.
+
+ * Makefile.am (DISTCLEANFILES): Include mpi-asm-defs.h
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Pass -DPIC. i386, PPC and Sparc code
+ require it. It worked for me because I am using the i586 code.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (.S.lo): Fixed for libtool build with --disable-shared.
+
+2002-07-24 Werner Koch <wk@gnupg.org>
+
+ * longlong.h: Replaced all K&R multiline strings by ISO ones for
+ the sake of modern compilers. Suggested by Marco Parrone.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * mpiutil.c (gcry_mpi_swap): New.
+
+ * mpi-div.c (gcry_mpi_div): New.
+ (gcry_mpi_mod): New.
+ * mpi-inv.c (gcry_mpi_invm): New.
+
+ * mpicoder.c (do_get_buffer): Make sure that we allocate at least
+ one byte.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * hppa1.1/udiv-qrnnd.S: Changes for PIC by Randolph Chung.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * config.links: Chnage the way the mpi modules are determined.
+ * Makefile.am: Revamped to better handle modules
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-04-18 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Don't use normalize on a NULL MPI.
+
+2002-03-20 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_read_from_buffer): Bail out on a zero length
+ buffer because we can't eventually do an malloc of this size.
+ Reported by Timo.
+
+2002-01-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-inv.c (_gcry_mpi_invm): Typo fixes, noted by Carlo Perassi.
+
+2001-11-01 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (gcry_mpi_scan): Allow to pass a nbytes as NULL or
+ with value 0 for format GCRY_FMT_SSH, so that the length is not
+ used for any checks, only the length stored in the bufer is used.
+ This is a nice format becuase we can just pass a buffer around and
+ don't need to care about its length.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * config.links: Changed the way the list of files to be
+ symlinked is returned.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * mpih-cmp.c: Removed and moved mpihelp_cmp to ..
+ * mpi-inline.h: .. here.
+
+ Major function renaming. All global functions are now prefixed
+ with _gcry_ or gcry_. Renamed also all mpihelp_ to just mpih_ so
+ that functions names are not getting to long an unreadable and for
+ better matching with the filenames.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * mpicoder.c (mpi_fromstr): Made static and assume that all input
+ is in hexformat.
+
+ Updated all CPU specific code with the one from GnuPG-1.0.5. This
+ is just a change of text formatting and the use of .label
+ instead of labels for hppa and pa7100.
+
+ * longlong.h: Fixes for ARM by Phil Blundell.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * mpi-mul.c (mpi_mul): Make sure that secret temporary results are
+ not stored in w. Suggested by Florian Weimer.
+
+ * config.links: Use i386 code for i386. According to tests by
+ Kevin Ryde the i586 code runs slow on i386 CPUs. Ditto for i786.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Removed mpi.h.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h: Put limb_t definition in an ifdef.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi-internal.h, mpi.h: Changed the way they are called and
+ introduced DID_MPI_LIMP_TYPEDEF hack. Very ugly, should all be
+ revamped.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * generic/mpi-asm-defs.h: New.
+ * mips3/mpi-asm-defs.h: New.
+ * config.links: Create a link to one of the above files.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * power/: Add all files from GMP for this CPU. Converted comments to
+ CPP comments because some ASes complain about ' in comments.
+
+ * config.links: Support for BSDI 4.x; by Wayne Chapeskie. Add support
+ for FreeBSD 5 and made the case stmt looking nicer; by Jun Kuriyama.
+ Add support for NetBSD.
+ (sparc8): Made the search path the same as sparc9
+ (sparc64-unknown-linux-gnu): use udiv module; by Adam Mitchell.
+
+ * Makefile.am: c/SFLAGS/ASFLAGS/. This has only been used by the
+ powerpc and actually never passed the -Wa,foo to the cc.
+
+ * mpih-div.c (mpihelp_divrem): The MPN_COPY_DECR copied one element
+ too many. This is a gmp2.0.2p9.txt patch.
+
+ * longlong.h (umul_ppmm): Fixes for ARM-4. By Sean MacLennan.
+
+ * mpi-internal.h (karatsuba_ctx): New.
+ * mpih-mul.c (mpihelp_release_karatsuba_ctx): New.
+ (mpihelp_mul_karatsuba_case): New.
+ (mpihelp_mul): Splitted to make use of the new functions.
+ * mpi-pow.c (mpi_powm): Make use of the new splitted function to avoid
+ multiple allocation of temporary memory during the karatsuba operations.
+ * mpi_mpow.c: Removed the unused Barrett code.
+
+2000-03-21 16:17:30 Werner Koch (wk@habibti.openit.de)
+
+ * config.links: Add support for FreeBSD 5.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (gcry_mpi_aprint): Now really returns the length.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * mpiutil.c: Removed all memory debugging code.
+
+ * mpicoder.c (gcry_mpi_aprint): New.
+
+ * Replaced all m_ memory functions by g10_ ones.
+
+Fri Dec 31 14:06:56 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpi-bit.c (gcry_mpi_get_nbits): New.
+
+ * mpiutil.c (mpi_set_secure): made static.
+ (gcry_mpi_get_flag): New.
+ (gcry_mpi_set_flag): New.
+ (gcry_mpi_clear_flag): New.
+ (mpi_set_opaque): renamed to gcry_mpi_set_opaque.
+ (mpi_get_opaque): renamed to gcry_mpi_get_opaque.
+
+Fri Dec 31 12:48:31 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (mpi_read_from_buffer): Made static.
+ (gcry_mpi_print): A buffer of NULL is now allowed to get the required
+ length back.
+ (mpi_get_keyid): Removed.
+ (mpi_print): Made static - should be removed.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am (INCLUDES): Add ../gcrypt.
+
+ * g10m.c : Removed.
+
+ * mpicoder.c (mpi_write): Removed.
+ (mpi_read): Removed.
+ (gcry_mpi_scan): New. Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_print): Ditto.
+
+ * mpi-pow.c (mpi_powm): Renamed to ...
+ (gcry_mpi_powm): ... this.
+
+ * mpiutil.c (gcry_mpi_new): New as a wrapper around the old function.
+ Taken from ../gcrypt/mpiapi.c.
+ (gcry_mpi_snew): Ditto.
+ (gcry_mpi_release): Ditto.
+ (gcry_mpi_copy): Ditto.
+ (gcry_mpi_set): Ditto.
+ (gcry_mpi_set_ui): Ditto.
+ (gcry_mpi_cmp): Ditto.
+ (gcry_mpi_cmp_ui): Ditto.
+ (gcry_mpi_randomize): Ditto.
+
+ * mpicoder.c (mpi_print): Removed the nbit_info kludge.
+ * mpi-bits.c (mpi_get_nbits): Replaced the is_protected stuff by
+ checking whether it is an opaque mpi and then returns it's length
+ in bits.
+ * mpiutil.c (mpi_set_opaque): Changed the interface to take a number
+ of bits for the length. Adjusted all users.
+ (mpi_get_opaque): Ditto.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * mpicoder.c (g10_log_mpidump): Add a temporary workaround
+
+ * mpih-mul.c (mpihelp_mul_n): s/m_is_ecure/g10_is_secure/
+
+ * mpiutil.c (mpi_alloc): Remved the debug mode because it has turned
+ out, that this feature was not very useful in the past. Use the
+ new alloc functions.
+ (mpi_alloc_secure): Ditto.
+ (mpi_alloc_limb_space): Ditto.
+ (mpi_free_limb_space): Ditto.
+ (mpi_resize): Ditto.
+ (mpi_free): Ditto.
+ (mpi_set_secure): Removed the debug stuff.
+ (mpi_set_opaque): Ditto.
+ (mpi_copy): Ditto.
+ (mpi_alloc_set_ui): Ditto.
+ (mpi_m_check): Use g10_ wrapper.
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * config.links: Add case label for DJGPP
+
+Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * Makefile.am: Use .s files as temporaries, disabled other .S rules.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpicoder.c (g10_log_mpidump): New.
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+
+ * mpi-bit.c (mpi_lshift_limbs,mpi_rshift_limbs): New.
+ * mpi-mpow.c (barrett_mulm): New but diabled.
+
+Tue Jun 1 16:01:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (i[56]86*-*-freebsdelf*): New.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links (sysdep.h): Not any more conditionally created.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpiutil.c (mpi_alloc_like): New.
+
+Mon Apr 26 17:48:15 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-add.c, mpih-sub.c: Removed
+ * mpi-inline.c: New.
+ * mpi-inline.h: Make it usable by mpi-inline.c.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpih-mul.c (mpihelp_mul_n): Fixed use of memory region.
+ (mpihelp_mul): Ditto.
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Explicit rules to invoke cpp on *.S
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Take advantage of the with_symbol_underscore macro.
+ Add support for freebsd 4.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mips3/mpih-sub1.S: Removed left over junk in last line. (Should I
+ blame me or my editor?).
+
+Sat Feb 13 12:04:43 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Removed the +=. Add MPI_OPT_FLAGS.
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-cmp.c (mpi_cmp_ui): Normalized the arg.
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * mpi-bit.c (mpi_normalize): New.
+ (mpi_get_nbits): Normalize the MPI.
+ * mpi-bit.c (mpi_cmp): Normalize the MPI before the compare.
+
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * config.links: Moved the case for powerpc*linux
+ * powerpcp32/*.S: Removed some underscores.
+
+Thu Nov 26 07:27:52 1998 Werner Koch <werner.koch@guug.de>
+
+ * config.links: Support for ppc with ELF
+ * powerpc32/syntax.h: New.
+ * powerpc32/*.S: Applied ELF patches (glibc patches)
+
+Tue Nov 10 19:31:37 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * power*/ : Started with stuff for PPC
+ * config.links: Some stuff for PPC.
+ * generic/udiv-w-sdiv.c: New but disabled.
+
+Tue Oct 27 12:37:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): Fixes for FreeBSD 3.0
+
+Wed Oct 14 09:59:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (freebsd): ELF patches from Jun Kuriyama.
+
+Thu Oct 8 13:28:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-mpow.c (mpi_mulpowm): Fixed mem leak (m_free/mpi_free).
+
+Thu Sep 17 18:08:50 1998 Werner Koch (wk@(none))
+
+ * hppa1.1/udiv-qrnnd.S: Fix from Steffen Zahn for HPUX 10.20
+
+Thu Aug 6 16:39:28 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * mpi-bit.c (mpi_set_bytes): Removed.
+
+Wed Aug 5 15:11:12 1998 Werner Koch (wk@(none))
+
+ * mpicoder.c (mpi_read_from_buffer): New.
+
+ * mpiutil.c (mpi_set_opaque): New.
+ (mpi_get_opaque): New.
+ (mpi_copy): Changed to support opauqe flag
+ (mpi_free): Ditto.
+
+Sat Jul 4 10:11:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_clear): Reset flags.
+ (mpi_set): Ditto.
+ (mpi_alloc_secure): Set flag to 1 and not ored the 1 in, tsss..
+
+Fri Jun 26 11:19:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpiutil.c (mpi_alloc): set nbits to 0.
+ (mpi_alloc_secure): Ditto.
+ (mpi_clear): Ditto.
+
+Thu Jun 25 11:50:01 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mips3/*.S: New
+
+Mon May 18 13:47:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: split mpih-shift into mpih-[lr]shift and
+ changed all implementations.
+ * mpi/alpha: add some new assembler stuff.
+
+Wed May 13 11:04:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Add support for MIPS
+
+Thu Apr 9 11:31:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_secure_buffer): New.
+
+Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links: Applied small fix from Ulf Möller.
+
+Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes
+ and changed all callers.
+
+Tue Mar 10 13:40:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi-bit.c (mpi_clear_highbit): New.
+
+Mon Mar 2 19:29:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am (DISTCLEANFILES): New
+
+Thu Feb 26 06:48:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links (X86_BROKEN_ALIGN): Added for some systems.
+
+Mon Feb 23 12:21:40 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * mpi/m68k/mpih-shift.S (Lspecial): Changed duplicate symbol.
+
+Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * config.links : Add detection of m68k cpus
+
+
+ Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+## Process this file with automake to produce Makefile.in
+# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# 1.5 leads to a combinatorial explosion due to all the conditionals
+# I was not able to build it with 64Megs - 1.6 fixes this.
+# not anymore required: AUTOMAKE_OPTIONS = 1.6
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+AM_ASFLAGS = $(MPI_SFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+
+EXTRA_DIST = Manifest config.links
+DISTCLEANFILES = mpi-asm-defs.h \
+ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
+ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
+ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
+ mpih-lshift.c mpih-rshift.c mpih-sub1.c \
+ sysdep.h mod-source-info.h
+
+# Beware: The following list is not a comment but grepped by
+# config.links to get the list of symlinked modules
+# Optional modules are marked with an O in the second column.
+#BEGIN_ASM_LIST
+# mpih-add1 C
+# mpih-sub1 C
+# mpih-mul1 C
+# mpih-mul2 C
+# mpih-mul3 C
+# mpih-lshift C
+# mpih-rshift C
+# udiv O
+# udiv-qrnnd O
+#END_ASM_LIST
+
+# Note: This function has not yet been implemented. There is only a dummy in
+# generic/
+# udiv-w-sdiv O
+
+# And we need to have conditionals for all modules because
+# we don't know whether they are .c or .S. Very ugly; I know.
+# Remember to define them all in configure.ac
+if MPI_MOD_ASM_MPIH_ADD1
+mpih_add1 = mpih-add1-asm.S
+else
+if MPI_MOD_C_MPIH_ADD1
+mpih_add1 = mpih-add1.c
+else
+mpih_add1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_SUB1
+mpih_sub1 = mpih-sub1-asm.S
+else
+if MPI_MOD_C_MPIH_SUB1
+mpih_sub1 = mpih-sub1.c
+else
+mpih_sub1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL1
+mpih_mul1 = mpih-mul1-asm.S
+else
+if MPI_MOD_C_MPIH_MUL1
+mpih_mul1 = mpih-mul1.c
+else
+mpih_mul1 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL2
+mpih_mul2 = mpih-mul2-asm.S
+else
+if MPI_MOD_C_MPIH_MUL2
+mpih_mul2 = mpih-mul2.c
+else
+mpih_mul2 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_MUL3
+mpih_mul3 = mpih-mul3-asm.S
+else
+if MPI_MOD_C_MPIH_MUL3
+mpih_mul3 = mpih-mul3.c
+else
+mpih_mul3 =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_LSHIFT
+mpih_lshift = mpih-lshift-asm.S
+else
+if MPI_MOD_C_MPIH_LSHIFT
+mpih_lshift = mpih-lshift.c
+else
+mpih_lshift =
+endif
+endif
+
+if MPI_MOD_ASM_MPIH_RSHIFT
+mpih_rshift = mpih-rshift-asm.S
+else
+if MPI_MOD_C_MPIH_RSHIFT
+mpih_rshift = mpih-rshift.c
+else
+mpih_rshift =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV
+udiv = udiv-asm.S
+else
+if MPI_MOD_C_UDIV
+udiv = udiv.c
+else
+udiv =
+endif
+endif
+
+if MPI_MOD_ASM_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd-asm.S
+else
+if MPI_MOD_C_UDIV_QRNND
+udiv_qrnnd = udiv-qrnnd.c
+else
+udiv_qrnnd =
+endif
+endif
+
+noinst_LTLIBRARIES = libmpi.la
+
+libmpi_la_LDFLAGS =
+nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
+ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
+ $(udiv) $(udiv_qrnnd)
+libmpi_la_SOURCES = longlong.h \
+ mpi-add.c \
+ mpi-bit.c \
+ mpi-cmp.c \
+ mpi-div.c \
+ mpi-gcd.c \
+ mpi-internal.h \
+ mpi-inline.h \
+ mpi-inline.c \
+ mpi-inv.c \
+ mpi-mul.c \
+ mpi-mod.c \
+ mpi-pow.c \
+ mpi-mpow.c \
+ mpi-scan.c \
+ mpicoder.c \
+ mpih-div.c \
+ mpih-mul.c \
+ mpiutil.c \
+ ec.c
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 1992, 1999, 2000, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# 1.5 leads to a combinatorial explosion due to all the conditionals
+# I was not able to build it with 64Megs - 1.6 fixes this.
+# not anymore required: AUTOMAKE_OPTIONS = 1.6
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = mpi
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+libmpi_la_LIBADD =
+am_libmpi_la_OBJECTS = mpi-add.lo mpi-bit.lo mpi-cmp.lo mpi-div.lo \
+ mpi-gcd.lo mpi-inline.lo mpi-inv.lo mpi-mul.lo mpi-mod.lo \
+ mpi-pow.lo mpi-mpow.lo mpi-scan.lo mpicoder.lo mpih-div.lo \
+ mpih-mul.lo mpiutil.lo ec.lo
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1.lo
+@MPI_MOD_ASM_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1-asm.lo
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_TRUE@am__objects_2 = mpih-sub1.lo
+@MPI_MOD_ASM_MPIH_SUB1_TRUE@am__objects_2 = mpih-sub1-asm.lo
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_TRUE@am__objects_3 = mpih-mul1.lo
+@MPI_MOD_ASM_MPIH_MUL1_TRUE@am__objects_3 = mpih-mul1-asm.lo
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_TRUE@am__objects_4 = mpih-mul2.lo
+@MPI_MOD_ASM_MPIH_MUL2_TRUE@am__objects_4 = mpih-mul2-asm.lo
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_TRUE@am__objects_5 = mpih-mul3.lo
+@MPI_MOD_ASM_MPIH_MUL3_TRUE@am__objects_5 = mpih-mul3-asm.lo
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_TRUE@am__objects_6 = mpih-lshift.lo
+@MPI_MOD_ASM_MPIH_LSHIFT_TRUE@am__objects_6 = mpih-lshift-asm.lo
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_TRUE@am__objects_7 = mpih-rshift.lo
+@MPI_MOD_ASM_MPIH_RSHIFT_TRUE@am__objects_7 = mpih-rshift-asm.lo
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_TRUE@am__objects_8 = udiv.lo
+@MPI_MOD_ASM_UDIV_TRUE@am__objects_8 = udiv-asm.lo
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_TRUE@am__objects_9 = udiv-qrnnd.lo
+@MPI_MOD_ASM_UDIV_QRNND_TRUE@am__objects_9 = udiv-qrnnd-asm.lo
+nodist_libmpi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3) $(am__objects_4) $(am__objects_5) \
+ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
+ $(am__objects_9)
+libmpi_la_OBJECTS = $(am_libmpi_la_OBJECTS) \
+ $(nodist_libmpi_la_OBJECTS)
+libmpi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(libmpi_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libmpi_la_SOURCES) $(nodist_libmpi_la_SOURCES)
+DIST_SOURCES = $(libmpi_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_ASFLAGS = $(MPI_SFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+EXTRA_DIST = Manifest config.links
+DISTCLEANFILES = mpi-asm-defs.h \
+ mpih-add1-asm.S mpih-mul1-asm.S mpih-mul2-asm.S mpih-mul3-asm.S \
+ mpih-lshift-asm.S mpih-rshift-asm.S mpih-sub1-asm.S asm-syntax.h \
+ mpih-add1.c mpih-mul1.c mpih-mul2.c mpih-mul3.c \
+ mpih-lshift.c mpih-rshift.c mpih-sub1.c \
+ sysdep.h mod-source-info.h
+
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_FALSE@mpih_add1 =
+@MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_TRUE@mpih_add1 = mpih-add1.c
+
+# Beware: The following list is not a comment but grepped by
+# config.links to get the list of symlinked modules
+# Optional modules are marked with an O in the second column.
+#BEGIN_ASM_LIST
+# mpih-add1 C
+# mpih-sub1 C
+# mpih-mul1 C
+# mpih-mul2 C
+# mpih-mul3 C
+# mpih-lshift C
+# mpih-rshift C
+# udiv O
+# udiv-qrnnd O
+#END_ASM_LIST
+
+# Note: This function has not yet been implemented. There is only a dummy in
+# generic/
+# udiv-w-sdiv O
+
+# And we need to have conditionals for all modules because
+# we don't know whether they are .c or .S. Very ugly; I know.
+# Remember to define them all in configure.ac
+@MPI_MOD_ASM_MPIH_ADD1_TRUE@mpih_add1 = mpih-add1-asm.S
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_FALSE@mpih_sub1 =
+@MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_TRUE@mpih_sub1 = mpih-sub1.c
+@MPI_MOD_ASM_MPIH_SUB1_TRUE@mpih_sub1 = mpih-sub1-asm.S
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_FALSE@mpih_mul1 =
+@MPI_MOD_ASM_MPIH_MUL1_FALSE@@MPI_MOD_C_MPIH_MUL1_TRUE@mpih_mul1 = mpih-mul1.c
+@MPI_MOD_ASM_MPIH_MUL1_TRUE@mpih_mul1 = mpih-mul1-asm.S
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_FALSE@mpih_mul2 =
+@MPI_MOD_ASM_MPIH_MUL2_FALSE@@MPI_MOD_C_MPIH_MUL2_TRUE@mpih_mul2 = mpih-mul2.c
+@MPI_MOD_ASM_MPIH_MUL2_TRUE@mpih_mul2 = mpih-mul2-asm.S
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_FALSE@mpih_mul3 =
+@MPI_MOD_ASM_MPIH_MUL3_FALSE@@MPI_MOD_C_MPIH_MUL3_TRUE@mpih_mul3 = mpih-mul3.c
+@MPI_MOD_ASM_MPIH_MUL3_TRUE@mpih_mul3 = mpih-mul3-asm.S
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_FALSE@mpih_lshift =
+@MPI_MOD_ASM_MPIH_LSHIFT_FALSE@@MPI_MOD_C_MPIH_LSHIFT_TRUE@mpih_lshift = mpih-lshift.c
+@MPI_MOD_ASM_MPIH_LSHIFT_TRUE@mpih_lshift = mpih-lshift-asm.S
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_FALSE@mpih_rshift =
+@MPI_MOD_ASM_MPIH_RSHIFT_FALSE@@MPI_MOD_C_MPIH_RSHIFT_TRUE@mpih_rshift = mpih-rshift.c
+@MPI_MOD_ASM_MPIH_RSHIFT_TRUE@mpih_rshift = mpih-rshift-asm.S
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_FALSE@udiv =
+@MPI_MOD_ASM_UDIV_FALSE@@MPI_MOD_C_UDIV_TRUE@udiv = udiv.c
+@MPI_MOD_ASM_UDIV_TRUE@udiv = udiv-asm.S
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_FALSE@udiv_qrnnd =
+@MPI_MOD_ASM_UDIV_QRNND_FALSE@@MPI_MOD_C_UDIV_QRNND_TRUE@udiv_qrnnd = udiv-qrnnd.c
+@MPI_MOD_ASM_UDIV_QRNND_TRUE@udiv_qrnnd = udiv-qrnnd-asm.S
+noinst_LTLIBRARIES = libmpi.la
+libmpi_la_LDFLAGS =
+nodist_libmpi_la_SOURCES = $(mpih_add1) $(mpih_sub1) $(mpih_mul1) \
+ $(mpih_mul2) $(mpih_mul3) $(mpih_lshift) $(mpih_rshift) \
+ $(udiv) $(udiv_qrnnd)
+
+libmpi_la_SOURCES = longlong.h \
+ mpi-add.c \
+ mpi-bit.c \
+ mpi-cmp.c \
+ mpi-div.c \
+ mpi-gcd.c \
+ mpi-internal.h \
+ mpi-inline.h \
+ mpi-inline.c \
+ mpi-inv.c \
+ mpi-mul.c \
+ mpi-mod.c \
+ mpi-pow.c \
+ mpi-mpow.c \
+ mpi-scan.c \
+ mpicoder.c \
+ mpih-div.c \
+ mpih-mul.c \
+ mpiutil.c \
+ ec.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu mpi/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu mpi/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libmpi.la: $(libmpi_la_OBJECTS) $(libmpi_la_DEPENDENCIES)
+ $(libmpi_la_LINK) $(libmpi_la_OBJECTS) $(libmpi_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-add.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-bit.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-cmp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-gcd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-inline.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-inv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mod.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mpow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-mul.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-pow.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-scan.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpicoder.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-add1-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-add1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-div.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-lshift-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-lshift.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul1-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul2-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul3-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-mul3.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-rshift-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-rshift.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-sub1-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpih-sub1.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpiutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-qrnnd-asm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv-qrnnd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv.Plo@am__quote@
+
+.S.o:
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(LTCPPASCOMPILE) -c -o $@ $<
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+ -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# Manifest - checksums of the mpi directory
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+Makefile.am
+config.links
+longlong.h
+mpi-add.c
+mpi-bit.c
+mpi-cmp.c
+mpi-div.c
+mpi-gcd.c
+mpi-inline.c
+mpi-inline.h
+mpi-internal.h
+mpi-inv.c
+mpi-mpow.c
+mpi-mul.c
+mpi-pow.c
+mpi-scan.c
+mpicoder.c
+mpih-div.c
+mpih-mul.c
+mpiutil.c
+$names$ iQCVAwUAP+LmfDEAnp832S/7AQKZJQQAkR/gQITUM+6Ygy9WAOAO17btyKAlCtGTXp5XSZ+J3X0o/rYneRdSCW89IJvwFRJjAOcFJd52MXs6ZVFF/RQBC8MvJzuQChbEzvihK8o2VgK34YWjU+6XH9sFgRMIgzkHs/51ZZxeQUOPy1XF7TyKB0WE7YBUVisFiRaqB1qGIOs==Z3qB
+
--- /dev/null
+This directory contains mpn functions optimized for DEC Alpha processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+EV4
+
+1. This chip has very limited store bandwidth. The on-chip L1 cache is
+write-through, and a cache line is transfered from the store buffer to the
+off-chip L2 in as much 15 cycles on most systems. This delay hurts
+mpn_add_n, mpn_sub_n, mpn_lshift, and mpn_rshift.
+
+2. Pairing is possible between memory instructions and integer arithmetic
+instructions.
+
+3. mulq and umulh is documented to have a latency of 23 cycles, but 2 of
+these cycles are pipelined. Thus, multiply instructions can be issued at a
+rate of one each 21nd cycle.
+
+EV5
+
+1. The memory bandwidth of this chip seems excellent, both for loads and
+stores. Even when the working set is larger than the on-chip L1 and L2
+caches, the perfromance remain almost unaffected.
+
+2. mulq has a measured latency of 13 cycles and an issue rate of 1 each 8th
+cycle. umulh has a measured latency of 15 cycles and an issue rate of 1
+each 10th cycle. But the exact timing is somewhat confusing.
+
+3. mpn_add_n. With 4-fold unrolling, we need 37 instructions, whereof 12
+ are memory operations. This will take at least
+ ceil(37/2) [dual issue] + 1 [taken branch] = 20 cycles
+ We have 12 memory cycles, plus 4 after-store conflict cycles, or 16 data
+ cache cycles, which should be completely hidden in the 20 issue cycles.
+ The computation is inherently serial, with these dependencies:
+ addq
+ / \
+ addq cmpult
+ | |
+ cmpult |
+ \ /
+ or
+ I.e., there is a 4 cycle path for each limb, making 16 cycles the absolute
+ minimum. We could replace the `or' with a cmoveq/cmovne, which would save
+ a cycle on EV5, but that might waste a cycle on EV4. Also, cmov takes 2
+ cycles.
+ addq
+ / \
+ addq cmpult
+ | \
+ cmpult -> cmovne
+
+STATUS
+
--- /dev/null
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+
+udiv-qrnnd.S
+
--- /dev/null
+/* alpha add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ * Copyright (C) 1995, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($16)
+ * mpi_ptr_t s1_ptr, ($17)
+ * mpi_ptr_t s2_ptr, ($18)
+ * mpi_size_t size) ($19)
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ addq $5,$6,$6
+ cmpult $6,$5,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ addq $3,$4,$4
+ cmpult $4,$3,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_add_n
+
--- /dev/null
+/* alpha - left shift
+ *
+ * Copyright (C) 1994, 1995, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .frame $30,0,$26,0
+
+ s8addq $18,$17,$17 # make r17 point at end of s1
+ ldq $4,-8($17) # load first limb
+ subq $17,8,$17
+ subq $31,$19,$7
+ s8addq $18,$16,$16 # make r16 point at end of RES
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ srl $4,$7,$0 # compute function result
+
+ beq $20,.L0
+ subq $18,$20,$18
+
+ .align 3
+.Loop0:
+ ldq $3,-8($17)
+ subq $16,8,$16
+ subq $17,8,$17
+ subq $20,1,$20
+ sll $4,$19,$5
+ srl $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,0($16)
+ bne $20,.Loop0
+
+.L0: beq $18,.Lend
+
+ .align 3
+.Loop: ldq $3,-8($17)
+ subq $16,32,$16
+ subq $18,4,$18
+ sll $4,$19,$5
+ srl $3,$7,$6
+
+ ldq $4,-16($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,24($16)
+ srl $4,$7,$2
+
+ ldq $3,-24($17)
+ sll $4,$19,$5
+ bis $1,$2,$8
+ stq $8,16($16)
+ srl $3,$7,$6
+
+ ldq $4,-32($17)
+ sll $3,$19,$1
+ bis $5,$6,$8
+ stq $8,8($16)
+ srl $4,$7,$2
+
+ subq $17,32,$17
+ bis $1,$2,$8
+ stq $8,0($16)
+
+ bgt $18,.Loop
+
+.Lend: sll $4,$19,$8
+ stq $8,-8($16)
+ ret $31,($26),1
+ .end _gcry_mpih_lshift
+
+
--- /dev/null
+/* Alpha 21064 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on the EV4 and 18 cycles/limb on the EV5.
+ *
+ * To improve performance for long multiplications, we would use
+ * 'fetch' for S1 and 'fetch_m' for RES. It's not obvious how to use
+ * these instructions without slowing down the general code: 1. We can
+ * only have two prefetches in operation at any time in the Alpha
+ * architecture. 2. There will seldom be any special alignment
+ * between RES_PTR and S1_PTR. Maybe we can simply divide the current
+ * loop into an inner and outer loop, having the inner loop handle
+ * exactly one prefetch block?
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1 2
+_gcry_mpih_mul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ bic $31,$31,$4 # clear cy_limb
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,Lend1 # jump if size was == 1
+ ldq $2,8($17) # $2 = s1_limb
+ subq $18,1,$18 # size--
+ stq $3,0($16)
+ beq $18,Lend2 # jump if size was == 2
+
+ .align 3
+Loop: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,16($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ stq $3,8($16)
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $16,8,$16 # res_ptr++
+ bne $18,Loop
+
+Lend2: mulq $2,$19,$3 # $3 = prod_low
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ stq $3,8($16)
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+Lend1: stq $3,0($16)
+ ret $31,($26),1
+
+ .end _gcry_mpih_mul_1
+
+
--- /dev/null
+/* Alpha 21064 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_size_t s1_size, (r18)
+ * mpi_limb_t s2_limb) (r19)
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1 2
+_gcry_mpih_addmul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ addq $5,$3,$3
+ cmpult $3,$5,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: addq $5,$3,$3
+ cmpult $3,$5,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_addmul_1
+
--- /dev/null
+/* Alpha 21064 submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r16 )
+ * mpi_ptr_t s1_ptr, (r17 )
+ * mpi_size_t s1_size, (r18 )
+ * mpi_limb_t s2_limb) (r19 )
+ *
+ * This code runs at 42 cycles/limb on EV4 and 18 cycles/limb on EV5.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1 2
+_gcry_mpih_submul_1:
+ .frame $30,0,$26
+
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ umulh $2,$19,$0 # $0 = prod_high
+ beq $18,.Lend1 # jump if size was == 1
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ subq $18,1,$18 # size--
+ subq $5,$3,$3
+ cmpult $5,$3,$4
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ beq $18,.Lend2 # jump if size was == 2
+
+ .align 3
+.Loop: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ subq $18,1,$18 # size--
+ umulh $2,$19,$4 # $4 = cy_limb
+ ldq $2,0($17) # $2 = s1_limb
+ addq $17,8,$17 # s1_ptr++
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $16,8,$16 # res_ptr++
+ addq $5,$0,$0 # combine carries
+ bne $18,.Loop
+
+.Lend2: mulq $2,$19,$3 # $3 = prod_low
+ ldq $5,0($16) # $5 = *res_ptr
+ addq $4,$0,$0 # cy_limb = cy_limb + 'cy'
+ umulh $2,$19,$4 # $4 = cy_limb
+ addq $3,$0,$3 # $3 = cy_limb + prod_low
+ cmpult $3,$0,$0 # $0 = carry from (cy_limb + prod_low)
+ subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $5,$0,$0 # combine carries
+ addq $4,$0,$0 # cy_limb = prod_high + cy
+ ret $31,($26),1
+.Lend1: subq $5,$3,$3
+ cmpult $5,$3,$5
+ stq $3,0($16)
+ addq $0,$5,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_submul_1
+
--- /dev/null
+/* alpha rshift
+ * Copyright (C) 1994, 1995, 1998, 1999,
+ * 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r16)
+ * mpi_ptr_t up, (r17)
+ * mpi_size_t usize, (r18)
+ * unsigned cnt) (r19)
+ *
+ * This code runs at 4.8 cycles/limb on the 21064. With infinite unrolling,
+ * it would take 4 cycles/limb. It should be possible to get down to 3
+ * cycles/limb since both ldq and stq can be paired with the other used
+ * instructions. But there are many restrictions in the 21064 pipeline that
+ * makes it hard, if not impossible, to get down to 3 cycles/limb:
+ *
+ * 1. ldq has a 3 cycle delay, srl and sll have a 2 cycle delay.
+ * 2. Only aligned instruction pairs can be paired.
+ * 3. The store buffer or silo might not be able to deal with the bandwidth.
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .frame $30,0,$26,0
+
+ ldq $4,0($17) # load first limb
+ addq $17,8,$17
+ subq $31,$19,$7
+ subq $18,1,$18
+ and $18,4-1,$20 # number of limbs in first loop
+ sll $4,$7,$0 # compute function result
+
+ beq $20,.R0
+ subq $18,$20,$18
+
+ .align 3
+.Roop0:
+ ldq $3,0($17)
+ addq $16,8,$16
+ addq $17,8,$17
+ subq $20,1,$20
+ srl $4,$19,$5
+ sll $3,$7,$6
+ bis $3,$3,$4
+ bis $5,$6,$8
+ stq $8,-8($16)
+ bne $20,.Roop0
+
+.R0: beq $18,.Rend
+
+ .align 3
+.Roop: ldq $3,0($17)
+ addq $16,32,$16
+ subq $18,4,$18
+ srl $4,$19,$5
+ sll $3,$7,$6
+
+ ldq $4,8($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-32($16)
+ sll $4,$7,$2
+
+ ldq $3,16($17)
+ srl $4,$19,$5
+ bis $1,$2,$8
+ stq $8,-24($16)
+ sll $3,$7,$6
+
+ ldq $4,24($17)
+ srl $3,$19,$1
+ bis $5,$6,$8
+ stq $8,-16($16)
+ sll $4,$7,$2
+
+ addq $17,32,$17
+ bis $1,$2,$8
+ stq $8,-8($16)
+
+ bgt $18,.Roop
+
+.Rend: srl $4,$19,$8
+ stq $8,0($16)
+ ret $31,($26),1
+ .end _gcry_mpih_rshift
+
--- /dev/null
+/* Alpha sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ * Copyright (C) 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r16)
+ * mpi_ptr_t s1_ptr, (r17)
+ * mpi_ptr_t s2_ptr, (r18)
+ * mpi_size_t size) (r19)
+ */
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .frame $30,0,$26,0
+
+ ldq $3,0($17)
+ ldq $4,0($18)
+
+ subq $19,1,$19
+ and $19,4-1,$2 # number of limbs in first loop
+ bis $31,$31,$0
+ beq $2,.L0 # if multiple of 4 limbs, skip first loop
+
+ subq $19,$2,$19
+
+.Loop0: subq $2,1,$2
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ addq $17,8,$17
+ addq $18,8,$18
+ bis $5,$5,$3
+ bis $6,$6,$4
+ addq $16,8,$16
+ bne $2,.Loop0
+
+.L0: beq $19,.Lend
+
+ .align 3
+.Loop: subq $19,4,$19
+
+ ldq $5,8($17)
+ addq $4,$0,$4
+ ldq $6,8($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+
+ ldq $3,16($17)
+ addq $6,$0,$6
+ ldq $4,16($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,8($16)
+ or $0,$1,$0
+
+ ldq $5,24($17)
+ addq $4,$0,$4
+ ldq $6,24($18)
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,16($16)
+ or $0,$1,$0
+
+ ldq $3,32($17)
+ addq $6,$0,$6
+ ldq $4,32($18)
+ cmpult $6,$0,$1
+ subq $5,$6,$6
+ cmpult $5,$6,$0
+ stq $6,24($16)
+ or $0,$1,$0
+
+ addq $17,32,$17
+ addq $18,32,$18
+ addq $16,32,$16
+ bne $19,.Loop
+
+.Lend: addq $4,$0,$4
+ cmpult $4,$0,$1
+ subq $3,$4,$4
+ cmpult $3,$4,$0
+ stq $4,0($16)
+ or $0,$1,$0
+ ret $31,($26),1
+
+ .end _gcry_mpih_sub_n
+
+
--- /dev/null
+/* Alpha 21064 __udiv_qrnnd
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+ .set noreorder
+ .set noat
+.text
+ .align 3
+ .globl __udiv_qrnnd
+ .ent __udiv_qrnnd
+__udiv_qrnnd:
+ .frame $30,0,$26,0
+ .prologue 0
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+
+ ldiq cnt,16
+ blt d,.Largedivisor
+
+.Loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.Largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+.Loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,.Loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,.LOdd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+.LOdd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+ cmpult n1,n0,tmp # tmp := carry from addq
+ beq tmp,.LLp6
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp6: cmpult n1,d,tmp
+ bne tmp,.LLp7
+ addq n0,1,n0
+ subq n1,d,n1
+.LLp7:
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
--- /dev/null
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
--- /dev/null
+/* AMD64 (x86_64) add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ adcq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
+
\ No newline at end of file
--- /dev/null
+/* AMD64 (x86_64) lshift -- Left shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ movq -8(%rsi,%rdx,8), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ movd %mm7, %rax
+ subq $2, %rdx
+ jl .Lendo
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psrlq %mm0, %mm6
+ psllq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, 8(%rdi,%rdx,8)
+ je .Lende
+ movq -8(%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psrlq %mm0, %mm7
+ psllq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, (%rdi,%rdx,8)
+ subq $2, %rdx
+ jge .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psllq %mm1, %mm2
+ movq %mm2, (%rdi)
+ emms
+ ret
--- /dev/null
+/* AMD64 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+
+
+ TEXT
+ ALIGN(5)
+ .byte 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq %r8, %rax
+ movl $0, %r8d
+ adcq %rdx, %r8
+ movq %rax, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
--- /dev/null
+/* AMD64 addmul2 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+ /* i80386 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+ movq %rdx, %r11
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+ xorl %r10d, %r10d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ mulq %rcx
+ addq (%rdi,%r11,8), %rax
+ adcq %r10, %rdx
+ addq %r8, %rax
+ movq %r10, %r8
+ movq %rax, (%rdi,%r11,8)
+ adcq %rdx, %r8
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
--- /dev/null
+/* AMD64 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (rdi)
+ * mpi_ptr_t s1_ptr, (rsi)
+ * mpi_size_t s1_size, (rdx)
+ * mpi_limb_t s2_limb) (rcx)
+ */
+ TEXT
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ movq %rdx, %r11
+ leaq (%rsi,%r11,8), %rsi
+ leaq (%rdi,%r11,8), %rdi
+ negq %r11
+ xorl %r8d, %r8d
+
+ ALIGN(3) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%r11,8), %rax
+ movq (%rdi,%r11,8), %r10
+ mulq %rcx
+ subq %r8, %r10
+ movl $0, %r8d
+ adcl %r8d, %r8d
+ subq %rax, %r10
+ adcq %rdx, %r8
+ movq %r10, (%rdi,%r11,8)
+ incq %r11
+ jne .Loop
+
+ movq %r8, %rax
+ ret
--- /dev/null
+/* AMD64 (x86_64) rshift -- Right shift a limb vector and store
+ * result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, rdi
+ * mpi_ptr_t up, rsi
+ * mpi_size_t usize, rdx
+ * unsigned cnt) rcx
+ */
+
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ movq (%rsi), %mm7
+ movd %ecx, %mm1
+ movl $64, %eax
+ subl %ecx, %eax
+ movd %eax, %mm0
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ movd %mm7, %rax
+ leaq (%rsi,%rdx,8), %rsi
+ leaq (%rdi,%rdx,8), %rdi
+ negq %rdx
+ addq $2, %rdx
+ jg .Lendo
+
+ ALIGN(8) /* minimal alignment for claimed speed */
+.Loop: movq -8(%rsi,%rdx,8), %mm6
+ movq %mm6, %mm2
+ psllq %mm0, %mm6
+ psrlq %mm1, %mm3
+ por %mm6, %mm3
+ movq %mm3, -16(%rdi,%rdx,8)
+ je .Lende
+ movq (%rsi,%rdx,8), %mm7
+ movq %mm7, %mm3
+ psllq %mm0, %mm7
+ psrlq %mm1, %mm2
+ por %mm7, %mm2
+ movq %mm2, -8(%rdi,%rdx,8)
+ addq $2, %rdx
+ jle .Loop
+
+.Lendo: movq %mm3, %mm2
+.Lende: psrlq %mm1, %mm2
+ movq %mm2, -8(%rdi)
+ emms
+ ret
--- /dev/null
+/* AMD64 (x86_64) sub_n -- Subtract two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, rdi
+ * mpi_ptr_t s1_ptr, rsi
+ * mpi_ptr_t s2_ptr, rdx
+ * mpi_size_t size) rcx
+ */
+.text
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ leaq (%rsi,%rcx,8), %rsi
+ leaq (%rdi,%rcx,8), %rdi
+ leaq (%rdx,%rcx,8), %rdx
+ negq %rcx
+ xorl %eax, %eax /* clear cy */
+
+ ALIGN(4) /* minimal alignment for claimed speed */
+.Loop: movq (%rsi,%rcx,8), %rax
+ movq (%rdx,%rcx,8), %r10
+ sbbq %r10, %rax
+ movq %rax, (%rdi,%rcx,8)
+ incq %rcx
+ jne .Loop
+
+ movq %rcx, %rax /* zero %rax */
+ adcq %rax, %rax
+ ret
--- /dev/null
+# config.links - helper for ../configure -*- mode: sh -*-
+# Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+#
+# sourced by ../configure to get the list of files to link
+# this should set $mpi_ln_list.
+# Note: this is called from the above directory.
+
+mpi_sflags=
+mpi_extra_modules=
+
+test -d ./mpi || mkdir ./mpi
+
+# We grep the list of modules from the Makefile so that
+# we don't need to maintain them here.
+mpi_standard_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 != "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
+ if( $3 == "O" ) print $2 }' $srcdir/mpi/Makefile.am`
+
+
+echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
+echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
+
+if test "$try_asm_modules" = "yes" ; then
+case "${host}" in
+ powerpc-apple-darwin* | \
+ i[34567]86*-*-openbsd[12]* | \
+ i[34567]86*-*-openbsd3.[0123]*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ i[3467]86*-*-openbsd* | \
+ i[3467]86*-*-freebsd*-elf | \
+ i[3467]86*-*-freebsd[3-9]* | \
+ i[3467]86*-*-freebsdelf* | \
+ i[3467]86*-*-netbsd* | \
+ i[3467]86*-*-k*bsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-openbsd* | \
+ i586*-*-freebsd*-elf | \
+ i586*-*-freebsd[3-9]* | \
+ i586*-*-freebsdelf* | \
+ i586*-*-netbsd* | \
+ i586*-*-k*bsd* | \
+ pentium-*-netbsd* | \
+ pentiumpro-*-netbsd*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[34]86*-*-bsdi4*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i[3467]86*-*-linuxaout* | \
+ i[3467]86*-*-linuxoldld* | \
+ i[3467]86*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-linuxaout* | \
+ i586*-*-linuxoldld* | \
+ i586*-*-*bsd*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[3467]86*-msdosdjgpp* | \
+ i[34]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-msdosdjgpp* | \
+ i[567]86*-apple-darwin*)
+ echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ i[3467]86*-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i386"
+ ;;
+ i586*-*-* | \
+ pentium-*-* | \
+ pentiumpro-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="i586 i386"
+ ;;
+ x86_64-*-*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h
+ path="amd64"
+ ;;
+ alpha*-*-*)
+ echo '/* configured for alpha */' >>./mpi/asm-syntax.h
+ path="alpha"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa7000*-*-*)
+ echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
+ path="hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa1.0*-*-*)
+ echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
+ path="hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ hppa*-*-*) # assume pa7100
+ echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
+ path="pa7100 hppa1.1 hppa"
+ mpi_extra_modules="udiv-qrnnd"
+ ;;
+ sparc64-*-linux-gnu)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64-sun-solaris2*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
+ # There are no sparc64 assembler modules that work on the
+ # *BSDs, so use the generic C functions.
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc64*-*-*)
+ echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+ sparc9*-*-* | \
+ ultrasparc*-*-* )
+ echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ ;;
+ sparc8*-*-* | \
+ microsparc*-*-*)
+ echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
+ path="sparc32v8 sparc32"
+ ;;
+ supersparc*-*-*)
+ echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
+ path="supersparc sparc32v8 sparc32"
+ mpi_extra_modules="udiv"
+ ;;
+ sparc*-*-*)
+ echo '/* configured for sparc */' >>./mpi/asm-syntax.h
+ path="sparc32"
+ mpi_extra_modules="udiv"
+ ;;
+ mips[34]*-*-* | \
+ mips*-*-irix6*)
+ echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
+ path="mips3"
+ ;;
+ mips*-*-*)
+ echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
+ path="mips2"
+ ;;
+
+ # Motorola 68k configurations. Let m68k mean 68020-68040.
+ # mc68000 or mc68060 configurations need to be specified explicitly
+ m680[234]0*-*-linuxaout* | \
+ m68k*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+ m68060*-*-linuxaout*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ ;;
+ m680[234]0*-*-linux* | \
+ m68k*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ ;;
+ m68060*-*-linux*)
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k"
+ ;;
+ m68k-atari-mint)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+ m68000*-*-* | \
+ m68060*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68000"
+ ;;
+ m680[234]0*-*-* | \
+ m68k*-*-*)
+ echo '#define MIT_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h
+ path="m68k/mc68020 m68k"
+ ;;
+
+ powerpc*-*-netbsd* | powerpc*-*-openbsd*)
+ echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+
+ ppc620-*-* | \
+ powerpc64*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc64"
+ ;;
+ powerpc*-*-linux*)
+ echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
+ echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
+ cat $srcdir/mpi/powerpc32/syntax.h >>./mpi/asm-syntax.h
+ path="powerpc32"
+ ;;
+
+ rs6000-*-aix[456789]* | \
+ rs6000-*-aix3.2.[456789])
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ rs6000-*-* | \
+ power-*-* | \
+ power2-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ powerpc-ibm-aix4.2.* )
+ # I am not sure about this one but a machine identified by
+ # powerpc-ibm-aix4.2.1.0 cannot use the powerpc32 code.
+ mpi_sflags="-Wa,-mpwr"
+ path="power"
+ mpi_extra_modules="udiv-w-sdiv"
+ ;;
+ ppc601-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="power powerpc32"
+ ;;
+ ppc60[234]*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+ powerpc*-*-*)
+ mpi_sflags="-Wa,-mppc"
+ path="powerpc32"
+ ;;
+ *)
+ echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+ path=""
+ ;;
+esac
+else
+ echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h
+ path=""
+fi
+
+
+# Make sysdep.h
+echo '/* created by config.links - do not edit */' >./mpi/sysdep.h
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+ cat <<EOF >>./mpi/sysdep.h
+#if __STDC__
+#define C_SYMBOL_NAME(name) _##name
+#else
+#define C_SYMBOL_NAME(name) _/**/name
+#endif
+EOF
+else
+ cat <<EOF >>./mpi/sysdep.h
+#define C_SYMBOL_NAME(name) name
+EOF
+fi
+
+
+# Figure the required modules out
+mpi_required_modules=$mpi_standard_modules
+if test "$mpi_extra_modules" != ""; then
+ for fn in $mpi_extra_modules; do
+ for i in $mpi_optional_modules; do
+ if test "$fn" = "$i" ; then
+ mpi_required_modules="$mpi_required_modules $fn"
+ fi
+ done
+ done
+fi
+
+# Try to get file to link from the assembler subdirectory and
+# if this fails get it from the generic subdirectory.
+mpi_ln_list=
+mpi_mod_list=
+path=`echo "$mpi_extra_path $path generic" | tr ':' ' '`
+echo '/* Created by config.links - do not edit */' >./mpi/mod-source-info.h
+echo "/* Host: ${host} */" >>./mpi/mod-source-info.h
+echo "static char mod_source_info[] =" >>./mpi/mod-source-info.h
+for fn in $mpi_required_modules ; do
+ fnu=`echo $fn | sed 's/-/_/g'`
+ eval mpi_mod_c_${fnu}=no
+ eval mpi_mod_asm_${fnu}=no
+ for dir in $path ; do
+ rm -f $srcdir/mpi/$fn.[Sc]
+ if test -f $srcdir/mpi/$dir/$fn.S ; then
+ echo " \":$dir/$fn.S\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn-asm.S:mpi/$dir/$fn.S"
+ eval mpi_mod_asm_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ elif test -f $srcdir/mpi/$dir/$fn.c ; then
+ echo " \":$dir/$fn.c\"" >>./mpi/mod-source-info.h
+ mpi_ln_list="$mpi_ln_list mpi/$fn.c:mpi/$dir/$fn.c"
+ eval mpi_mod_c_${fnu}=yes
+ mpi_mod_list="$mpi_mod_list $fn"
+ break;
+ fi
+ done
+done
+echo " ;" >>./mpi/mod-source-info.h
+
+# Same thing for the file which defines the limb size
+path=`echo "$path generic" | tr ':' ' '`
+for dir in $path ; do
+ rm -f $srcdir/mpi/mpi-asm-defs.h
+ if test -f $srcdir/mpi/$dir/mpi-asm-defs.h ; then
+ mpi_ln_list="$mpi_ln_list mpi/mpi-asm-defs.h:mpi/$dir/mpi-asm-defs.h"
+ break;
+ fi
+done
--- /dev/null
+/* ec.c - Elliptic Curve functions
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+#define point_init(a) _gcry_mpi_ec_point_init ((a))
+#define point_free(a) _gcry_mpi_ec_point_free ((a))
+
+
+/* Object to represent a point in projective coordinates. */
+/* Currently defined in mpi.h */
+
+/* This context is used with all our EC functions. */
+struct mpi_ec_ctx_s
+{
+ /* Domain parameters. */
+ gcry_mpi_t p; /* Prime specifying the field GF(p). */
+ gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */
+
+ int a_is_pminus3; /* True if A = P - 3. */
+
+ /* Some often used constants. */
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t three;
+ gcry_mpi_t four;
+ gcry_mpi_t eight;
+ gcry_mpi_t two_inv_p;
+
+ /* Scratch variables. */
+ gcry_mpi_t scratch[11];
+
+ /* Helper for fast reduction. */
+/* int nist_nbits; /\* If this is a NIST curve, the number of bits. *\/ */
+/* gcry_mpi_t s[10]; */
+/* gcry_mpi_t c; */
+
+};
+
+
+
+/* Initialized a point object. gcry_mpi_ec_point_free shall be used
+ to release this object. */
+void
+_gcry_mpi_ec_point_init (mpi_point_t *p)
+{
+ p->x = mpi_new (0);
+ p->y = mpi_new (0);
+ p->z = mpi_new (0);
+}
+
+
+/* Release a point object. */
+void
+_gcry_mpi_ec_point_free (mpi_point_t *p)
+{
+ mpi_free (p->x); p->x = NULL;
+ mpi_free (p->y); p->y = NULL;
+ mpi_free (p->z); p->z = NULL;
+}
+
+/* Set the value from S into D. */
+static void
+point_set (mpi_point_t *d, mpi_point_t *s)
+{
+ mpi_set (d->x, s->x);
+ mpi_set (d->y, s->y);
+ mpi_set (d->z, s->z);
+}
+
+
+
+static void
+ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_addm (w, u, v, ctx->p);
+}
+
+static void
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+ mpi_subm (w, u, v, ctx->p);
+}
+
+static void
+ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+{
+#if 0
+ /* NOTE: This code works only for limb sizes of 32 bit. */
+ mpi_limb_t *wp, *sp;
+
+ if (ctx->nist_nbits == 192)
+ {
+ mpi_mul (w, u, v);
+ mpi_resize (w, 12);
+ wp = w->d;
+
+ sp = ctx->s[0]->d;
+ sp[0*2+0] = wp[0*2+0];
+ sp[0*2+1] = wp[0*2+1];
+ sp[1*2+0] = wp[1*2+0];
+ sp[1*2+1] = wp[1*2+1];
+ sp[2*2+0] = wp[2*2+0];
+ sp[2*2+1] = wp[2*2+1];
+
+ sp = ctx->s[1]->d;
+ sp[0*2+0] = wp[3*2+0];
+ sp[0*2+1] = wp[3*2+1];
+ sp[1*2+0] = wp[3*2+0];
+ sp[1*2+1] = wp[3*2+1];
+ sp[2*2+0] = 0;
+ sp[2*2+1] = 0;
+
+ sp = ctx->s[2]->d;
+ sp[0*2+0] = 0;
+ sp[0*2+1] = 0;
+ sp[1*2+0] = wp[4*2+0];
+ sp[1*2+1] = wp[4*2+1];
+ sp[2*2+0] = wp[4*2+0];
+ sp[2*2+1] = wp[4*2+1];
+
+ sp = ctx->s[3]->d;
+ sp[0*2+0] = wp[5*2+0];
+ sp[0*2+1] = wp[5*2+1];
+ sp[1*2+0] = wp[5*2+0];
+ sp[1*2+1] = wp[5*2+1];
+ sp[2*2+0] = wp[5*2+0];
+ sp[2*2+1] = wp[5*2+1];
+
+ ctx->s[0]->nlimbs = 6;
+ ctx->s[1]->nlimbs = 6;
+ ctx->s[2]->nlimbs = 6;
+ ctx->s[3]->nlimbs = 6;
+
+ mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[2]);
+ mpi_add (ctx->c, ctx->c, ctx->s[3]);
+
+ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
+ mpi_sub ( ctx->c, ctx->c, ctx->p );
+ mpi_set (w, ctx->c);
+ }
+ else if (ctx->nist_nbits == 384)
+ {
+ int i;
+ mpi_mul (w, u, v);
+ mpi_resize (w, 24);
+ wp = w->d;
+
+#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
+ sp = ctx->s[(a)]->d; \
+ i = 0; } while (0)
+#define X(a) do { sp[i++] = wp[(a)];} while (0)
+#define X0(a) do { sp[i++] = 0; } while (0)
+ NEXT(0);
+ X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
+ NEXT(1);
+ X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
+ NEXT(2);
+ X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
+ NEXT(3);
+ X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
+ NEXT(4);
+ X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
+ NEXT(5);
+ X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
+ NEXT(6);
+ X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
+ NEXT(7);
+ X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
+ NEXT(8);
+ X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
+ NEXT(9);
+ X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
+#undef X0
+#undef X
+#undef NEXT
+ mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[1]);
+ mpi_add (ctx->c, ctx->c, ctx->s[2]);
+ mpi_add (ctx->c, ctx->c, ctx->s[3]);
+ mpi_add (ctx->c, ctx->c, ctx->s[4]);
+ mpi_add (ctx->c, ctx->c, ctx->s[5]);
+ mpi_add (ctx->c, ctx->c, ctx->s[6]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[7]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[8]);
+ mpi_sub (ctx->c, ctx->c, ctx->s[9]);
+
+ while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
+ mpi_sub ( ctx->c, ctx->c, ctx->p );
+ while ( ctx->c->sign )
+ mpi_add ( ctx->c, ctx->c, ctx->p );
+ mpi_set (w, ctx->c);
+ }
+ else
+#endif /*0*/
+ mpi_mulm (w, u, v, ctx->p);
+}
+
+static void
+ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ mpi_ec_t ctx)
+{
+ mpi_powm (w, b, e, ctx->p);
+}
+
+static void
+ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
+{
+ mpi_invm (x, a, ctx->p);
+}
+
+
+
+/* This function returns a new context for elliptic curve based on the
+ field GF(p). P is the prime specifying thuis field, A is the first
+ coefficient.
+
+ This context needs to be released using _gcry_mpi_ec_free. */
+mpi_ec_t
+_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
+{
+ int i;
+ mpi_ec_t ctx;
+ gcry_mpi_t tmp;
+
+ mpi_normalize (p);
+ mpi_normalize (a);
+
+ /* Fixme: Do we want to check some constraints? e.g.
+ a < p
+ */
+
+ ctx = gcry_xcalloc (1, sizeof *ctx);
+
+ ctx->p = mpi_copy (p);
+ ctx->a = mpi_copy (a);
+
+ tmp = mpi_alloc_like (ctx->p);
+ mpi_sub_ui (tmp, ctx->p, 3);
+ ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp);
+ mpi_free (tmp);
+
+
+ /* Allocate constants. */
+ ctx->one = mpi_alloc_set_ui (1);
+ ctx->two = mpi_alloc_set_ui (2);
+ ctx->three = mpi_alloc_set_ui (3);
+ ctx->four = mpi_alloc_set_ui (4);
+ ctx->eight = mpi_alloc_set_ui (8);
+ ctx->two_inv_p = mpi_alloc (0);
+ ec_invm (ctx->two_inv_p, ctx->two, ctx);
+
+ /* Allocate scratch variables. */
+ for (i=0; i< DIM(ctx->scratch); i++)
+ ctx->scratch[i] = mpi_alloc_like (ctx->p);
+
+ /* Prepare for fast reduction. */
+ /* FIXME: need a test for NIST values. However it does not gain us
+ any real advantage, for 384 bits it is actually slower than using
+ mpi_mulm. */
+/* ctx->nist_nbits = mpi_get_nbits (ctx->p); */
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* ctx->s[i] = mpi_new (192); */
+/* ctx->c = mpi_new (192*2); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* ctx->s[i] = mpi_new (384); */
+/* ctx->c = mpi_new (384*2); */
+/* } */
+
+ return ctx;
+}
+
+void
+_gcry_mpi_ec_free (mpi_ec_t ctx)
+{
+ int i;
+
+ if (!ctx)
+ return;
+
+ mpi_free (ctx->p);
+ mpi_free (ctx->a);
+
+ mpi_free (ctx->one);
+ mpi_free (ctx->two);
+ mpi_free (ctx->three);
+ mpi_free (ctx->four);
+ mpi_free (ctx->eight);
+
+ mpi_free (ctx->two_inv_p);
+
+ for (i=0; i< DIM(ctx->scratch); i++)
+ mpi_free (ctx->scratch[i]);
+
+/* if (ctx->nist_nbits == 192) */
+/* { */
+/* for (i=0; i < 4; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+/* else if (ctx->nist_nbits == 384) */
+/* { */
+/* for (i=0; i < 10; i++) */
+/* mpi_free (ctx->s[i]); */
+/* mpi_free (ctx->c); */
+/* } */
+
+ gcry_free (ctx);
+}
+
+/* Compute the affine coordinates from the projective coordinates in
+ POINT. Set them into X and Y. If one coordinate is not required,
+ X or Y may be passed as NULL. CTX is the usual context. Returns: 0
+ on success or !0 if POINT is at infinity. */
+int
+_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+ mpi_ec_t ctx)
+{
+ gcry_mpi_t z1, z2, z3;
+
+ if (!mpi_cmp_ui (point->z, 0))
+ return -1;
+
+ z1 = mpi_new (0);
+ z2 = mpi_new (0);
+ ec_invm (z1, point->z, ctx); /* z1 = z^(-1) mod p */
+ ec_mulm (z2, z1, z1, ctx); /* z2 = z^(-2) mod p */
+
+ if (x)
+ ec_mulm (x, point->x, z2, ctx);
+
+ if (y)
+ {
+ z3 = mpi_new (0);
+ ec_mulm (z3, z2, z1, ctx); /* z3 = z^(-3) mod p */
+ ec_mulm (y, point->y, z3, ctx);
+ mpi_free (z3);
+ }
+
+ mpi_free (z2);
+ mpi_free (z1);
+ return 0;
+}
+
+
+
+
+\f
+/* RESULT = 2 * POINT */
+void
+_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
+{
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define t1 (ctx->scratch[0])
+#define t2 (ctx->scratch[1])
+#define t3 (ctx->scratch[2])
+#define l1 (ctx->scratch[3])
+#define l2 (ctx->scratch[4])
+#define l3 (ctx->scratch[5])
+
+ if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
+ {
+ /* P_y == 0 || P_z == 0 => [1:1:0] */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ else
+ {
+ if (ctx->a_is_pminus3) /* Use the faster case. */
+ {
+ /* L1 = 3(X - Z^2)(X + Z^2) */
+ /* T1: used for Z^2. */
+ /* T2: used for the right term. */
+ ec_powm (t1, point->z, ctx->two, ctx);
+ ec_subm (l1, point->x, t1, ctx);
+ ec_mulm (l1, l1, ctx->three, ctx);
+ ec_addm (t2, point->x, t1, ctx);
+ ec_mulm (l1, l1, t2, ctx);
+ }
+ else /* Standard case. */
+ {
+ /* L1 = 3X^2 + aZ^4 */
+ /* T1: used for aZ^4. */
+ ec_powm (l1, point->x, ctx->two, ctx);
+ ec_mulm (l1, l1, ctx->three, ctx);
+ ec_powm (t1, point->z, ctx->four, ctx);
+ ec_mulm (t1, t1, ctx->a, ctx);
+ ec_addm (l1, l1, t1, ctx);
+ }
+ /* Z3 = 2YZ */
+ ec_mulm (z3, point->y, point->z, ctx);
+ ec_mulm (z3, z3, ctx->two, ctx);
+
+ /* L2 = 4XY^2 */
+ /* T2: used for Y2; required later. */
+ ec_powm (t2, point->y, ctx->two, ctx);
+ ec_mulm (l2, t2, point->x, ctx);
+ ec_mulm (l2, l2, ctx->four, ctx);
+
+ /* X3 = L1^2 - 2L2 */
+ /* T1: used for L2^2. */
+ ec_powm (x3, l1, ctx->two, ctx);
+ ec_mulm (t1, l2, ctx->two, ctx);
+ ec_subm (x3, x3, t1, ctx);
+
+ /* L3 = 8Y^4 */
+ /* T2: taken from above. */
+ ec_powm (t2, t2, ctx->two, ctx);
+ ec_mulm (l3, t2, ctx->eight, ctx);
+
+ /* Y3 = L1(L2 - X3) - L3 */
+ ec_subm (y3, l2, x3, ctx);
+ ec_mulm (y3, y3, l1, ctx);
+ ec_subm (y3, y3, l3, ctx);
+ }
+
+#undef x3
+#undef y3
+#undef z3
+#undef t1
+#undef t2
+#undef t3
+#undef l1
+#undef l2
+#undef l3
+}
+
+
+
+/* RESULT = P1 + P2 */
+void
+_gcry_mpi_ec_add_points (mpi_point_t *result,
+ mpi_point_t *p1, mpi_point_t *p2,
+ mpi_ec_t ctx)
+{
+#define x1 (p1->x )
+#define y1 (p1->y )
+#define z1 (p1->z )
+#define x2 (p2->x )
+#define y2 (p2->y )
+#define z2 (p2->z )
+#define x3 (result->x)
+#define y3 (result->y)
+#define z3 (result->z)
+#define l1 (ctx->scratch[0])
+#define l2 (ctx->scratch[1])
+#define l3 (ctx->scratch[2])
+#define l4 (ctx->scratch[3])
+#define l5 (ctx->scratch[4])
+#define l6 (ctx->scratch[5])
+#define l7 (ctx->scratch[6])
+#define l8 (ctx->scratch[7])
+#define l9 (ctx->scratch[8])
+#define t1 (ctx->scratch[9])
+#define t2 (ctx->scratch[10])
+
+ if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
+ {
+ /* Same point; need to call the duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else if (!mpi_cmp_ui (z1, 0))
+ {
+ /* P1 is at infinity. */
+ mpi_set (x3, p2->x);
+ mpi_set (y3, p2->y);
+ mpi_set (z3, p2->z);
+ }
+ else if (!mpi_cmp_ui (z2, 0))
+ {
+ /* P2 is at infinity. */
+ mpi_set (x3, p1->x);
+ mpi_set (y3, p1->y);
+ mpi_set (z3, p1->z);
+ }
+ else
+ {
+ int z1_is_one = !mpi_cmp_ui (z1, 1);
+ int z2_is_one = !mpi_cmp_ui (z2, 1);
+
+ /* l1 = x1 z2^2 */
+ /* l2 = x2 z1^2 */
+ if (z2_is_one)
+ mpi_set (l1, x1);
+ else
+ {
+ ec_powm (l1, z2, ctx->two, ctx);
+ ec_mulm (l1, l1, x1, ctx);
+ }
+ if (z1_is_one)
+ mpi_set (l2, x1);
+ else
+ {
+ ec_powm (l2, z1, ctx->two, ctx);
+ ec_mulm (l2, l2, x2, ctx);
+ }
+ /* l3 = l1 - l2 */
+ ec_subm (l3, l1, l2, ctx);
+ /* l4 = y1 z2^3 */
+ ec_powm (l4, z2, ctx->three, ctx);
+ ec_mulm (l4, l4, y1, ctx);
+ /* l5 = y2 z1^3 */
+ ec_powm (l5, z1, ctx->three, ctx);
+ ec_mulm (l5, l5, y2, ctx);
+ /* l6 = l4 - l5 */
+ ec_subm (l6, l4, l5, ctx);
+
+ if (!mpi_cmp_ui (l3, 0))
+ {
+ if (!mpi_cmp_ui (l6, 0))
+ {
+ /* P1 and P2 are the same - use duplicate function. */
+ _gcry_mpi_ec_dup_point (result, p1, ctx);
+ }
+ else
+ {
+ /* P1 is the inverse of P2. */
+ mpi_set_ui (x3, 1);
+ mpi_set_ui (y3, 1);
+ mpi_set_ui (z3, 0);
+ }
+ }
+ else
+ {
+ /* l7 = l1 + l2 */
+ ec_addm (l7, l1, l2, ctx);
+ /* l8 = l4 + l5 */
+ ec_addm (l8, l4, l5, ctx);
+ /* z3 = z1 z2 l3 */
+ ec_mulm (z3, z1, z2, ctx);
+ ec_mulm (z3, z3, l3, ctx);
+ /* x3 = l6^2 - l7 l3^2 */
+ ec_powm (t1, l6, ctx->two, ctx);
+ ec_powm (t2, l3, ctx->two, ctx);
+ ec_mulm (t2, t2, l7, ctx);
+ ec_subm (x3, t1, t2, ctx);
+ /* l9 = l7 l3^2 - 2 x3 */
+ ec_mulm (t1, x3, ctx->two, ctx);
+ ec_subm (l9, t2, t1, ctx);
+ /* y3 = (l9 l6 - l8 l3^3)/2 */
+ ec_mulm (l9, l9, l6, ctx);
+ ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/
+ ec_mulm (t1, t1, l8, ctx);
+ ec_subm (y3, l9, t1, ctx);
+ ec_mulm (y3, y3, ctx->two_inv_p, ctx);
+ }
+ }
+
+#undef x1
+#undef y1
+#undef z1
+#undef x2
+#undef y2
+#undef z2
+#undef x3
+#undef y3
+#undef z3
+#undef l1
+#undef l2
+#undef l3
+#undef l4
+#undef l5
+#undef l6
+#undef l7
+#undef l8
+#undef l9
+#undef t1
+#undef t2
+}
+
+
+
+/* Scalar point multiplication - the main function for ECC. If takes
+ an integer SCALAR and a POINT as well as the usual context CTX.
+ RESULT will be set to the resulting point. */
+void
+_gcry_mpi_ec_mul_point (mpi_point_t *result,
+ gcry_mpi_t scalar, mpi_point_t *point,
+ mpi_ec_t ctx)
+{
+#if 0
+ /* Simple left to right binary method. GECC Algorithm 3.27 */
+ unsigned int nbits;
+ int i;
+
+ nbits = mpi_get_nbits (scalar);
+ mpi_set_ui (result->x, 1);
+ mpi_set_ui (result->y, 1);
+ mpi_set_ui (result->z, 0);
+
+ for (i=nbits-1; i >= 0; i--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (scalar, i) == 1)
+ _gcry_mpi_ec_add_points (result, result, point, ctx);
+ }
+
+#else
+ gcry_mpi_t x1, y1, z1, k, h, yy;
+ unsigned int i, loops;
+ mpi_point_t p1, p2, p1inv;
+
+ x1 = mpi_alloc_like (ctx->p);
+ y1 = mpi_alloc_like (ctx->p);
+ h = mpi_alloc_like (ctx->p);
+ k = mpi_copy (scalar);
+ yy = mpi_copy (point->y);
+
+ if ( mpi_is_neg (k) )
+ {
+ k->sign = 0;
+ ec_invm (yy, yy, ctx);
+ }
+
+ if (!mpi_cmp_ui (point->z, 1))
+ {
+ mpi_set (x1, point->x);
+ mpi_set (y1, yy);
+ }
+ else
+ {
+ gcry_mpi_t z2, z3;
+
+ z2 = mpi_alloc_like (ctx->p);
+ z3 = mpi_alloc_like (ctx->p);
+ ec_mulm (z2, point->z, point->z, ctx);
+ ec_mulm (z3, point->z, z2, ctx);
+ ec_invm (z2, z2, ctx);
+ ec_mulm (x1, point->x, z2, ctx);
+ ec_invm (z3, z3, ctx);
+ ec_mulm (y1, yy, z3, ctx);
+ mpi_free (z2);
+ mpi_free (z3);
+ }
+ z1 = mpi_copy (ctx->one);
+
+ mpi_mul (h, k, ctx->three); /* h = 3k */
+ loops = mpi_get_nbits (h);
+
+ mpi_set (result->x, point->x);
+ mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
+ mpi_set (result->z, point->z);
+
+ p1.x = x1; x1 = NULL;
+ p1.y = y1; y1 = NULL;
+ p1.z = z1; z1 = NULL;
+ point_init (&p2);
+ point_init (&p1inv);
+
+ for (i=loops-2; i > 0; i--)
+ {
+ _gcry_mpi_ec_dup_point (result, result, ctx);
+ if (mpi_test_bit (h, i) == 1 && mpi_test_bit (k, i) == 0)
+ {
+ point_set (&p2, result);
+ _gcry_mpi_ec_add_points (result, &p2, &p1, ctx);
+ }
+ if (mpi_test_bit (h, i) == 0 && mpi_test_bit (k, i) == 1)
+ {
+ point_set (&p2, result);
+ /* Invert point: y = p - y mod p */
+ point_set (&p1inv, &p1);
+ ec_subm (p1inv.y, ctx->p, p1inv.y, ctx);
+ _gcry_mpi_ec_add_points (result, &p2, &p1inv, ctx);
+ }
+ }
+
+ point_free (&p1);
+ point_free (&p2);
+ point_free (&p1inv);
+ mpi_free (h);
+ mpi_free (k);
+#endif
+}
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.c iQCVAwUAP+Lj2DEAnp832S/7AQKn/AQAwQLWggl6zNQ5EZ+lE+jKV8W3FsogW3/6tp9T5rrSR5JnlWyoHQ9/Pu4knOcLjS6nIfVOiAEifu3nuIysQr9jDSSSJA2LylSUBSXKLKDamPsOCwXOLxiZODslJT3CCGAUtLvXJrWDbTZQrkEuwnLnjQFDzuA7iY9JLrG9kAoXD6Q==WoWm
+mpih-mul1.c iQCVAwUAP+LkCTEAnp832S/7AQKFVQP+MhBNjcY73JtnsHZfnaVZq3TiKwN151cWV51nDc1RnTaMhSIFeuNlj3vNML2W0Gn8n+GnyiWE2XXdQEaik6BL02eekUn9aq7I/rdpnTHuOjQPK1uwjuNl8RuJ9YrERBAxq4oB71f+iwMab8dsMSUlVC+NdeAocRqLLgnR/efkdLc==2Tkb
+mpih-mul2.c iQCVAwUAP+LkMjEAnp832S/7AQLPeAQAqmRzxFe/mDqTdZr/pTXT8RVyB1vKB0Ei2THV05BxmI4OPv39uysfFpLMt/INsX7AGqdOlj4jOZ/qNaFXR1ceMrlSXvo8u/epk6rCXFp82kM7Qs983LjoP//PrMCkYkXwblaVrgUGiBUCbuPMliWTK6qKkxxXtEfqZ7nVbEWdBx8==Kwhl
+mpih-mul3.c iQCVAwUAP+LkVDEAnp832S/7AQL91gP/Qd5iZWxRiN5DdEIVHAedoNvl23NPrT2UUdXvnSK49DpplTxkLiMBj0WqCayG/YIET2NpMRCeLvAZNcSt6lOm0bSZDYo1Hv/N+UoqD3V1McjY16REBv/nnPaMWMZcx7rl5yKTVZiX2PgV6oQOL7Yfrt5ZIOlrHBRs9S2/zcCaVz0==9BQe
+mpih-lshift.c iQCVAwUAP+LlATEAnp832S/7AQIACAQAhMrpx0SRXE/LN1NkjMO9n74nMrvmzYJyru0gw2O4BYrUPvD/LWGju2FZaggKV0IBjmi0cDoCrNeK9EGjKOO1lfgODbX2IZ1LUhr9jDuMj0QRqj6T9YkAFYTNUk4GfpwIf7T6Ybo7c78Jx93PidCJt7d39eMMEalooC7LZ4IU3NM==nZ4k
+mpih-rshift.c iQCVAwUAP+LlIjEAnp832S/7AQKiuAP/eYC2ZScd+taBx/kNzRvGjA0eAXvORMkMLV6Ot+OXVzVUi04eoP2yXdxSNFKwUj12p8GWXkdoMG3aOGBKg2a7bY5Q5RUho3hUWb9UsVYVUfXLf7IOTt/3a6MLh2CmV5dFPWJmSlbCyQRcn6n/fLDeJ3A2bWTS/BhqGfpOXUIU1ws==jCf8
+mpih-sub1.c iQCVAwUAP+LlZzEAnp832S/7AQIEPgP/dLHTDRbPrYJhsLp9SjGstU1M8/IC5XytcDtO3NQeu4mx6vaXjpujtsTvKIbX4QL5IahNntVVKv1xFLEm2yFg7L2ns0uD/mfwGgOhCG1j2o/SaTAWP5KxP7ae5UDcZl2w6NWvEuMj9t32zmziAZjP8W73A37FUspeRDYiL9sQzkI==QQzk
+udiv-w-sdiv.c iQCVAwUAP+Lk0TEAnp832S/7AQICXAQAsxe1SQD4+xZaZTqBC0V9Cyuo0mrdccnRFzthOtm0ARwKFXU2cuLW/ZBOkmeWOVmOFhBp22/I8dEGYnMA3gcfmOMCpNu9i9zk/XHfptdunA1MnOe3GsoWgfHL0rhpAyPhp/X043ICB41NElnnuxADuQQlD4Z1fca5ygYxMr2crJg==EI/6
+mpi-asm-defs.h iQCVAwUAP+LkgDEAnp832S/7AQK0FgQAxJZ7xvXhoZa33GWe23LRb3asrno/loZSyAIXrntqtVH8M3pEsCY0OyW4ry4hX2RnxpuhRCM/PdRNLG3xXyMSVIhkHU8WVRLqzF2LLjEkyU3cAmHnnTQ9aO/XpUWtJGTZ8q2bv7ZsAEi4aPl0p6KhPXcPgM9vQ2XcyOPn3Dl0d6Q==xpjI
+$names$ iQCVAwUAP+LmNDEAnp832S/7AQJa+gP+KQNJpbNOgc+s2UX+Ya2gDaOFcAROImIllhg3ej8EaBF8xxdHmWT1zaKwTwi3moEEleykMR104YAGWyQeMbFYiuPPBW+ohrT6KxRBVJpIA9auOOqqJMyglZyoR3Hv7gduVYUW1h/DebnqiKXKEfzQDFqYuT0ayuteoOR4B5NICbE==nLSh
--- /dev/null
+Manifest
+mpih-add1.c
+mpih-mul1.c
+mpih-mul2.c
+mpih-mul3.c
+mpih-lshift.c
+mpih-rshift.c
+mpih-sub1.c
+udiv-w-sdiv.c
+mpi-asm-defs.h
+
--- /dev/null
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG)
+
+
+
+
+
+
--- /dev/null
+/* mpihelp-add_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998,
+ * 2000, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_add_n (mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to one addend */
+ cy = y < cy; /* get out carry from that addition */
+ y += x; /* add other addend */
+ cy += y < x; /* get out carry from that add, combine */
+ res_ptr[j] = y;
+ }
+ while ( ++j );
+
+ return cy;
+}
+
--- /dev/null
+/* mpi-lshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/* Shift U (pointed to by UP and USIZE digits long) CNT bits to the left
+ * and store the USIZE least significant digits of the result at WP.
+ * Return the bits shifted out from the most significant digit.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be >= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned int cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp += 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ i = usize - 1;
+ low_limb = up[i];
+ retval = low_limb >> sh_2;
+ high_limb = low_limb;
+ while ( --i >= 0 )
+ {
+ low_limb = up[i];
+ wp[i] = (high_limb << sh_1) | (low_limb >> sh_2);
+ high_limb = low_limb;
+ }
+ wp[i] = high_limb << sh_1;
+
+ return retval;
+}
+
+
--- /dev/null
+/* mpihelp-mul_1.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+
+ /* The loop counter and index J goes from -S1_SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ res_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
--- /dev/null
+/* mpih-mul2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb );
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x + prod_low;
+ cy_limb += prod_low < x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while ( ++j );
+
+ return cy_limb;
+}
+
+
--- /dev/null
+/* mpih-mul3.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+mpi_limb_t
+_gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t cy_limb;
+ mpi_size_t j;
+ mpi_limb_t prod_high, prod_low;
+ mpi_limb_t x;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ * the loop becomes faster. */
+ j = -s1_size;
+ res_ptr -= j;
+ s1_ptr -= j;
+
+ cy_limb = 0;
+ do
+ {
+ umul_ppmm( prod_high, prod_low, s1_ptr[j], s2_limb);
+
+ prod_low += cy_limb;
+ cy_limb = (prod_low < cy_limb?1:0) + prod_high;
+
+ x = res_ptr[j];
+ prod_low = x - prod_low;
+ cy_limb += prod_low > x?1:0;
+ res_ptr[j] = prod_low;
+ }
+ while( ++j );
+
+ return cy_limb;
+}
+
+
--- /dev/null
+/* mpih-rshift.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2000, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+/* Shift U (pointed to by UP and USIZE limbs long) CNT bits to the right
+ * and store the USIZE least significant limbs of the result at WP.
+ * The bits shifted out to the right are returned.
+ *
+ * Argument constraints:
+ * 1. 0 < CNT < BITS_PER_MP_LIMB
+ * 2. If the result is to be written over the input, WP must be <= UP.
+ */
+
+mpi_limb_t
+_gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize, unsigned cnt)
+{
+ mpi_limb_t high_limb, low_limb;
+ unsigned sh_1, sh_2;
+ mpi_size_t i;
+ mpi_limb_t retval;
+
+ sh_1 = cnt;
+ wp -= 1;
+ sh_2 = BITS_PER_MPI_LIMB - sh_1;
+ high_limb = up[0];
+ retval = high_limb << sh_2;
+ low_limb = high_limb;
+ for (i=1; i < usize; i++)
+ {
+ high_limb = up[i];
+ wp[i] = (low_limb >> sh_1) | (high_limb << sh_2);
+ low_limb = high_limb;
+ }
+ wp[i] = low_limb >> sh_1;
+
+ return retval;
+}
+
--- /dev/null
+/* mpihelp-add_2.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1997, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+mpi_limb_t
+_gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size)
+{
+ mpi_limb_t x, y, cy;
+ mpi_size_t j;
+
+ /* The loop counter and index J goes from -SIZE to -1. This way
+ the loop becomes faster. */
+ j = -size;
+
+ /* Offset the base pointers to compensate for the negative indices. */
+ s1_ptr -= j;
+ s2_ptr -= j;
+ res_ptr -= j;
+
+ cy = 0;
+ do
+ {
+ y = s2_ptr[j];
+ x = s1_ptr[j];
+ y += cy; /* add previous carry to subtrahend */
+ cy = y < cy; /* get out carry from that addition */
+ y = x - y; /* main subtract */
+ cy += y > x; /* get out carry from the subtract, combine */
+ res_ptr[j] = y;
+ }
+ while( ++j );
+
+ return cy;
+}
+
+
--- /dev/null
+/* mpih-w-sdiv -- implement udiv_qrnnd on machines with only signed
+ * division.
+ * Copyright (C) 1992, 1994, 1996, 1998, 2002 Free Software Foundation, Inc.
+ * Contributed by Peter L. Montgomery.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#if 0 /* not yet ported to MPI */
+
+mpi_limb_t
+mpihelp_udiv_w_sdiv( mpi_limp_t *rp,
+ mpi_limp_t *a1,
+ mpi_limp_t *a0,
+ mpi_limp_t *d )
+{
+ mp_limb_t q, r;
+ mp_limb_t c0, c1, b1;
+
+ if ((mpi_limb_signed_t) d >= 0)
+ {
+ if (a1 < d - a1 - (a0 >> (BITS_PER_MP_LIMB - 1)))
+ {
+ /* dividend, divisor, and quotient are nonnegative */
+ sdiv_qrnnd (q, r, a1, a0, d);
+ }
+ else
+ {
+ /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
+ sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (BITS_PER_MP_LIMB - 1));
+ /* Divide (c1*2^32 + c0) by d */
+ sdiv_qrnnd (q, r, c1, c0, d);
+ /* Add 2^31 to quotient */
+ q += (mp_limb_t) 1 << (BITS_PER_MP_LIMB - 1);
+ }
+ }
+ else
+ {
+ b1 = d >> 1; /* d/2, between 2^30 and 2^31 - 1 */
+ c1 = a1 >> 1; /* A/2 */
+ c0 = (a1 << (BITS_PER_MP_LIMB - 1)) + (a0 >> 1);
+
+ if (a1 < b1) /* A < 2^32*b1, so A/2 < 2^31*b1 */
+ {
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ r = 2*r + (a0 & 1); /* Remainder from A/(2*b1) */
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else if (c1 < b1) /* So 2^31 <= (A/2)/b1 < 2^32 */
+ {
+ c1 = (b1 - 1) - c1;
+ c0 = ~c0; /* logical NOT */
+
+ sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
+
+ q = ~q; /* (A/2)/b1 */
+ r = (b1 - 1) - r;
+
+ r = 2*r + (a0 & 1); /* A/(2*b1) */
+
+ if ((d & 1) != 0)
+ {
+ if (r >= q)
+ r = r - q;
+ else if (q - r <= d)
+ {
+ r = r - q + d;
+ q--;
+ }
+ else
+ {
+ r = r - q + 2*d;
+ q -= 2;
+ }
+ }
+ }
+ else /* Implies c1 = b1 */
+ { /* Hence a1 = d - 1 = 2*b1 - 1 */
+ if (a0 >= -d)
+ {
+ q = -1;
+ r = a0 + d;
+ }
+ else
+ {
+ q = -2;
+ r = a0 + 2*d;
+ }
+ }
+ }
+
+ *rp = r;
+ return q;
+}
+
+#endif
+
--- /dev/null
+This directory contains mpn functions for various HP PA-RISC chips. Code
+that runs faster on the PA7100 and later implementations, is in the pa7100
+directory.
+
+RELEVANT OPTIMIZATION ISSUES
+
+ Load and Store timing
+
+On the PA7000 no memory instructions can issue the two cycles after a store.
+For the PA7100, this is reduced to one cycle.
+
+The PA7100 has a lookup-free cache, so it helps to schedule loads and the
+dependent instruction really far from each other.
+
+STATUS
+
+1. mpn_mul_1 could be improved to 6.5 cycles/limb on the PA7100, using the
+ instructions bwlow (but some sw pipelining is needed to avoid the
+ xmpyu-fstds delay):
+
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib Loop
+
+2. mpn_addmul_1 could be improved from the current 10 to 7.5 cycles/limb
+ (asymptotically) on the PA7100, using the instructions below. With proper
+ sw pipelining and the unrolling level below, the speed becomes 8
+ cycles/limb.
+
+ fldds s1_ptr
+ fldds s1_ptr
+
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+ xmpyu
+ fstds N(%r30)
+
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ ldws N(%r30)
+ addc
+ addc
+ addc
+ addc
+ addc %r0,%r0,cy-limb
+
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ ldws res_ptr
+ add
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+ addc
+ stws res_ptr
+
+ addib
--- /dev/null
+README
+udiv-qrnnd.S
+mpih-add1.S
+mpih-sub1.S
+mpih-lshift.S
+mpih-rshift.S
+
--- /dev/null
+/* hppa add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Fee Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+ .code
+ .export _gcry_mpih_add_n
+ .label _gcry_mpih_add_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ add %r20,%r19,%r28 ; add first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ addc %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r0,%r28
+
+ .exit
+ .procend
--- /dev/null
+/* hppa lshift
+ *
+ * Copyright (C) 1992, 1994, 1998
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,= -1,%r24,L$0002
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,= -1,%r24,L$0003
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,<> -1,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$0002
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$0003
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
--- /dev/null
+/* hppa rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,= -1,%r24,L$r002
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,= -1,%r24,L$r003
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,<> -1,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$r002
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$r003
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
--- /dev/null
+/* hppa sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (gr26)
+ * mpi_ptr_t s1_ptr, (gr25)
+ * mpi_ptr_t s2_ptr, (gr24)
+ * mpi_size_t size) (gr23)
+ *
+ * One might want to unroll this as for other processors, but it turns
+ * out that the data cache contention after a store makes such
+ * unrolling useless. We can't come under 5 cycles/limb anyway.
+ */
+
+
+ .code
+ .export _gcry_mpih_sub_n
+ .label _gcry_mpih_sub_n
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+
+ addib,= -1,%r23,L$end ; check for (SIZE == 1)
+ sub %r20,%r19,%r28 ; subtract first limbs ignoring cy
+
+ .label L$loop
+ ldws,ma 4(0,%r25),%r20
+ ldws,ma 4(0,%r24),%r19
+ stws,ma %r28,4(0,%r26)
+ addib,<> -1,%r23,L$loop
+ subb %r20,%r19,%r28
+
+ .label L$end
+ stws %r28,0(0,%r26)
+ addc %r0,%r0,%r28
+ bv 0(%r2)
+ subi 1,%r28,%r28
+
+ .exit
+ .procend
+
+
+
--- /dev/null
+/* HP-PA __udiv_qrnnd division support, used from longlong.h.
+ * This version runs fast on pre-PA7000 CPUs.
+ *
+ * Copyright (C) 1993, 1994, 1998, 2001,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/* INPUT PARAMETERS
+ * rem_ptr gr26
+ * n1 gr25
+ * n0 gr24
+ * d gr23
+ *
+ * The code size is a bit excessive. We could merge the last two ds;addc
+ * sequences by simply moving the "bb,< Odd" instruction down. The only
+ * trouble is the FFFFFFFF code that would need some hacking.
+ */
+
+ .code
+ .export __udiv_qrnnd
+ .label __udiv_qrnnd
+ .proc
+ .callinfo frame=0,no_calls
+ .entry
+
+ comb,< %r23,0,L$largedivisor
+ sub %r0,%r23,%r1 ; clear cy as side-effect
+ ds %r0,%r1,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r23,%r25
+ addc %r24,%r24,%r28
+ ds %r25,%r23,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r23,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r28,%r28,%r28
+
+ .label L$largedivisor
+ extru %r24,31,1,%r19 ; r19 = n0 & 1
+ bb,< %r23,31,L$odd
+ extru %r23,30,31,%r22 ; r22 = d >> 1
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r24,%r24,%r28
+
+ .label L$odd
+ addib,sv,n 1,%r22,L$FF.. ; r22 = (d / 2 + 1)
+ shd %r25,%r24,1,%r24 ; r24 = new n0
+ extru %r25,30,31,%r25 ; r25 = new n1
+ sub %r0,%r22,%r21
+ ds %r0,%r21,%r0
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r24
+ ds %r25,%r22,%r25
+ addc %r24,%r24,%r28
+ comclr,>= %r25,%r0,%r0
+ addl %r25,%r22,%r25
+ sh1addl %r25,%r19,%r25
+; We have computed (n1,,n0) / (d + 1), q' = r28, r' = r25
+ add,nuv %r28,%r25,%r25
+ addl %r25,%r1,%r25
+ addc %r0,%r28,%r28
+ sub,<< %r25,%r23,%r0
+ addl %r25,%r1,%r25
+ stws %r25,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r28,%r28
+
+; This is just a special case of the code above.
+; We come here when d == 0xFFFFFFFF
+ .label L$FF..
+ add,uv %r25,%r24,%r24
+ sub,<< %r24,%r23,%r0
+ ldo 1(%r24),%r24
+ stws %r24,0(0,%r26)
+ bv 0(%r2)
+ addc %r0,%r25,%r28
+
+ .exit
+ .procend
--- /dev/null
+udiv-qrnnd.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
--- /dev/null
+/* hppa1.1 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ *
+ *
+ * This runs at 9 cycles/limb on a PA7000. With the used instructions, it can
+ * not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 7 cycles/limb, and that can not be improved either, since
+ * only the xmpyu does not need the integer pipeline, so the only dual-issue
+ * we will get are addc+xmpyu. Unrolling would not help either CPU.
+ *
+ * We could use fldds to read two limbs at a time from the S1 array, and that
+ * could bring down the times to 8.5 and 6.5 cycles/limb for the PA7000 and
+ * PA7100, respectively. We don't do that since it does not seem worth the
+ * (alignment) troubles...
+ *
+ * At least the PA7100 is rumored to be able to deal with cache-misses
+ * without stalling instruction issue. If this is true, and the cache is
+ * actually also lockup-free, we should use a deeper software pipeline, and
+ * load from S1 very early! (The loads and stores to -12(sp) will surely be
+ * in the cache.)
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_mul_1
+ .label _gcry_mpih_mul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ fldws,ma 4(%r25),%fr5
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ fstds %fr6,-16(%r30)
+ ldw -16(%r30),%r28
+ ldo -64(%r30),%r30
+ bv 0(%r2)
+ fstws %fr6R,0(%r26)
+
+ .exit
+ .procend
+
+
--- /dev/null
+/* hppa1.1 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ * This runs at 11 cycles/limb on a PA7000. With the used instructions, it
+ * can not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 10 cycles/limb, and that can not be improved either,
+ * since only the xmpyu does not need the integer pipeline, so the only
+ * dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+ * on the PA7100.
+ *
+ * There are some ideas described in mul1.S that applies to this code too.
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_addmul_1
+ .label _gcry_mpih_addmul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ ldw 0(%r26),%r29
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ add %r29,%r19,%r19
+ stws,ma %r19,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ add %r29,%r1,%r19
+ stw %r19,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
+
+
--- /dev/null
+/* hppa1.1 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r26)
+ * mpi_ptr_t s1_ptr, (r25)
+ * mpi_size_t s1_size, (r24)
+ * mpi_limb_t s2_limb) (r23)
+ *
+ *
+ * This runs at 12 cycles/limb on a PA7000. With the used instructions, it
+ * can not become faster due to data cache contention after a store. On the
+ * PA7100 it runs at 11 cycles/limb, and that can not be improved either,
+ * since only the xmpyu does not need the integer pipeline, so the only
+ * dual-issue we will get are addc+xmpyu. Unrolling could gain a cycle/limb
+ * on the PA7100.
+ *
+ * There are some ideas described in mul1.S that applies to this code too.
+ *
+ * It seems possible to make this run as fast as addmul_1, if we use
+ * sub,>>= %r29,%r19,%r22
+ * addi 1,%r28,%r28
+ * but that requires reworking the hairy software pipeline...
+ */
+
+ .level 1.1
+
+ .code
+ .export _gcry_mpih_submul_1
+ .label _gcry_mpih_submul_1
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldo 64(%r30),%r30
+ fldws,ma 4(%r25),%fr5
+ stw %r23,-16(%r30) ; move s2_limb ...
+ addib,= -1,%r24,L$just_one_limb
+ fldws -16(%r30),%fr4 ; ... into fr4
+ add %r0,%r0,%r0 ; clear carry
+ xmpyu %fr4,%fr5,%fr6
+ fldws,ma 4(%r25),%fr7
+ fstds %fr6,-16(%r30)
+ xmpyu %fr4,%fr7,%fr8
+ ldw -12(%r30),%r19 ; least significant limb in product
+ ldw -16(%r30),%r28
+
+ fstds %fr8,-16(%r30)
+ addib,= -1,%r24,L$end
+ ldw -12(%r30),%r1
+
+; Main loop
+ .label L$loop
+ ldws 0(%r26),%r29
+ fldws,ma 4(%r25),%fr5
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ xmpyu %fr4,%fr5,%fr6
+ ldw -16(%r30),%r28
+ fstds %fr6,-16(%r30)
+ addc %r0,%r28,%r28
+ addib,<> -1,%r24,L$loop
+ ldw -12(%r30),%r1
+
+ .label L$end
+ ldw 0(%r26),%r29
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r28,%r1,%r19
+ ldw -16(%r30),%r28
+ ldws 0(%r26),%r29
+ addc %r0,%r28,%r28
+ sub %r29,%r19,%r22
+ add %r22,%r19,%r0
+ stws,ma %r22,4(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .label L$just_one_limb
+ xmpyu %fr4,%fr5,%fr6
+ ldw 0(%r26),%r29
+ fstds %fr6,-16(%r30)
+ ldw -12(%r30),%r1
+ ldw -16(%r30),%r28
+ sub %r29,%r1,%r22
+ add %r22,%r1,%r0
+ stw %r22,0(%r26)
+ addc %r0,%r28,%r28
+ bv 0(%r2)
+ ldo -64(%r30),%r30
+
+ .exit
+ .procend
+
--- /dev/null
+/* HP-PA __udiv_qrnnd division support, used from longlong.h.
+ * This version runs fast on PA 7000 and later.
+ *
+ * Copyright (C) 1993, 1994, 1998,
+ * 2001, 2002, 2004 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+/* INPUT PARAMETERS
+ * rem_ptr gr26
+ * n1 gr25
+ * n0 gr24
+ * d gr23
+ */
+
+ .level 1.1
+
+ .data
+ .align 8
+ .label L$0000
+ .word 0x43f00000
+ .word 0x0
+ .code
+ .export __udiv_qrnnd
+ .label __udiv_qrnnd
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+ ldo 64(%r30),%r30
+
+ stws %r25,-16(0,%r30) ; n_hi
+ stws %r24,-12(0,%r30) ; n_lo
+ stw %r19,-32(%r30)
+ addil LT%L$0000,%r19
+ ldw RT%L$0000(%r1),%r1
+ fldds -16(0,%r30),%fr5
+ stws %r23,-12(0,%r30)
+ comib,<= 0,%r25,L$1
+ fcnvxf,dbl,dbl %fr5,%fr5
+ fldds 0(0,%r1),%fr4
+ fadd,dbl %fr4,%fr5,%fr5
+ .label L$1
+ fcpy,sgl %fr0,%fr6L
+ fldws -12(0,%r30),%fr6R
+ fcnvxf,dbl,dbl %fr6,%fr4
+
+ fdiv,dbl %fr5,%fr4,%fr5
+
+ fcnvfx,dbl,dbl %fr5,%fr4
+ fstws %fr4R,-16(%r30)
+ xmpyu %fr4R,%fr6R,%fr6
+ ldws -16(%r30),%r28
+ fstds %fr6,-16(0,%r30)
+ ldws -12(0,%r30),%r21
+ ldws -16(0,%r30),%r20
+ sub %r24,%r21,%r22
+ subb %r25,%r20,%r1
+ comib,= 0,%r1,L$2
+ ldo -64(%r30),%r30
+
+ add %r22,%r23,%r22
+ ldo -1(%r28),%r28
+ .label L$2
+ bv 0(%r2)
+ stws %r22,0(0,%r26)
+
+ .exit
+ .procend
+
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+syntax.h
+$names$ iQCVAwUAP+LmOTEAnp832S/7AQJZmgQA1+GIl7rXiEY00y5xD2kG5Lm2QD6c9aBME8hTl812OEcj0ul/QSpdv8E2NEKooifr4SiLVhEVfLNaLqAgN3cIsttn3rRX3/pMC5JwSKHDJPsUbpN9tzb5dr2YC9GG9m8xngAQrN11IQPnGfvFLJK+oDnEMIAeHDpOnX9NeQPDAQA==bnOy
--- /dev/null
+Manifest
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+syntax.h
+
--- /dev/null
+/* i80386 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ adcl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ adcl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ adcl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ adcl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ adcl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ adcl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ adcl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ adcl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* i80386 lshift
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* res_ptr */
+ movl 20(%esp),%esi /* s_ptr */
+ movl 24(%esp),%edx /* size */
+ movl 28(%esp),%ecx /* cnt */
+
+ subl $4,%esi /* adjust s_ptr */
+
+ movl (%esi,%edx,4),%ebx /* read most significant limb */
+ xorl %eax,%eax
+ shldl %cl,%ebx,%eax /* compute carry limb */
+ decl %edx
+ jz Lend
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L1 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop: movl (%esi,%edx,4),%ebx /* load next lower limb */
+ shldl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ decl %edx
+L1: movl (%esi,%edx,4),%eax
+ shldl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ decl %edx
+ jnz Loop
+
+ shll %cl,%eax /* compute least significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend: shll %cl,%ebx /* compute least significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* i80386 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80386 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80386 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+Loop:
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+ INSN1(mul,l ,R(s2_limb))
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,MEM_INDEX(res_ptr,size,4),R(eax))
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(mov,l ,R(ebx),R(edx))
+
+ INSN1(inc,l ,R(size))
+ INSN1(jnz, ,Loop)
+ INSN2(mov,l ,R(eax),R(ebx))
+
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80386 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+
+ movl 16(%esp),%edi /* wp */
+ movl 20(%esp),%esi /* up */
+ movl 24(%esp),%edx /* usize */
+ movl 28(%esp),%ecx /* cnt */
+
+ leal -4(%edi,%edx,4),%edi
+ leal (%esi,%edx,4),%esi
+ negl %edx
+
+ movl (%esi,%edx,4),%ebx /* read least significant limb */
+ xorl %eax,%eax
+ shrdl %cl,%ebx,%eax /* compute carry limb */
+ incl %edx
+ jz Lend2
+ pushl %eax /* push carry limb onto stack */
+ testb $1,%dl
+ jnz L2 /* enter loop in the middle */
+ movl %ebx,%eax
+
+ ALIGN (3)
+Loop2: movl (%esi,%edx,4),%ebx /* load next higher limb */
+ shrdl %cl,%ebx,%eax /* compute result limb */
+ movl %eax,(%edi,%edx,4) /* store it */
+ incl %edx
+L2: movl (%esi,%edx,4),%eax
+ shrdl %cl,%eax,%ebx
+ movl %ebx,(%edi,%edx,4)
+ incl %edx
+ jnz Loop2
+
+ shrl %cl,%eax /* compute most significant limb */
+ movl %eax,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+Lend2: shrl %cl,%ebx /* compute most significant limb */
+ movl %ebx,(%edi) /* store it */
+
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* i80386 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+ pushl %edi
+ pushl %esi
+
+ movl 12(%esp),%edi /* res_ptr */
+ movl 16(%esp),%esi /* s1_ptr */
+ movl 20(%esp),%edx /* s2_ptr */
+ movl 24(%esp),%ecx /* size */
+
+ movl %ecx,%eax
+ shrl $3,%ecx /* compute count for unrolled loop */
+ negl %eax
+ andl $7,%eax /* get index where to start loop */
+ jz Loop /* necessary special case for 0 */
+ incl %ecx /* adjust loop count */
+ shll $2,%eax /* adjustment for pointers... */
+ subl %eax,%edi /* ... since they are offset ... */
+ subl %eax,%esi /* ... by a constant when we ... */
+ subl %eax,%edx /* ... enter the loop */
+ shrl $2,%eax /* restore previous value */
+#ifdef PIC
+/* Calculate start address in loop for PIC. Due to limitations in some
+ assemblers, Loop-L0-3 cannot be put into the leal */
+ call L0
+L0: leal (%eax,%eax,8),%eax
+ addl (%esp),%eax
+ addl $(Loop-L0-3),%eax
+ addl $4,%esp
+#else
+/* Calculate start address in loop for non-PIC. */
+ leal (Loop - 3)(%eax,%eax,8),%eax
+#endif
+ jmp *%eax /* jump into loop */
+ ALIGN (3)
+Loop: movl (%esi),%eax
+ sbbl (%edx),%eax
+ movl %eax,(%edi)
+ movl 4(%esi),%eax
+ sbbl 4(%edx),%eax
+ movl %eax,4(%edi)
+ movl 8(%esi),%eax
+ sbbl 8(%edx),%eax
+ movl %eax,8(%edi)
+ movl 12(%esi),%eax
+ sbbl 12(%edx),%eax
+ movl %eax,12(%edi)
+ movl 16(%esi),%eax
+ sbbl 16(%edx),%eax
+ movl %eax,16(%edi)
+ movl 20(%esi),%eax
+ sbbl 20(%edx),%eax
+ movl %eax,20(%edi)
+ movl 24(%esi),%eax
+ sbbl 24(%edx),%eax
+ movl %eax,24(%edi)
+ movl 28(%esi),%eax
+ sbbl 28(%edx),%eax
+ movl %eax,28(%edi)
+ leal 32(%edi),%edi
+ leal 32(%esi),%esi
+ leal 32(%edx),%edx
+ decl %ecx
+ jnz Loop
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* syntax.h -- Definitions for x86 syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#undef ALIGN
+
+#if defined (BSD_SYNTAX) || defined (ELF_SYNTAX)
+#define R(r) %r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)displacement(R(base))
+#define MEM_INDEX(base,index,size)(R(base),R(index),size)
+#ifdef __STDC__
+#define INSN1(mnemonic,size_suffix,dst)mnemonic##size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic##size_suffix src,dst
+#else
+#define INSN1(mnemonic,size_suffix,dst)mnemonic/**/size_suffix dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic/**/size_suffix src,dst
+#endif
+#define TEXT .text
+#if defined (BSD_SYNTAX)
+#define ALIGN(log) .align log
+#endif
+#if defined (ELF_SYNTAX)
+#define ALIGN(log) .align 1<<(log)
+#endif
+#define GLOBL .globl
+#endif
+
+#ifdef INTEL_SYNTAX
+#define R(r) r
+#define MEM(base)[base]
+#define MEM_DISP(base,displacement)[base+(displacement)]
+#define MEM_INDEX(base,index,size)[base+index*size]
+#define INSN1(mnemonic,size_suffix,dst)mnemonic dst
+#define INSN2(mnemonic,size_suffix,dst,src)mnemonic dst,src
+#define TEXT .text
+#define ALIGN(log) .align log
+#define GLOBL .globl
+#endif
+
+#ifdef X86_BROKEN_ALIGN
+#undef ALIGN
+#define ALIGN(log) .align log,0x90
+#endif
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmQDEAnp832S/7AQKCmgQAhG+E7X0KB4qdVf3sMb6Qr+Iv5Jlehzoub/5vxTRgePKzRuOHidCnTzSSoyzA++UcHrOjHQQDMsXnO6PqpS1d/TKkxjnGN7rE8mvMYlFAT8RsawTozSfh14mCzI0HTDbaKL9Z8pcMJtadB3XqAuqWJNO8kyECJFwurt3DRWXSWS8==Rug5
--- /dev/null
+This directory contains mpn functions optimized for Intel Pentium
+processors.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. Pentium doesn't allocate cache lines on writes, unlike most other modern
+processors. Since the functions in the mpn class do array writes, we have to
+handle allocating the destination cache lines by reading a word from it in the
+loops, to achieve the best performance.
+
+2. Pairing of memory operations requires that the two issued operations refer
+to different cache banks. The simplest way to insure this is to read/write
+two words from the same object. If we make operations on different objects,
+they might or might not be to the same cache bank.
+
+STATUS
+
+1. mpn_lshift and mpn_rshift run at about 6 cycles/limb, but the Pentium
+documentation indicates that they should take only 43/8 = 5.375 cycles/limb,
+or 5 cycles/limb asymptotically.
+
+2. mpn_add_n and mpn_sub_n run at asymptotically 2 cycles/limb. Due to loop
+overhead and other delays (cache refill?), they run at or near 2.5 cycles/limb.
+
+3. mpn_mul_1, mpn_addmul_1, mpn_submul_1 all run 1 cycle faster than they
+should...
--- /dev/null
+Manifest
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpih-sub1.S
+README
+
--- /dev/null
+/* i80586 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ adcl %ebx,%eax
+ movl 12(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ adcl %ebx,%eax
+ movl 20(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %ebx,%eax
+ movl 28(%ebp),%ebx
+ adcl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ adcl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
--- /dev/null
+/* i80586 lshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Lnormal
+ leal 4(%esi),%eax
+ cmpl %edi,%eax
+ jnc Lspecial /* jump if s_ptr + 1 >= res_ptr */
+ leal (%esi,%ebp,4),%eax
+ cmpl %eax,%edi
+ jnc Lspecial /* jump if res_ptr >= s_ptr + size */
+
+Lnormal:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+ xorl %eax,%eax
+ shldl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Lend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Loop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ shldl %cl,%ebx,%edx
+ shldl %cl,%eax,%ebx
+ movl %edx,-8(%edi)
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ shldl %cl,%edx,%eax
+ shldl %cl,%ebx,%edx
+ movl %eax,-16(%edi)
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ shldl %cl,%eax,%ebx
+ shldl %cl,%edx,%eax
+ movl %ebx,-24(%edi)
+ movl %eax,-28(%edi)
+
+ subl $32,%esi
+ subl $32,%edi
+ decl %ebp
+ jnz Loop
+
+Lend: popl %ebp
+ andl $7,%ebp
+ jz Lend2
+Loop2: movl (%esi),%eax
+ shldl %cl,%eax,%edx
+ movl %edx,(%edi)
+ movl %eax,%edx
+ subl $4,%esi
+ subl $4,%edi
+ decl %ebp
+ jnz Loop2
+
+Lend2: shll %cl,%edx /* compute least significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Lspecial:
+ movl (%esi),%edx
+ addl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ addl %edx,%edx
+ incl %ebp
+ decl %ebp
+ jz LLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+LLoop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,(%edi)
+ adcl %edx,%edx
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ adcl %ebx,%ebx
+ movl %edx,8(%edi)
+ adcl %eax,%eax
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ adcl %edx,%edx
+ movl %eax,16(%edi)
+ adcl %ebx,%ebx
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ adcl %eax,%eax
+ movl %ebx,24(%edi)
+ adcl %edx,%edx
+ movl %eax,28(%edi)
+
+ leal 32(%esi),%esi /* use leal not to clobber carry */
+ leal 32(%edi),%edi
+ decl %ebp
+ jnz LLoop
+
+LLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz LLend2
+ addl %eax,%eax /* restore carry from eax */
+LLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ adcl %edx,%edx
+ movl %ebx,(%edi)
+
+ leal 4(%esi),%esi /* use leal not to clobber carry */
+ leal 4(%edi),%edi
+ decl %ebp
+ jnz LLoop2
+
+ jmp LL1
+LLend2: addl %eax,%eax /* restore carry from eax */
+LL1: movl %edx,(%edi) /* store last limb */
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+
--- /dev/null
+/* i80586 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80586 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(add,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80586 submul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+#define res_ptr edi
+#define s1_ptr esi
+#define size ecx
+#define s2_limb ebp
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ INSN1(push,l ,R(edi))
+ INSN1(push,l ,R(esi))
+ INSN1(push,l ,R(ebx))
+ INSN1(push,l ,R(ebp))
+
+ INSN2(mov,l ,R(res_ptr),MEM_DISP(esp,20))
+ INSN2(mov,l ,R(s1_ptr),MEM_DISP(esp,24))
+ INSN2(mov,l ,R(size),MEM_DISP(esp,28))
+ INSN2(mov,l ,R(s2_limb),MEM_DISP(esp,32))
+
+ INSN2(lea,l ,R(res_ptr),MEM_INDEX(res_ptr,size,4))
+ INSN2(lea,l ,R(s1_ptr),MEM_INDEX(s1_ptr,size,4))
+ INSN1(neg,l ,R(size))
+ INSN2(xor,l ,R(ebx),R(ebx))
+ ALIGN (3)
+
+Loop: INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),MEM_INDEX(s1_ptr,size,4))
+
+ INSN1(mul,l ,R(s2_limb))
+
+ INSN2(add,l ,R(eax),R(ebx))
+ INSN2(mov,l ,R(ebx),MEM_INDEX(res_ptr,size,4))
+
+ INSN2(adc,l ,R(edx),$0)
+ INSN2(sub,l ,R(ebx),R(eax))
+
+ INSN2(mov,l ,MEM_INDEX(res_ptr,size,4),R(ebx))
+ INSN1(inc,l ,R(size))
+
+ INSN2(mov,l ,R(ebx),R(edx))
+ INSN1(jnz, ,Loop)
+
+ INSN2(adc,l ,R(ebx),$0)
+ INSN2(mov,l ,R(eax),R(ebx))
+ INSN1(pop,l ,R(ebp))
+ INSN1(pop,l ,R(ebx))
+ INSN1(pop,l ,R(esi))
+ INSN1(pop,l ,R(edi))
+ ret
+
--- /dev/null
+/* i80586 rshift
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s_ptr */
+ movl 28(%esp),%ebp /* size */
+ movl 32(%esp),%ecx /* cnt */
+
+/* We can use faster code for shift-by-1 under certain conditions. */
+ cmp $1,%ecx
+ jne Rnormal
+ leal 4(%edi),%eax
+ cmpl %esi,%eax
+ jnc Rspecial /* jump if res_ptr + 1 >= s_ptr */
+ leal (%edi,%ebp,4),%eax
+ cmpl %eax,%esi
+ jnc Rspecial /* jump if s_ptr >= res_ptr + size */
+
+Rnormal:
+ movl (%esi),%edx
+ addl $4,%esi
+ xorl %eax,%eax
+ shrdl %cl,%edx,%eax /* compute carry limb */
+ pushl %eax /* push carry limb onto stack */
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+ jz Rend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+Roop: movl 28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl 4(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,(%edi)
+ movl %eax,4(%edi)
+
+ movl 8(%esi),%ebx
+ movl 12(%esi),%eax
+ shrdl %cl,%ebx,%edx
+ shrdl %cl,%eax,%ebx
+ movl %edx,8(%edi)
+ movl %ebx,12(%edi)
+
+ movl 16(%esi),%edx
+ movl 20(%esi),%ebx
+ shrdl %cl,%edx,%eax
+ shrdl %cl,%ebx,%edx
+ movl %eax,16(%edi)
+ movl %edx,20(%edi)
+
+ movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ shrdl %cl,%eax,%ebx
+ shrdl %cl,%edx,%eax
+ movl %ebx,24(%edi)
+ movl %eax,28(%edi)
+
+ addl $32,%esi
+ addl $32,%edi
+ decl %ebp
+ jnz Roop
+
+Rend: popl %ebp
+ andl $7,%ebp
+ jz Rend2
+Roop2: movl (%esi),%eax
+ shrdl %cl,%eax,%edx /* compute result limb */
+ movl %edx,(%edi)
+ movl %eax,%edx
+ addl $4,%esi
+ addl $4,%edi
+ decl %ebp
+ jnz Roop2
+
+Rend2: shrl %cl,%edx /* compute most significant limb */
+ movl %edx,(%edi) /* store it */
+
+ popl %eax /* pop carry limb */
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination.
+*/
+
+Rspecial:
+ leal -4(%edi,%ebp,4),%edi
+ leal -4(%esi,%ebp,4),%esi
+
+ movl (%esi),%edx
+ subl $4,%esi
+
+ decl %ebp
+ pushl %ebp
+ shrl $3,%ebp
+
+ shrl $1,%edx
+ incl %ebp
+ decl %ebp
+ jz RLend
+
+ movl (%edi),%eax /* fetch destination cache line */
+
+ ALIGN (2)
+RLoop: movl -28(%edi),%eax /* fetch destination cache line */
+ movl %edx,%ebx
+
+ movl (%esi),%eax
+ movl -4(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,(%edi)
+ rcrl $1,%edx
+ movl %eax,-4(%edi)
+
+ movl -8(%esi),%ebx
+ movl -12(%esi),%eax
+ rcrl $1,%ebx
+ movl %edx,-8(%edi)
+ rcrl $1,%eax
+ movl %ebx,-12(%edi)
+
+ movl -16(%esi),%edx
+ movl -20(%esi),%ebx
+ rcrl $1,%edx
+ movl %eax,-16(%edi)
+ rcrl $1,%ebx
+ movl %edx,-20(%edi)
+
+ movl -24(%esi),%eax
+ movl -28(%esi),%edx
+ rcrl $1,%eax
+ movl %ebx,-24(%edi)
+ rcrl $1,%edx
+ movl %eax,-28(%edi)
+
+ leal -32(%esi),%esi /* use leal not to clobber carry */
+ leal -32(%edi),%edi
+ decl %ebp
+ jnz RLoop
+
+RLend: popl %ebp
+ sbbl %eax,%eax /* save carry in %eax */
+ andl $7,%ebp
+ jz RLend2
+ addl %eax,%eax /* restore carry from eax */
+RLoop2: movl %edx,%ebx
+ movl (%esi),%edx
+ rcrl $1,%edx
+ movl %ebx,(%edi)
+
+ leal -4(%esi),%esi /* use leal not to clobber carry */
+ leal -4(%edi),%edi
+ decl %ebp
+ jnz RLoop2
+
+ jmp RL1
+RLend2: addl %eax,%eax /* restore carry from eax */
+RL1: movl %edx,(%edi) /* store last limb */
+
+ movl $0,%eax
+ rcrl $1,%eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* i80586 sub_n -- Sub two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pushl %edi
+ pushl %esi
+ pushl %ebx
+ pushl %ebp
+
+ movl 20(%esp),%edi /* res_ptr */
+ movl 24(%esp),%esi /* s1_ptr */
+ movl 28(%esp),%ebp /* s2_ptr */
+ movl 32(%esp),%ecx /* size */
+
+ movl (%ebp),%ebx
+
+ decl %ecx
+ movl %ecx,%edx
+ shrl $3,%ecx
+ andl $7,%edx
+ testl %ecx,%ecx /* zero carry flag */
+ jz Lend
+ pushl %edx
+
+ ALIGN (3)
+Loop: movl 28(%edi),%eax /* fetch destination cache line */
+ leal 32(%edi),%edi
+
+L1: movl (%esi),%eax
+ movl 4(%esi),%edx
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 8(%ebp),%ebx
+ movl %eax,-32(%edi)
+ movl %edx,-28(%edi)
+
+L2: movl 8(%esi),%eax
+ movl 12(%esi),%edx
+ sbbl %ebx,%eax
+ movl 12(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 16(%ebp),%ebx
+ movl %eax,-24(%edi)
+ movl %edx,-20(%edi)
+
+L3: movl 16(%esi),%eax
+ movl 20(%esi),%edx
+ sbbl %ebx,%eax
+ movl 20(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 24(%ebp),%ebx
+ movl %eax,-16(%edi)
+ movl %edx,-12(%edi)
+
+L4: movl 24(%esi),%eax
+ movl 28(%esi),%edx
+ sbbl %ebx,%eax
+ movl 28(%ebp),%ebx
+ sbbl %ebx,%edx
+ movl 32(%ebp),%ebx
+ movl %eax,-8(%edi)
+ movl %edx,-4(%edi)
+
+ leal 32(%esi),%esi
+ leal 32(%ebp),%ebp
+ decl %ecx
+ jnz Loop
+
+ popl %edx
+Lend:
+ decl %edx /* test %edx w/o clobbering carry */
+ js Lend2
+ incl %edx
+Loop2:
+ leal 4(%edi),%edi
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl 4(%ebp),%ebx
+ movl %eax,-4(%edi)
+ leal 4(%esi),%esi
+ leal 4(%ebp),%ebp
+ decl %edx
+ jnz Loop2
+Lend2:
+ movl (%esi),%eax
+ sbbl %ebx,%eax
+ movl %eax,(%edi)
+
+ sbbl %eax,%eax
+ negl %eax
+
+ popl %ebp
+ popl %ebx
+ popl %esi
+ popl %edi
+ ret
+
--- /dev/null
+/* longlong.h -- definitions for mixed size 32/64 bit arithmetic.
+ Note: I added some stuff for use with gnupg
+
+Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
+ 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+This file 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with this file; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+/* You have to define the following before including this file:
+
+ UWtype -- An unsigned type, default type for operations (typically a "word")
+ UHWtype -- An unsigned type, at least half the size of UWtype.
+ UDWtype -- An unsigned type, at least twice as large a UWtype
+ W_TYPE_SIZE -- size in bits of UWtype
+
+ SItype, USItype -- Signed and unsigned 32 bit types.
+ DItype, UDItype -- Signed and unsigned 64 bit types.
+
+ On a 32 bit machine UWtype should typically be USItype;
+ on a 64 bit machine, UWtype should typically be UDItype.
+*/
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2))
+
+/* This is used to make sure no undesirable sharing between different libraries
+ that use this file takes place. */
+#ifndef __MPN
+#define __MPN(x) __##x
+#endif
+
+/* Define auxiliary asm macros.
+
+ 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two
+ UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype
+ word product in HIGH_PROD and LOW_PROD.
+
+ 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a
+ UDWtype product. This is just a variant of umul_ppmm.
+
+ 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator) divides a UDWtype, composed by the UWtype integers
+ HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient
+ in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less
+ than DENOMINATOR for correct operation. If, in addition, the most
+ significant bit of DENOMINATOR must be 1, then the pre-processor symbol
+ UDIV_NEEDS_NORMALIZATION is defined to 1.
+
+ 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator,
+ denominator). Like udiv_qrnnd but the numbers are signed. The quotient
+ is rounded towards 0.
+
+ 5) count_leading_zeros(count, x) counts the number of zero-bits from the
+ msb to the first non-zero bit in the UWtype X. This is the number of
+ steps X needs to be shifted left to set the msb. Undefined for X == 0,
+ unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value.
+
+ 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts
+ from the least significant end.
+
+ 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1,
+ high_addend_2, low_addend_2) adds two UWtype integers, composed by
+ HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2
+ respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow
+ (i.e. carry out) is not stored anywhere, and is lost.
+
+ 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend,
+ high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers,
+ composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and
+ LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE
+ and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere,
+ and is lost.
+
+ If any of these macros are left undefined for a particular CPU,
+ C macros are used. */
+
+/* The CPUs come in alphabetical order below.
+
+ Please add support for more CPUs here, or improve the current support
+ for the CPUs below! */
+
+#ifdef __riscos__
+#pragma continue_after_hash_error
+#else /* !__riscos__ */
+#if defined (__GNUC__) && !defined (NO_ASM)
+
+/* We sometimes need to clobber "cc" with gcc2, but that would not be
+ understood by gcc1. Use cpp to avoid major code duplication. */
+#if __GNUC__ < 2
+#define __CLOBBER_CC
+#define __AND_CLOBBER_CC
+#else /* __GNUC__ >= 2 */
+#define __CLOBBER_CC : "cc"
+#define __AND_CLOBBER_CC , "cc"
+#endif /* __GNUC__ < 2 */
+
+
+/***************************************
+ ************** A29K *****************
+ ***************************************/
+#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %1,%4,%5\n" \
+ "addc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %1,%4,%5\n" \
+ "subc %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("multiplu %0,%1,%2" \
+ : "=r" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ __asm__ ("multmu %0,%1,%2" \
+ : "=r" ((USItype)(xh)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("dividu %0,%3,%4" \
+ : "=r" ((USItype)(q)), \
+ "=q" ((USItype)(r)) \
+ : "1" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#endif /* __a29k__ */
+
+
+#if defined (__alpha) && W_TYPE_SIZE == 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("umulh %r1,%2,%0" \
+ : "=r" ((UDItype) ph) \
+ : "%rJ" (__m0), \
+ "rI" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 46
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { UDItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern UDItype __udiv_qrnnd ();
+#define UDIV_TIME 220
+#endif /* LONGLONG_STANDALONE */
+#endif /* __alpha */
+
+/***************************************
+ ************** ARM ******************
+ ***************************************/
+#if defined (__arm__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("adds %1, %4, %5\n" \
+ "adc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subs %1, %4, %5\n" \
+ "sbc %0, %2, %3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "r" ((USItype)(al)), \
+ "rI" ((USItype)(bl)))
+#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "mov %|r0, %2, lsr #16 @ AAAA\n" \
+ "mov %|r2, %3, lsr #16 @ BBBB\n" \
+ "bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
+ "bic %0, %3, %|r2, lsl #16 @ bbbb\n" \
+ "mul %1, %|r1, %|r2 @ aaaa * BBBB\n" \
+ "mul %|r2, %|r0, %|r2 @ AAAA * BBBB\n" \
+ "mul %|r1, %0, %|r1 @ aaaa * bbbb\n" \
+ "mul %0, %|r0, %0 @ AAAA * bbbb\n" \
+ "adds %|r0, %1, %0 @ central sum\n" \
+ "addcs %|r2, %|r2, #65536\n" \
+ "adds %1, %|r1, %|r0, lsl #16\n" \
+ "adc %0, %|r2, %|r0, lsr #16" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1", "r2")
+#else
+#define umul_ppmm(xh, xl, a, b) \
+ __asm__ ("%@ Inlined umul_ppmm\n" \
+ "umull %r1, %r0, %r2, %r3" \
+ : "=&r" ((USItype)(xh)), \
+ "=r" ((USItype)(xl)) \
+ : "r" ((USItype)(a)), \
+ "r" ((USItype)(b)) \
+ : "r0", "r1")
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 100
+#endif /* __arm__ */
+
+/***************************************
+ ************** CLIPPER **************
+ ***************************************/
+#if defined (__clipper__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define smul_ppmm(w1, w0, u, v) \
+ ({union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("mulwx %2,%0" \
+ : "=r" (__xx.__ll) \
+ : "%0" ((SItype)(u)), \
+ "r" ((SItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("mulwux %2,%0" \
+ : "=r" (__w) \
+ : "%0" ((USItype)(u)), \
+ "r" ((USItype)(v))); \
+ __w; })
+#endif /* __clipper__ */
+
+
+/***************************************
+ ************** GMICRO ***************
+ ***************************************/
+#if defined (__gmicro__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add.w %5,%1\n" \
+ "addx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub.w %5,%1\n" \
+ "subx %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ __asm__ ("mulx %3,%0,%1" \
+ : "=g" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%0" ((USItype)(m0)), \
+ "g" ((USItype)(m1)))
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("divx %4,%0,%1" \
+ : "=g" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "1" ((USItype)(nh)), \
+ "0" ((USItype)(nl)), \
+ "g" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bsch/1 %1,%0" \
+ : "=g" (count) \
+ : "g" ((USItype)(x)), \
+ "0" ((USItype)0))
+#endif
+
+
+/***************************************
+ ************** HPPA *****************
+ ***************************************/
+#if defined (__hppa) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ (" add %4,%5,%1\n" \
+ " addc %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "%rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ (" sub %4,%5,%1\n" \
+ " subb %2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rM" ((USItype)(ah)), \
+ "rM" ((USItype)(bh)), \
+ "rM" ((USItype)(al)), \
+ "rM" ((USItype)(bl)))
+#if defined (_PA_RISC1_1)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ (" xmpyu %1,%2,%0" \
+ : "=*f" (__xx.__ll) \
+ : "*f" ((USItype)(u)), \
+ "*f" ((USItype)(v))); \
+ (wh) = __xx.__i.__h; \
+ (wl) = __xx.__i.__l; \
+ } while (0)
+#define UMUL_TIME 8
+#define UDIV_TIME 60
+#else
+#define UMUL_TIME 40
+#define UDIV_TIME 80
+#endif
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#endif /* LONGLONG_STANDALONE */
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __tmp; \
+ __asm__ ( \
+ " ldi 1,%0 \n" \
+ " extru,= %1,15,16,%%r0 ; Bits 31..16 zero? \n" \
+ " extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \
+ " ldo 16(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,23,8,%%r0 ; Bits 15..8 zero? \n" \
+ " extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \
+ " ldo 8(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,27,4,%%r0 ; Bits 7..4 zero? \n" \
+ " extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \
+ " ldo 4(%0),%0 ; Yes. Perform add. \n" \
+ " extru,= %1,29,2,%%r0 ; Bits 3..2 zero? \n" \
+ " extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \
+ " ldo 2(%0),%0 ; Yes. Perform add. \n" \
+ " extru %1,30,1,%1 ; Extract bit 1. \n" \
+ " sub %0,%1,%0 ; Subtract it. " \
+ : "=r" (count), "=r" (__tmp) : "1" (x)); \
+ } while (0)
+#endif /* hppa */
+
+
+/***************************************
+ ************** I370 *****************
+ ***************************************/
+#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "r" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define smul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("mr %0,%3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (m0), \
+ "r" (m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("dr %0,%2" \
+ : "=r" (__xx.__ll) \
+ : "0" (__xx.__ll), "r" (d)); \
+ (q) = __xx.__i.__l; (r) = __xx.__i.__h; \
+ } while (0)
+#endif
+
+
+/***************************************
+ ************** I386 *****************
+ ***************************************/
+#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl %5,%1\n" \
+ "adcl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl %5,%1\n" \
+ "sbbl %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mull %3" \
+ : "=a" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "rm" ((USItype)(v)))
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divl %4" \
+ : "=a" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "rm" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("bsrl %1,%0" \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define count_trailing_zeros(count, x) \
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* 80x86 */
+
+
+/***************************************
+ ************** I860 *****************
+ ***************************************/
+#if defined (__i860__) && W_TYPE_SIZE == 32
+#define rshift_rhlc(r,h,l,c) \
+ __asm__ ("shr %3,r0,r0\n" \
+ "shrd %1,%2,%0" \
+ "=r" (r) : "r" (h), "r" (l), "rn" (c))
+#endif /* i860 */
+
+/***************************************
+ ************** I960 *****************
+ ***************************************/
+#if defined (__i960__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 1,0\n" \
+ "addc %5,%4,%1\n" \
+ "addc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "%dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("cmpo 0,0\n" \
+ "subc %5,%4,%1\n" \
+ "subc %3,%2,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "dI" ((USItype)(ah)), \
+ "dI" ((USItype)(bh)), \
+ "dI" ((USItype)(al)), \
+ "dI" ((USItype)(bl)))
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__xx.__ll) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("emul %2,%1,%0" \
+ : "=d" (__w) \
+ : "%dI" ((USItype)(u)), \
+ "dI" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (nh); __nn.__i.__l = (nl); \
+ __asm__ ("ediv %d,%n,%0" \
+ : "=d" (__rq.__ll) \
+ : "dI" (__nn.__ll), \
+ "dI" ((USItype)(d))); \
+ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("scanbit %1,%0" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 (-32) /* sic */
+#if defined (__i960mx) /* what is the proper symbol to test??? */
+#define rshift_rhlc(r,h,l,c) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __nn; \
+ __nn.__i.__h = (h); __nn.__i.__l = (l); \
+ __asm__ ("shre %2,%1,%0" \
+ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \
+ }
+#endif /* i960mx */
+#endif /* i960 */
+
+
+/***************************************
+ ************** 68000 ****************
+ ***************************************/
+#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add%.l %5,%1\n" \
+ "addx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub%.l %5,%1\n" \
+ "subx%.l %3,%0" \
+ : "=d" ((USItype)(sh)), \
+ "=&d" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "d" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("mulu%.l %3,%1:%0" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "%0" ((USItype)(u)), \
+ "dmi" ((USItype)(v)))
+#define UMUL_TIME 45
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divu%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define UDIV_TIME 90
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("divs%.l %4,%1:%0" \
+ : "=d" ((USItype)(q)), \
+ "=d" ((USItype)(r)) \
+ : "0" ((USItype)(n0)), \
+ "1" ((USItype)(n1)), \
+ "dmi" ((USItype)(d)))
+#define count_leading_zeros(count, x) \
+ __asm__ ("bfffo %1{%b2:%b2},%0" \
+ : "=d" ((USItype)(count)) \
+ : "od" ((USItype)(x)), "n" (0))
+#define COUNT_LEADING_ZEROS_0 32
+#else /* not mc68020 */
+#define umul_ppmm(xh, xl, a, b) \
+ do { USItype __umul_tmp1, __umul_tmp2; \
+ __asm__ ("| Inlined umul_ppmm \n" \
+ " move%.l %5,%3 \n" \
+ " move%.l %2,%0 \n" \
+ " move%.w %3,%1 \n" \
+ " swap %3 \n" \
+ " swap %0 \n" \
+ " mulu %2,%1 \n" \
+ " mulu %3,%0 \n" \
+ " mulu %2,%3 \n" \
+ " swap %2 \n" \
+ " mulu %5,%2 \n" \
+ " add%.l %3,%2 \n" \
+ " jcc 1f \n" \
+ " add%.l %#0x10000,%0 \n" \
+ "1: move%.l %2,%3 \n" \
+ " clr%.w %2 \n" \
+ " swap %2 \n" \
+ " swap %3 \n" \
+ " clr%.w %3 \n" \
+ " add%.l %3,%1 \n" \
+ " addx%.l %2,%0 \n" \
+ " | End inlined umul_ppmm" \
+ : "=&d" ((USItype)(xh)), "=&d" ((USItype)(xl)), \
+ "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \
+ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \
+ } while (0)
+#define UMUL_TIME 100
+#define UDIV_TIME 400
+#endif /* not mc68020 */
+#endif /* mc68000 */
+
+
+/***************************************
+ ************** 88000 ****************
+ ***************************************/
+#if defined (__m88000__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addu.co %1,%r4,%r5\n" \
+ "addu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subu.co %1,%r4,%r5\n" \
+ "subu.ci %0,%r2,%r3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rJ" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rJ" ((USItype)(bl)))
+#define count_leading_zeros(count, x) \
+ do { \
+ USItype __cbtmp; \
+ __asm__ ("ff1 %0,%1" \
+ : "=r" (__cbtmp) \
+ : "r" ((USItype)(x))); \
+ (count) = __cbtmp ^ 31; \
+ } while (0)
+#define COUNT_LEADING_ZEROS_0 63 /* sic */
+#if defined (__m88110__)
+#define umul_ppmm(wh, wl, u, v) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x; \
+ __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \
+ (wh) = __x.__i.__h; \
+ (wl) = __x.__i.__l; \
+ } while (0)
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __x, __q; \
+ __x.__i.__h = (n1); __x.__i.__l = (n0); \
+ __asm__ ("divu.d %0,%1,%2" \
+ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \
+ (r) = (n0) - __q.__l * (d); (q) = __q.__l; })
+#define UMUL_TIME 5
+#define UDIV_TIME 25
+#else
+#define UMUL_TIME 17
+#define UDIV_TIME 150
+#endif /* __m88110__ */
+#endif /* __m88000__ */
+
+/***************************************
+ ************** MIPS *****************
+ ***************************************/
+#if defined (__mips__) && W_TYPE_SIZE == 32
+#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UDItype _r; \
+ _r = (UDItype) u * v; \
+ (w1) = _r >> 32; \
+ (w0) = (USItype) _r; \
+ } while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3" \
+ : "=l" ((USItype)(w0)), \
+ "=h" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("multu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((USItype)(w0)), \
+ "=d" ((USItype)(w1)) \
+ : "d" ((USItype)(u)), \
+ "d" ((USItype)(v)))
+#endif
+#define UMUL_TIME 10
+#define UDIV_TIME 100
+#endif /* __mips__ */
+
+/***************************************
+ ************** MIPS/64 **************
+ ***************************************/
+#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64
+#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+typedef unsigned int UTItype __attribute__ ((mode (TI)));
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UTItype _r; \
+ _r = (UTItype) u * v; \
+ (w1) = _r >> 64; \
+ (w0) = (UDItype) _r; \
+ } while (0)
+#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3" \
+ : "=l" ((UDItype)(w0)), \
+ "=h" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#else
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("dmultu %2,%3 \n" \
+ "mflo %0 \n" \
+ "mfhi %1" \
+ : "=d" ((UDItype)(w0)), \
+ "=d" ((UDItype)(w1)) \
+ : "d" ((UDItype)(u)), \
+ "d" ((UDItype)(v)))
+#endif
+#define UMUL_TIME 20
+#define UDIV_TIME 140
+#endif /* __mips__ */
+
+
+/***************************************
+ ************** 32000 ****************
+ ***************************************/
+#if defined (__ns32000__) && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#define __umulsidi3(u, v) \
+ ({UDItype __w; \
+ __asm__ ("meid %2,%0" \
+ : "=g" (__w) \
+ : "%0" ((USItype)(u)), \
+ "g" ((USItype)(v))); \
+ __w; })
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ ({union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = (n1); __xx.__i.__l = (n0); \
+ __asm__ ("deid %2,%0" \
+ : "=g" (__xx.__ll) \
+ : "0" (__xx.__ll), \
+ "g" ((USItype)(d))); \
+ (r) = __xx.__i.__l; (q) = __xx.__i.__h; })
+#define count_trailing_zeros(count,x) \
+ do {
+ __asm__ ("ffsd %2,%0" \
+ : "=r" ((USItype) (count)) \
+ : "0" ((USItype) 0), \
+ "r" ((USItype) (x))); \
+ } while (0)
+#endif /* __ns32000__ */
+
+
+/***************************************
+ ************** PPC ******************
+ ***************************************/
+#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%r" ((USItype)(al)), \
+ "rI" ((USItype)(bl))); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "r" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "rI" ((USItype)(al)), \
+ "r" ((USItype)(bl))); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("{cntlz|cntlzw} %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x)))
+#define COUNT_LEADING_ZEROS_0 32
+#if defined (_ARCH_PPC)
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhwu %0,%1,%2" \
+ : "=r" ((USItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ SItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhw %0,%1,%2" \
+ : "=r" ((SItype) ph) \
+ : "%r" (__m0), \
+ "r" (__m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14
+#define UDIV_TIME 120
+#else
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((USItype)(xh)), \
+ "=q" ((USItype)(xl)) \
+ : "r" (__m0), \
+ "r" (__m1)); \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 8
+#define smul_ppmm(xh, xl, m0, m1) \
+ __asm__ ("mul %0,%2,%3" \
+ : "=r" ((SItype)(xh)), \
+ "=q" ((SItype)(xl)) \
+ : "r" (m0), \
+ "r" (m1))
+#define SMUL_TIME 4
+#define sdiv_qrnnd(q, r, nh, nl, d) \
+ __asm__ ("div %0,%2,%4" \
+ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \
+ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d)))
+#define UDIV_TIME 100
+#endif
+#endif /* Power architecture variants. */
+
+/* Powerpc 64 bit support taken from gmp-4.1.2. */
+/* We should test _IBMR2 here when we add assembly support for the system
+ vendor compilers. */
+#if 0 /* Not yet enabled because we don't have hardware for a test. */
+#if (defined (_ARCH_PPC) || defined (__powerpc__)) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\
+ else \
+ __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
+ : "=r" (sh), "=&r" (sl) \
+ : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \
+ } while (0)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ if (__builtin_constant_p (ah) && (ah) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \
+ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
+ : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\
+ else \
+ __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
+ : "=r" (sh), "=&r" (sl) \
+ : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \
+ } while (0)
+#define count_leading_zeros(count, x) \
+ __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x))
+#define COUNT_LEADING_ZEROS_0 64
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ UDItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define UMUL_TIME 15
+#define smul_ppmm(ph, pl, m0, m1) \
+ do { \
+ DItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \
+ (pl) = __m0 * __m1; \
+ } while (0)
+#define SMUL_TIME 14 /* ??? */
+#define UDIV_TIME 120 /* ??? */
+#endif /* 64-bit PowerPC. */
+#endif /* if 0 */
+
+/***************************************
+ ************** PYR ******************
+ ***************************************/
+#if defined (__pyr__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addw %5,%1 \n" \
+ "addwc %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subw %5,%1 \n" \
+ "subwb %3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */
+#define umul_ppmm(w1, w0, u, v) \
+ ({union {UDItype __ll; \
+ struct {USItype __h, __l;} __i; \
+ } __xx; \
+ __asm__ ("movw %1,%R0 \n" \
+ "uemul %2,%0" \
+ : "=&r" (__xx.__ll) \
+ : "g" ((USItype) (u)), \
+ "g" ((USItype)(v))); \
+ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;})
+#endif /* __pyr__ */
+
+
+/***************************************
+ ************** RT/ROMP **************
+ ***************************************/
+#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("a %1,%5 \n" \
+ "ae %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("s %1,%5\n" \
+ "se %0,%3" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "r" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "r" ((USItype)(bl)))
+#define umul_ppmm(ph, pl, m0, m1) \
+ do { \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ( \
+ "s r2,r2 \n" \
+ "mts r10,%2 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "m r2,%3 \n" \
+ "cas %0,r2,r0 \n" \
+ "mfs r10,%1" \
+ : "=r" ((USItype)(ph)), \
+ "=r" ((USItype)(pl)) \
+ : "%r" (__m0), \
+ "r" (__m1) \
+ : "r2"); \
+ (ph) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define UMUL_TIME 20
+#define UDIV_TIME 200
+#define count_leading_zeros(count, x) \
+ do { \
+ if ((x) >= 0x10000) \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x) >> 16)); \
+ else \
+ { \
+ __asm__ ("clz %0,%1" \
+ : "=r" ((USItype)(count)) \
+ : "r" ((USItype)(x))); \
+ (count) += 16; \
+ } \
+ } while (0)
+#endif /* RT/ROMP */
+
+
+/***************************************
+ ************** SH2 ******************
+ ***************************************/
+#if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \
+ && W_TYPE_SIZE == 32
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ( \
+ "dmulu.l %2,%3\n" \
+ "sts macl,%1\n" \
+ "sts mach,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "macl", "mach")
+#define UMUL_TIME 5
+#endif
+
+/***************************************
+ ************** SPARC ****************
+ ***************************************/
+#if defined (__sparc__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addcc %r4,%5,%1\n" \
+ "addx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "%rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "%rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subcc %r4,%5,%1\n" \
+ "subx %r2,%3,%0" \
+ : "=r" ((USItype)(sh)), \
+ "=&r" ((USItype)(sl)) \
+ : "rJ" ((USItype)(ah)), \
+ "rI" ((USItype)(bh)), \
+ "rJ" ((USItype)(al)), \
+ "rI" ((USItype)(bl)) \
+ __CLOBBER_CC)
+#if defined (__sparc_v8__)
+/* Don't match immediate range because, 1) it is not often useful,
+ 2) the 'I' flag thinks of the range as a 13 bit signed interval,
+ while we want to match a 13 bit interval, sign extended to 32 bits,
+ but INTERPRETED AS UNSIGNED. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ USItype __q; \
+ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \
+ : "=r" ((USItype)(__q)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "r" ((USItype)(d))); \
+ (r) = (n0) - __q * (d); \
+ (q) = __q; \
+ } while (0)
+#define UDIV_TIME 25
+#endif /* SUPERSPARC */
+#else /* ! __sparc_v8__ */
+#if defined (__sparclite__)
+/* This has hardware multiply but not divide. It also has two additional
+ instructions scan (ffs from high bit) and divscc. */
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("umul %2,%3,%1;rd %%y,%0" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "r" ((USItype)(u)), \
+ "r" ((USItype)(v)))
+#define UMUL_TIME 5
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ __asm__ ("! Inlined udiv_qrnnd \n" \
+ " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \
+ " tst %%g0 \n" \
+ " divscc %3,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%%g1 \n" \
+ " divscc %%g1,%4,%0 \n" \
+ " rd %%y,%1 \n" \
+ " bl,a 1f \n" \
+ " add %1,%4,%1 \n" \
+ "1: ! End of inline udiv_qrnnd" \
+ : "=r" ((USItype)(q)), \
+ "=r" ((USItype)(r)) \
+ : "r" ((USItype)(n1)), \
+ "r" ((USItype)(n0)), \
+ "rI" ((USItype)(d)) \
+ : "%g1" __AND_CLOBBER_CC)
+#define UDIV_TIME 37
+#define count_leading_zeros(count, x) \
+ __asm__ ("scan %1,0,%0" \
+ : "=r" ((USItype)(x)) \
+ : "r" ((USItype)(count)))
+/* Early sparclites return 63 for an argument of 0, but they warn that future
+ implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0
+ undefined. */
+#endif /* __sparclite__ */
+#endif /* __sparc_v8__ */
+/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */
+#ifndef umul_ppmm
+#define umul_ppmm(w1, w0, u, v) \
+ __asm__ ("! Inlined umul_ppmm \n" \
+ " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \
+ " sra %3,31,%%g2 ! Don't move this insn \n" \
+ " and %2,%%g2,%%g2 ! Don't move this insn \n" \
+ " andcc %%g0,0,%%g1 ! Don't move this insn \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,%3,%%g1 \n" \
+ " mulscc %%g1,0,%%g1 \n" \
+ " add %%g1,%%g2,%0 \n" \
+ " rd %%y,%1" \
+ : "=r" ((USItype)(w1)), \
+ "=r" ((USItype)(w0)) \
+ : "%rI" ((USItype)(u)), \
+ "r" ((USItype)(v)) \
+ : "%g1", "%g2" __AND_CLOBBER_CC)
+#define UMUL_TIME 39 /* 39 instructions */
+#endif
+#ifndef udiv_qrnnd
+#ifndef LONGLONG_STANDALONE
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { USItype __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
+ } while (0)
+extern USItype __udiv_qrnnd ();
+#define UDIV_TIME 140
+#endif /* LONGLONG_STANDALONE */
+#endif /* udiv_qrnnd */
+#endif /* __sparc__ */
+
+
+/***************************************
+ ************** VAX ******************
+ ***************************************/
+#if defined (__vax__) && W_TYPE_SIZE == 32
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("addl2 %5,%1\n" \
+ "adwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "%0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "%1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("subl2 %5,%1\n" \
+ "sbwc %3,%0" \
+ : "=g" ((USItype)(sh)), \
+ "=&g" ((USItype)(sl)) \
+ : "0" ((USItype)(ah)), \
+ "g" ((USItype)(bh)), \
+ "1" ((USItype)(al)), \
+ "g" ((USItype)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {UDItype __ll; \
+ struct {USItype __l, __h;} __i; \
+ } __xx; \
+ USItype __m0 = (m0), __m1 = (m1); \
+ __asm__ ("emul %1,%2,$0,%0" \
+ : "=g" (__xx.__ll) \
+ : "g" (__m0), \
+ "g" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((SItype) __m0 >> 31) & __m1) \
+ + (((SItype) __m1 >> 31) & __m0)); \
+ } while (0)
+#define sdiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ union {DItype __ll; \
+ struct {SItype __l, __h;} __i; \
+ } __xx; \
+ __xx.__i.__h = n1; __xx.__i.__l = n0; \
+ __asm__ ("ediv %3,%2,%0,%1" \
+ : "=g" (q), "=g" (r) \
+ : "g" (__xx.__ll), "g" (d)); \
+ } while (0)
+#endif /* __vax__ */
+
+
+/***************************************
+ ************** Z8000 ****************
+ ***************************************/
+#if defined (__z8000__) && W_TYPE_SIZE == 16
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "%0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "%1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \
+ : "=r" ((unsigned int)(sh)), \
+ "=&r" ((unsigned int)(sl)) \
+ : "0" ((unsigned int)(ah)), \
+ "r" ((unsigned int)(bh)), \
+ "1" ((unsigned int)(al)), \
+ "rQR" ((unsigned int)(bl)))
+#define umul_ppmm(xh, xl, m0, m1) \
+ do { \
+ union {long int __ll; \
+ struct {unsigned int __h, __l;} __i; \
+ } __xx; \
+ unsigned int __m0 = (m0), __m1 = (m1); \
+ __asm__ ("mult %S0,%H3" \
+ : "=r" (__xx.__i.__h), \
+ "=r" (__xx.__i.__l) \
+ : "%1" (__m0), \
+ "rQR" (__m1)); \
+ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \
+ (xh) += ((((signed int) __m0 >> 15) & __m1) \
+ + (((signed int) __m1 >> 15) & __m0)); \
+ } while (0)
+#endif /* __z8000__ */
+
+#endif /* __GNUC__ */
+#endif /* !__riscos__ */
+
+
+/***************************************
+ *********** Generic Versions ********
+ ***************************************/
+#if !defined (umul_ppmm) && defined (__umulsidi3)
+#define umul_ppmm(ph, pl, m0, m1) \
+ { \
+ UDWtype __ll = __umulsidi3 (m0, m1); \
+ ph = (UWtype) (__ll >> W_TYPE_SIZE); \
+ pl = (UWtype) __ll; \
+ }
+#endif
+
+#if !defined (__umulsidi3)
+#define __umulsidi3(u, v) \
+ ({UWtype __hi, __lo; \
+ umul_ppmm (__hi, __lo, u, v); \
+ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; })
+#endif
+
+/* If this machine has no inline assembler, use C macros. */
+
+#if !defined (add_ssaaaa)
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) + (bl); \
+ (sh) = (ah) + (bh) + (__x < (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (sub_ddmmss)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ UWtype __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __x0, __x1, __x2, __x3; \
+ UHWtype __ul, __vl, __uh, __vh; \
+ UWtype __u = (u), __v = (v); \
+ \
+ __ul = __ll_lowpart (__u); \
+ __uh = __ll_highpart (__u); \
+ __vl = __ll_lowpart (__v); \
+ __vh = __ll_highpart (__v); \
+ \
+ __x0 = (UWtype) __ul * __vl; \
+ __x1 = (UWtype) __ul * __vh; \
+ __x2 = (UWtype) __uh * __vl; \
+ __x3 = (UWtype) __uh * __vh; \
+ \
+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \
+ __x1 += __x2; /* but this indeed can */ \
+ if (__x1 < __x2) /* did we get it? */ \
+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \
+ \
+ (w1) = __x3 + __ll_highpart (__x1); \
+ (w0) = (__ll_lowpart (__x1) << W_TYPE_SIZE/2) + __ll_lowpart (__x0);\
+ } while (0)
+#endif
+
+#if !defined (umul_ppmm)
+#define smul_ppmm(w1, w0, u, v) \
+ do { \
+ UWtype __w1; \
+ UWtype __m0 = (u), __m1 = (v); \
+ umul_ppmm (__w1, w0, __m0, __m1); \
+ (w1) = __w1 - (-(__m0 >> (W_TYPE_SIZE - 1)) & __m1) \
+ - (-(__m1 >> (W_TYPE_SIZE - 1)) & __m0); \
+ } while (0)
+#endif
+
+/* Define this unconditionally, so it can be used for debugging. */
+#define __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \
+ __d1 = __ll_highpart (d); \
+ __d0 = __ll_lowpart (d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (UWtype) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \
+ if (__r1 < __m) \
+ { \
+ __q1--, __r1 += (d); \
+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (UWtype) __q0 * __d0; \
+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \
+ if (__r0 < __m) \
+ { \
+ __q0--, __r0 += (d); \
+ if (__r0 >= (d)) \
+ if (__r0 < __m) \
+ __q0--, __r0 += (d); \
+ } \
+ __r0 -= __m; \
+ \
+ (q) = (UWtype) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through
+ __udiv_w_sdiv (defined in libgcc or elsewhere). */
+#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd)
+#define udiv_qrnnd(q, r, nh, nl, d) \
+ do { \
+ UWtype __r; \
+ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \
+ (r) = __r; \
+ } while (0)
+#endif
+
+/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */
+#if !defined (udiv_qrnnd)
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+#endif
+
+#if !defined (count_leading_zeros)
+extern
+#ifdef __STDC__
+const
+#endif
+unsigned char _gcry_clz_tab[];
+#define MPI_INTERNAL_NEED_CLZ_TAB 1
+#define count_leading_zeros(count, x) \
+ do { \
+ UWtype __xr = (x); \
+ UWtype __a; \
+ \
+ if (W_TYPE_SIZE <= 32) \
+ { \
+ __a = __xr < ((UWtype) 1 << 2*__BITS4) \
+ ? (__xr < ((UWtype) 1 << __BITS4) ? 0 : __BITS4) \
+ : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 : 3*__BITS4);\
+ } \
+ else \
+ { \
+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \
+ if (((__xr >> __a) & 0xff) != 0) \
+ break; \
+ } \
+ \
+ (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \
+ } while (0)
+/* This version gives a well-defined value for zero. */
+#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE
+#endif
+
+#if !defined (count_trailing_zeros)
+/* Define count_trailing_zeros using count_leading_zeros. The latter might be
+ defined in asm, but if it is not, the C version above is good enough. */
+#define count_trailing_zeros(count, x) \
+ do { \
+ UWtype __ctz_x = (x); \
+ UWtype __ctz_c; \
+ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \
+ (count) = W_TYPE_SIZE - 1 - __ctz_c; \
+ } while (0)
+#endif
+
+#ifndef UDIV_NEEDS_NORMALIZATION
+#define UDIV_NEEDS_NORMALIZATION 0
+#endif
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+syntax.h
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmTDEAnp832S/7AQJHUAP/dxfq2U0pDc5ZLoEizoqgjjcnHIyb9EjMG3YjvgK6jQ62yoAOCuo/jFYlJS+Mdve6bgfdTzYMrnKV7BG2SEcwb263pVnIntS7ZhKQPiMCbFgXWR2VjN3+a1v8yjQDZtgqEgm8OlQ+u7jKBY13Oryiuq5nPNxsXZqJpelG6Zkdg9M==PIee
--- /dev/null
+Manifest
+syntax.h
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+mpih-sub1.S
+
+
+
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+$names$ iQCVAwUAP+LmRTEAnp832S/7AQK3rwP/TyGBbii5HCrjDiLCVJHiDNeOdENx6AicRXnu4vuJmMmPZ0y+i7MPusDaeTbIUA0w6RaJx+Ep41nIvthmNDnFePY5Mw0pIUJcpI7AJR4vYqpwNQA6nlEdn/m1jg6sPLKZXUXNUkhroEzcHzoU+12BPS+nvSXlwSksg6rXEGOJ+Ms==XCXP
--- /dev/null
+Manifest
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
--- /dev/null
+/* mc68020 __mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_mul_1:)
+PROLOG(_gcry_mpih_mul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d4),MEM_PREDEC(sp)
+#if 0
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(d3),MEM_PREDEC(sp)
+ movel R(d4),MEM_PREDEC(sp)
+#endif
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,16),R(res_ptr)
+ movel MEM_DISP(sp,20),R(s1_ptr)
+ movel MEM_DISP(sp,24),R(s1_size)
+ movel MEM_DISP(sp,28),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ movel R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ clrl R(d3)
+ addxl R(d3),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d4)
+#if 0
+ movel MEM_POSTINC(sp),R(d4)
+ movel MEM_POSTINC(sp),R(d3)
+ movel MEM_POSTINC(sp),R(d2)
+#endif
+ rts
+EPILOG(_gcry_mpih_mul_1)
+
+
--- /dev/null
+/* mc68020 __mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+PROLOG(_gcry_mpih_addmul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ addl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ addl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_addmul_1)
+
--- /dev/null
+/* mc68020 __mpn_submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+PROLOG(_gcry_mpih_submul_1)
+
+#define res_ptr a0
+#define s1_ptr a1
+#define s1_size d2
+#define s2_limb d4
+
+/* Save used registers on the stack. */
+ moveml R(d2)-R(d5),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,20),R(res_ptr)
+ movel MEM_DISP(sp,24),R(s1_ptr)
+ movel MEM_DISP(sp,28),R(s1_size)
+ movel MEM_DISP(sp,32),R(s2_limb)
+
+ eorw #1,R(s1_size)
+ clrl R(d1)
+ clrl R(d5)
+ lsrl #1,R(s1_size)
+ bcc L(L1)
+ subql #1,R(s1_size)
+ subl R(d0),R(d0) /* (d0,cy) <= (0,0) */
+
+L(Loop:)
+ movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d1):R(d3)
+ addxl R(d0),R(d3)
+ addxl R(d5),R(d1)
+ subl R(d3),MEM_POSTINC(res_ptr)
+L(L1:) movel MEM_POSTINC(s1_ptr),R(d3)
+ mulul R(s2_limb),R(d0):R(d3)
+ addxl R(d1),R(d3)
+ addxl R(d5),R(d0)
+ subl R(d3),MEM_POSTINC(res_ptr)
+
+ dbf R(s1_size),L(Loop)
+ addxl R(d5),R(d0)
+ subl #0x10000,R(s1_size)
+ bcc L(Loop)
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d5)
+
+ rts
+EPILOG(_gcry_mpih_submul_1)
+
+
--- /dev/null
+/* mc68020 __mpn_add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994,1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+PROLOG(_gcry_mpih_add_n)
+ /* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ addxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+ /* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_add_n)
+
+
--- /dev/null
+/* mc68020 lshift -- Shift left a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_lshift)
+
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+PROLOG(_gcry_mpih_lshift)
+
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Lnormal)
+ cmpl R(s_ptr),R(res_ptr)
+ bls L(Lspecial) /* jump if s_ptr >= res_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(s_ptr,d0,l),R(a2)
+#endif
+ cmpl R(res_ptr),R(a2)
+ bls L(Lspecial) /* jump if res_ptr >= s_ptr + s_size */
+
+L(Lnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsrl R(d5),R(d0) /* compute carry limb */
+
+ lsll R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Lend)
+ lsrl #1,R(s_size)
+ bcs L(L1)
+ subql #1,R(s_size)
+
+L(Loop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d2)
+L(L1:)
+ movel MEM_PREDEC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsrl R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+ lsll R(cnt),R(d1)
+
+ dbf R(s_size),L(Loop)
+ subl #0x10000,R(s_size)
+ bcc L(Loop)
+
+L(Lend:)
+ movel R(d1),MEM_PREDEC(res_ptr) /* store least significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from least significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Lspecial:)
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LL1)
+ subql #1,R(s_size)
+
+L(LLoop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+L(LL1:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ addxl R(d2),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+
+ dbf R(s_size),L(LLoop)
+ addxl R(d0),R(d0) /* save cy in lsb */
+ subl #0x10000,R(s_size)
+ bcs L(LLend)
+ lsrl #1,R(d0) /* restore cy */
+ bra L(LLoop)
+
+L(LLend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_lshift)
+
+
+
+
+
--- /dev/null
+/* mc68020 rshift -- Shift right a low-level natural-number integer.
+ *
+ * Copyright (C) 1996, 1998, 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ */
+
+#define res_ptr a1
+#define s_ptr a0
+#define s_size d6
+#define cnt d4
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_rshift)
+
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+PROLOG(_gcry_mpih_rshift)
+ /* Save used registers on the stack. */
+ moveml R(d2)-R(d6)/R(a2),MEM_PREDEC(sp)
+
+ /* Copy the arguments to registers. */
+ movel MEM_DISP(sp,28),R(res_ptr)
+ movel MEM_DISP(sp,32),R(s_ptr)
+ movel MEM_DISP(sp,36),R(s_size)
+ movel MEM_DISP(sp,40),R(cnt)
+
+ moveql #1,R(d5)
+ cmpl R(d5),R(cnt)
+ bne L(Rnormal)
+ cmpl R(res_ptr),R(s_ptr)
+ bls L(Rspecial) /* jump if res_ptr >= s_ptr */
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(a2)
+#else /* not mc68020 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ lea MEM_INDX(res_ptr,d0,l),R(a2)
+#endif
+ cmpl R(s_ptr),R(a2)
+ bls L(Rspecial) /* jump if s_ptr >= res_ptr + s_size */
+
+L(Rnormal:)
+ moveql #32,R(d5)
+ subl R(cnt),R(d5)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d0)
+ lsll R(d5),R(d0) /* compute carry limb */
+
+ lsrl R(cnt),R(d2)
+ movel R(d2),R(d1)
+ subql #1,R(s_size)
+ beq L(Rend)
+ lsrl #1,R(s_size)
+ bcs L(R1)
+ subql #1,R(s_size)
+
+L(Roop:)
+ movel MEM_POSTINC(s_ptr),R(d2)
+ movel R(d2),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d1)
+ movel R(d1),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d2)
+L(R1:)
+ movel MEM_POSTINC(s_ptr),R(d1)
+ movel R(d1),R(d3)
+ lsll R(d5),R(d3)
+ orl R(d3),R(d2)
+ movel R(d2),MEM_POSTINC(res_ptr)
+ lsrl R(cnt),R(d1)
+
+ dbf R(s_size),L(Roop)
+ subl #0x10000,R(s_size)
+ bcc L(Roop)
+
+L(Rend:)
+ movel R(d1),MEM(res_ptr) /* store most significant limb */
+
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+
+/* We loop from most significant end of the arrays, which is only
+ permissable if the source and destination don't overlap, since the
+ function is documented to work for overlapping source and destination. */
+
+L(Rspecial:)
+#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020))
+ lea MEM_INDX1(s_ptr,s_size,l,4),R(s_ptr)
+ lea MEM_INDX1(res_ptr,s_size,l,4),R(res_ptr)
+#else /* not mc68000 */
+ movel R(s_size),R(d0)
+ asll #2,R(d0)
+ addl R(s_size),R(s_ptr)
+ addl R(s_size),R(res_ptr)
+#endif
+
+ clrl R(d0) /* initialize carry */
+ eorw #1,R(s_size)
+ lsrl #1,R(s_size)
+ bcc L(LR1)
+ subql #1,R(s_size)
+
+L(LRoop:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+L(LR1:)
+ movel MEM_PREDEC(s_ptr),R(d2)
+ roxrl #1,R(d2)
+ movel R(d2),MEM_PREDEC(res_ptr)
+
+ dbf R(s_size),L(LRoop)
+ roxrl #1,R(d0) /* save cy in msb */
+ subl #0x10000,R(s_size)
+ bcs L(LRend)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(LRoop)
+
+L(LRend:)
+/* Restore used registers from stack frame. */
+ moveml MEM_POSTINC(sp),R(d2)-R(d6)/R(a2)
+ rts
+EPILOG(_gcry_mpih_rshift)
+
+
+
+
--- /dev/null
+/* mc68020 __mpn_sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 16)
+ * mpi_size_t size) (sp + 12)
+ */
+
+
+ TEXT
+ ALIGN
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_sub_n)
+
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+PROLOG(_gcry_mpih_sub_n)
+/* Save used registers on the stack. */
+ movel R(d2),MEM_PREDEC(sp)
+ movel R(a2),MEM_PREDEC(sp)
+
+/* Copy the arguments to registers. Better use movem? */
+ movel MEM_DISP(sp,12),R(a2)
+ movel MEM_DISP(sp,16),R(a0)
+ movel MEM_DISP(sp,20),R(a1)
+ movel MEM_DISP(sp,24),R(d2)
+
+ eorw #1,R(d2)
+ lsrl #1,R(d2)
+ bcc L(L1)
+ subql #1,R(d2) /* clears cy as side effect */
+
+L(Loop:)
+ movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+L(L1:) movel MEM_POSTINC(a0),R(d0)
+ movel MEM_POSTINC(a1),R(d1)
+ subxl R(d1),R(d0)
+ movel R(d0),MEM_POSTINC(a2)
+
+ dbf R(d2),L(Loop) /* loop until 16 lsb of %4 == -1 */
+ subxl R(d0),R(d0) /* d0 <= -cy; save cy as 0 or -1 in d0 */
+ subl #0x10000,R(d2)
+ bcs L(L2)
+ addl R(d0),R(d0) /* restore cy */
+ bra L(Loop)
+
+L(L2:)
+ negl R(d0)
+
+/* Restore used registers from stack frame. */
+ movel MEM_POSTINC(sp),R(a2)
+ movel MEM_POSTINC(sp),R(d2)
+
+ rts
+EPILOG(_gcry_mpih_sub_n)
+
+
--- /dev/null
+/* asm.h -- Definitions for 68k syntax variations.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#undef ALIGN
+
+#ifdef MIT_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)base@
+#define MEM_DISP(base,displacement)base@(displacement)
+#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale)
+#define MEM_PREDEC(memory_base)memory_base@-
+#define MEM_POSTINC(memory_base)memory_base@+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#define moveql moveq
+/* Use variable sized opcodes. */
+#define bcc jcc
+#define bcs jcs
+#define bls jls
+#define beq jeq
+#define bne jne
+#define bra jra
+#endif
+
+#ifdef SONY_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT .text
+#define ALIGN .even
+#define GLOBL .globl
+#endif
+
+#ifdef MOTOROLA_SYNTAX
+#define PROLOG(name)
+#define EPILOG(name)
+#define R(r)r
+#define MEM(base)(base)
+#define MEM_DISP(base,displacement)(displacement,base)
+#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale)
+#define MEM_PREDEC(memory_base)-(memory_base)
+#define MEM_POSTINC(memory_base)(memory_base)+
+#define L(label) label
+#define TEXT
+#define ALIGN
+#define GLOBL XDEF
+#define lea LEA
+#define movel MOVE.L
+#define moveml MOVEM.L
+#define moveql MOVEQ.L
+#define cmpl CMP.L
+#define orl OR.L
+#define clrl CLR.L
+#define eorw EOR.W
+#define lsrl LSR.L
+#define lsll LSL.L
+#define roxrl ROXR.L
+#define roxll ROXL.L
+#define addl ADD.L
+#define addxl ADDX.L
+#define addql ADDQ.L
+#define subl SUB.L
+#define subxl SUBX.L
+#define subql SUBQ.L
+#define negl NEG.L
+#define mulul MULU.L
+#define bcc BCC
+#define bcs BCS
+#define bls BLS
+#define beq BEQ
+#define bne BNE
+#define bra BRA
+#define dbf DBF
+#define rts RTS
+#define d0 D0
+#define d1 D1
+#define d2 D2
+#define d3 D3
+#define d4 D4
+#define d5 D5
+#define d6 D6
+#define d7 D7
+#define a0 A0
+#define a1 A1
+#define a2 A2
+#define a3 A3
+#define a4 A4
+#define a5 A5
+#define a6 A6
+#define a7 A7
+#define sp SP
+#endif
+
+#ifdef ELF_SYNTAX
+#define PROLOG(name) .type name,@function
+#define EPILOG(name) .size name,.-name
+#define MEM(base)(R(base))
+#define MEM_DISP(base,displacement)(displacement,R(base))
+#define MEM_PREDEC(memory_base)-(R(memory_base))
+#define MEM_POSTINC(memory_base)(R(memory_base))+
+#ifdef __STDC__
+#define R_(r)%##r
+#define R(r)R_(r)
+#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix))
+#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix)
+#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale))
+#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale)
+#define L(label) .##label
+#else
+#define R(r)%/**/r
+#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix)
+#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale)
+#define L(label) ./**/label
+#endif
+#define TEXT .text
+#define ALIGN .align 2
+#define GLOBL .globl
+#define bcc jbcc
+#define bcs jbcs
+#define bls jbls
+#define beq jbeq
+#define bne jbne
+#define bra jbra
+#endif
+
+#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX)
+#define movel move.l
+#define moveml movem.l
+#define moveql moveq.l
+#define cmpl cmp.l
+#define orl or.l
+#define clrl clr.l
+#define eorw eor.w
+#define lsrl lsr.l
+#define lsll lsl.l
+#define roxrl roxr.l
+#define roxll roxl.l
+#define addl add.l
+#define addxl addx.l
+#define addql addq.l
+#define subl sub.l
+#define subxl subx.l
+#define subql subq.l
+#define negl neg.l
+#define mulul mulu.l
+#endif
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpi-asm-defs.h
+$names$ iQCVAwUAP+LmUTEAnp832S/7AQLm/gP/RHR2aLMwHPxsq0mGO5H0kneVn8a9l9yDNEZBefkYcOJMb7MZGKxbGspyENiU04Mc2TFnA1wS9gjNHlRWtUYxxn/wyuV6BIRgfstXt2nXGgEQrK07GIz8ETFcYqcxu7JKiICIuXZgnIgdwBJswbBV1zaMUDXeg5B8vkkEeRWj8hQ==IQVO
--- /dev/null
+This directory contains mpn functions optimized for MIPS3. Example of
+processors that implement MIPS3 are R4000, R4400, R4600, R4700, and R8000.
+
+RELEVANT OPTIMIZATION ISSUES
+
+1. On the R4000 and R4400, branches, both the plain and the "likely" ones,
+ take 3 cycles to execute. (The fastest possible loop will take 4 cycles,
+ because of the delay insn.)
+
+ On the R4600, branches takes a single cycle
+
+ On the R8000, branches often take no noticable cycles, as they are
+ executed in a separate function unit..
+
+2. The R4000 and R4400 have a load latency of 4 cycles.
+
+3. On the R4000 and R4400, multiplies take a data-dependent number of
+ cycles, contrary to the SGI documentation. There seem to be 3 or 4
+ possible latencies.
+
+STATUS
+
+Good...
--- /dev/null
+Manifest
+README
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+mpi-asm-defs.h
+
--- /dev/null
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB 8
+
+
+
+
+
+
--- /dev/null
+/* mips3 add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, ($4)
+ * mpi_ptr_t s1_ptr, ($5)
+ * mpi_ptr_t s2_ptr, ($6)
+ * mpi_size_t size) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_add_n
+ .ent _gcry_mpih_add_n
+_gcry_mpih_add_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ daddu $13,$12,$13
+ sltu $2,$13,$12
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ daddu $11,$10,$11
+ sltu $2,$11,$10
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_add_n
+
--- /dev/null
+/* mips3 lshift
+ *
+ * Copyright (C) 1995, 1998, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_lshift
+ .ent _gcry_mpih_lshift
+_gcry_mpih_lshift:
+ .set noreorder
+ .set nomacro
+
+ dsll $2,$6,3
+ daddu $5,$5,$2 # make r5 point at end of src
+ ld $10,-8($5) # load first limb
+ dsubu $13,$0,$7
+ daddu $4,$4,$2 # make r4 point at end of res
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsrl $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,-16($5)
+ daddiu $4,$4,-8
+ daddiu $5,$5,-8
+ daddiu $9,$9,-1
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,0($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,-16($5)
+ daddiu $4,$4,-32
+ daddiu $6,$6,-4
+ dsll $11,$10,$7
+ dsrl $12,$3,$13
+
+ ld $10,-24($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,24($4)
+ dsrl $9,$10,$13
+
+ ld $3,-32($5)
+ dsll $11,$10,$7
+ or $8,$14,$9
+ sd $8,16($4)
+ dsrl $12,$3,$13
+
+ ld $10,-40($5)
+ dsll $14,$3,$7
+ or $8,$11,$12
+ sd $8,8($4)
+ dsrl $9,$10,$13
+
+ daddiu $5,$5,-32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,0($4)
+
+.Lend: dsll $8,$10,$7
+ j $31
+ sd $8,-8($4)
+ .end _gcry_mpih_lshift
--- /dev/null
+/* mips3 mpih-mul1.S -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_mul_1
+ .ent _gcry_mpih_mul_1
+_gcry_mpih_mul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: mflo $10
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $10,$10,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$10,$2 # carry from previous addition -> $2
+ sd $10,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ dmultu $8,$7
+ sd $10,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: mflo $10
+ mfhi $9
+ daddu $10,$10,$2
+ sltu $2,$10,$2
+ sd $10,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_mul_1
+
--- /dev/null
+/* MIPS3 addmul_1 -- Multiply a limb vector with a single limb and
+ * add the product to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_addmul_1
+ .ent _gcry_mpih_addmul_1
+_gcry_mpih_addmul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ daddu $3,$10,$3
+ sltu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_addmul_1
+
--- /dev/null
+/* MIPS3 submul_1 -- Multiply a limb vector with a single limb and
+ * subtract the product from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_size_t s1_size, (r6)
+ * mpi_limb_t s2_limb) (r7)
+ */
+
+ .text
+ .align 4
+ .globl _gcry_mpih_submul_1
+ .ent _gcry_mpih_submul_1
+_gcry_mpih_submul_1:
+ .set noreorder
+ .set nomacro
+
+/* # warm up phase 0 */
+ ld $8,0($5)
+
+/* # warm up phase 1 */
+ daddiu $5,$5,8
+ dmultu $8,$7
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC0
+ move $2,$0 # zero cy2
+
+ daddiu $6,$6,-1
+ beq $6,$0,$LC1
+ ld $8,0($5) # load new s1 limb as early as possible
+
+Loop: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddiu $5,$5,8
+ daddu $3,$3,$2 # add old carry limb to low product limb
+ dmultu $8,$7
+ ld $8,0($5) # load new s1 limb as early as possible
+ daddiu $6,$6,-1 # decrement loop counter
+ sltu $2,$3,$2 # carry from previous addition -> $2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ bne $6,$0,Loop
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 1 */
+$LC1: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dmultu $8,$7
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ daddiu $4,$4,8
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+/* # cool down phase 0 */
+$LC0: ld $10,0($4)
+ mflo $3
+ mfhi $9
+ daddu $3,$3,$2
+ sltu $2,$3,$2
+ dsubu $3,$10,$3
+ sgtu $10,$3,$10
+ daddu $2,$2,$10
+ sd $3,0($4)
+ j $31
+ daddu $2,$9,$2 # add high product limb and carry from addition
+
+ .end _gcry_mpih_submul_1
+
--- /dev/null
+/* mips3 rshift
+ *
+ * Copyright (C) 1995, 1998, 2000
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, ($4)
+ * mpi_ptr_t up, ($5)
+ * mpi_size_t usize, ($6)
+ * unsigned cnt) ($7)
+ */
+
+ .text
+ .align 2
+ .globl _gcry_mpih_rshift
+ .ent _gcry_mpih_rshift
+_gcry_mpih_rshift:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5) # load first limb
+ dsubu $13,$0,$7
+ daddiu $6,$6,-1
+ and $9,$6,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ dsll $2,$10,$13 # compute function result
+
+ dsubu $6,$6,$9
+
+.Loop0: ld $3,8($5)
+ daddiu $4,$4,8
+ daddiu $5,$5,8
+ daddiu $9,$9,-1
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+ move $10,$3
+ or $8,$11,$12
+ bne $9,$0,.Loop0
+ sd $8,-8($4)
+
+.L0: beq $6,$0,.Lend
+ nop
+
+.Loop: ld $3,8($5)
+ daddiu $4,$4,32
+ daddiu $6,$6,-4
+ dsrl $11,$10,$7
+ dsll $12,$3,$13
+
+ ld $10,16($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-32($4)
+ dsll $9,$10,$13
+
+ ld $3,24($5)
+ dsrl $11,$10,$7
+ or $8,$14,$9
+ sd $8,-24($4)
+ dsll $12,$3,$13
+
+ ld $10,32($5)
+ dsrl $14,$3,$7
+ or $8,$11,$12
+ sd $8,-16($4)
+ dsll $9,$10,$13
+
+ daddiu $5,$5,32
+ or $8,$14,$9
+ bgtz $6,.Loop
+ sd $8,-8($4)
+
+.Lend: dsrl $8,$10,$7
+ j $31
+ sd $8,0($4)
+ .end _gcry_mpih_rshift
+
--- /dev/null
+/* mips3 sub_n -- Subtract two limb vectors of the same length > 0 and
+ * store difference in a third limb vector.
+ *
+ * Copyright (C) 1995, 1998, 1999, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r4)
+ * mpi_ptr_t s1_ptr, (r5)
+ * mpi_ptr_t s2_ptr, (r6)
+ * mpi_size_t size) (r7)
+ */
+
+
+ .text
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .ent _gcry_mpih_sub_n
+_gcry_mpih_sub_n:
+ .set noreorder
+ .set nomacro
+
+ ld $10,0($5)
+ ld $11,0($6)
+
+ daddiu $7,$7,-1
+ and $9,$7,4-1 # number of limbs in first loop
+ beq $9,$0,.L0 # if multiple of 4 limbs, skip first loop
+ move $2,$0
+
+ dsubu $7,$7,$9
+
+.Loop0: daddiu $9,$9,-1
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,8
+ daddiu $6,$6,8
+ move $10,$12
+ move $11,$13
+ bne $9,$0,.Loop0
+ daddiu $4,$4,8
+
+.L0: beq $7,$0,.Lend
+ nop
+
+.Loop: daddiu $7,$7,-4
+
+ ld $12,8($5)
+ daddu $11,$11,$2
+ ld $13,8($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ or $2,$2,$8
+
+ ld $10,16($5)
+ daddu $13,$13,$2
+ ld $11,16($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,8($4)
+ or $2,$2,$8
+
+ ld $12,24($5)
+ daddu $11,$11,$2
+ ld $13,24($6)
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,16($4)
+ or $2,$2,$8
+
+ ld $10,32($5)
+ daddu $13,$13,$2
+ ld $11,32($6)
+ sltu $8,$13,$2
+ dsubu $13,$12,$13
+ sltu $2,$12,$13
+ sd $13,24($4)
+ or $2,$2,$8
+
+ daddiu $5,$5,32
+ daddiu $6,$6,32
+
+ bne $7,$0,.Loop
+ daddiu $4,$4,32
+
+.Lend: daddu $11,$11,$2
+ sltu $8,$11,$2
+ dsubu $11,$10,$11
+ sltu $2,$10,$11
+ sd $11,0($4)
+ j $31
+ or $2,$2,$8
+
+ .end _gcry_mpih_sub_n
+
--- /dev/null
+/* mpi-add.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+
+
+/****************
+ * Add the unsigned integer V to the mpi-integer U and store the
+ * result in W. U and V may be the same.
+ */
+void
+gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ }
+ else if( !usign ) { /* mpi is not negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ wsign = 1;
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_ptr_t wp, up, vp;
+ mpi_size_t usize, vsize, wsize;
+ int usign, vsign, wsign;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = v->d;
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ wsize = usize + 1;
+ RESIZE_IF_NEEDED(w, wsize);
+ /* These must be after realloc (u or v may be the same as w). */
+ up = u->d;
+ vp = v->d;
+ }
+ wp = w->d;
+ wsign = 0;
+
+ if( !vsize ) { /* simple */
+ MPN_COPY(wp, up, usize );
+ wsize = usize;
+ wsign = usign;
+ }
+ else if( usign != vsign ) { /* different sign */
+ /* This test is right since USIZE >= VSIZE */
+ if( usize != vsize ) {
+ _gcry_mpih_sub(wp, up, usize, vp, vsize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ wsign = usign;
+ }
+ else if( _gcry_mpih_cmp(up, vp, usize) < 0 ) {
+ _gcry_mpih_sub_n(wp, vp, up, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( !usign )
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_n(wp, up, vp, usize);
+ wsize = usize;
+ MPN_NORMALIZE(wp, wsize);
+ if( usign )
+ wsign = 1;
+ }
+ }
+ else { /* U and V have same sign. Add them. */
+ mpi_limb_t cy = _gcry_mpih_add(wp, up, usize, vp, vsize);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ if( usign )
+ wsign = 1;
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+/****************
+ * Subtract the unsigned integer V from the mpi-integer U and store the
+ * result in W.
+ */
+void
+gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize, wsize;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+ wsign = 0;
+
+ /* If not space for W (and possible carry), increase space. */
+ wsize = usize + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize);
+
+ /* These must be after realloc (U may be the same as W). */
+ up = u->d;
+ wp = w->d;
+
+ if( !usize ) { /* simple */
+ wp[0] = v;
+ wsize = v? 1:0;
+ wsign = 1;
+ }
+ else if( usign ) { /* mpi and v are negative */
+ mpi_limb_t cy;
+ cy = _gcry_mpih_add_1(wp, up, usize, v);
+ wp[usize] = cy;
+ wsize = usize + cy;
+ }
+ else { /* The signs are different. Need exact comparison to determine
+ * which operand to subtract from which. */
+ if( usize == 1 && up[0] < v ) {
+ wp[0] = v - up[0];
+ wsize = 1;
+ wsign = 1;
+ }
+ else {
+ _gcry_mpih_sub_1(wp, up, usize, v);
+ /* Size can decrease with at most one limb. */
+ wsize = usize - (wp[usize-1]==0);
+ }
+ }
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+void
+gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ gcry_mpi_t vv = mpi_copy (v);
+ vv->sign = ! vv->sign;
+ gcry_mpi_add (w, u, vv);
+ mpi_free (vv);
+}
+
+
+void
+gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_add(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
+
+void
+gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_sub(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
--- /dev/null
+/* mpi-bit.c - MPI bit level functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+#ifdef MPI_INTERNAL_NEED_CLZ_TAB
+#ifdef __STDC__
+const
+#endif
+unsigned char
+_gcry_clz_tab[] =
+{
+ 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+ 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+ 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+};
+#endif
+
+
+#define A_LIMB_1 ((mpi_limb_t)1)
+
+
+/****************
+ * Sometimes we have MSL (most significant limbs) which are 0;
+ * this is for some reasons not good, so this function removes them.
+ */
+void
+_gcry_mpi_normalize( gcry_mpi_t a )
+{
+ if( mpi_is_opaque(a) )
+ return;
+
+ for( ; a->nlimbs && !a->d[a->nlimbs-1]; a->nlimbs-- )
+ ;
+}
+
+
+
+/****************
+ * Return the number of bits in A.
+ */
+unsigned int
+gcry_mpi_get_nbits( gcry_mpi_t a )
+{
+ unsigned n;
+
+ if( mpi_is_opaque(a) ) {
+ return a->sign; /* which holds the number of bits */
+ }
+
+ _gcry_mpi_normalize( a );
+ if( a->nlimbs ) {
+ mpi_limb_t alimb = a->d[a->nlimbs-1];
+ if( alimb )
+ count_leading_zeros( n, alimb );
+ else
+ n = BITS_PER_MPI_LIMB;
+ n = BITS_PER_MPI_LIMB - n + (a->nlimbs-1) * BITS_PER_MPI_LIMB;
+ }
+ else
+ n = 0;
+ return n;
+}
+
+
+/****************
+ * Test whether bit N is set.
+ */
+int
+gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+ mpi_limb_t limb;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return 0; /* too far left: this is a 0 */
+ limb = a->d[limbno];
+ return (limb & (A_LIMB_1 << bitno))? 1: 0;
+}
+
+
+/****************
+ * Set bit N of A.
+ */
+void
+gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+}
+
+/****************
+ * Set bit N of A. and clear all bits above
+ */
+void
+gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if ( limbno >= a->nlimbs )
+ {
+ mpi_resize (a, limbno+1 );
+ a->nlimbs = limbno+1;
+ }
+ a->d[limbno] |= (A_LIMB_1<<bitno);
+ for ( bitno++; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * clear bit N of A and all bits above
+ */
+void
+gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* not allocated, therefore no need to clear bits
+ :-) */
+
+ for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+ a->nlimbs = limbno+1;
+}
+
+/****************
+ * Clear bit N of A.
+ */
+void
+gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
+{
+ unsigned int limbno, bitno;
+
+ limbno = n / BITS_PER_MPI_LIMB;
+ bitno = n % BITS_PER_MPI_LIMB;
+
+ if( limbno >= a->nlimbs )
+ return; /* don't need to clear this bit, it's to far to left */
+ a->d[limbno] &= ~(A_LIMB_1 << bitno);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the right
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
+{
+ mpi_ptr_t ap = a->d;
+ mpi_size_t n = a->nlimbs;
+ unsigned int i;
+
+ if( count >= n ) {
+ a->nlimbs = 0;
+ return;
+ }
+
+ for( i = 0; i < n - count; i++ )
+ ap[i] = ap[i+count];
+ ap[i] = 0;
+ a->nlimbs -= count;
+}
+
+
+/*
+ * Shift A by N bits to the right.
+ */
+void
+gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ mpi_size_t xsize;
+ unsigned int i;
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if ( x == a )
+ {
+ /* In-place operation. */
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+
+ }
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else if ( nlimbs )
+ {
+ /* Copy and shift by more or equal bits than in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+ for (i=0; i < a->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ x->nlimbs = i;
+
+ if ( nlimbs >= x->nlimbs )
+ {
+ x->nlimbs = 0;
+ return;
+ }
+
+ if (nlimbs)
+ {
+ for (i=0; i < x->nlimbs - nlimbs; i++ )
+ x->d[i] = x->d[i+nlimbs];
+ x->d[i] = 0;
+ x->nlimbs -= nlimbs;
+ }
+
+ if ( x->nlimbs && nbits )
+ _gcry_mpih_rshift ( x->d, x->d, x->nlimbs, nbits );
+ }
+ else
+ {
+ /* Copy and shift by less than bits in a limb. */
+ xsize = a->nlimbs;
+ x->sign = a->sign;
+ RESIZE_IF_NEEDED (x, xsize);
+ x->nlimbs = xsize;
+
+ if ( xsize )
+ {
+ if (nbits )
+ _gcry_mpih_rshift (x->d, a->d, x->nlimbs, nbits );
+ else
+ {
+ /* The rshift helper function is not specified for
+ NBITS==0, thus we do a plain copy here. */
+ for (i=0; i < x->nlimbs; i++ )
+ x->d[i] = a->d[i];
+ }
+ }
+ }
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
+
+
+/****************
+ * Shift A by COUNT limbs to the left
+ * This is used only within the MPI library
+ */
+void
+_gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count)
+{
+ mpi_ptr_t ap;
+ int n = a->nlimbs;
+ int i;
+
+ if (!count || !n)
+ return;
+
+ RESIZE_IF_NEEDED (a, n+count);
+
+ ap = a->d;
+ for (i = n-1; i >= 0; i--)
+ ap[i+count] = ap[i];
+ for (i=0; i < count; i++ )
+ ap[i] = 0;
+ a->nlimbs += count;
+}
+
+
+/*
+ * Shift A by N bits to the left.
+ */
+void
+gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+{
+ unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
+ unsigned int nbits = (n%BITS_PER_MPI_LIMB);
+
+ if (x == a && !n)
+ return; /* In-place shift with an amount of zero. */
+
+ if ( x != a )
+ {
+ /* Copy A to X. */
+ unsigned int alimbs = a->nlimbs;
+ int asign = a->sign;
+ mpi_ptr_t xp, ap;
+
+ RESIZE_IF_NEEDED (x, alimbs+nlimbs+1);
+ xp = x->d;
+ ap = a->d;
+ MPN_COPY (xp, ap, alimbs);
+ x->nlimbs = alimbs;
+ x->flags = a->flags;
+ x->sign = asign;
+ }
+
+ if (nlimbs && !nbits)
+ {
+ /* Shift a full number of limbs. */
+ _gcry_mpi_lshift_limbs (x, nlimbs);
+ }
+ else if (n)
+ {
+ /* We use a very dump approach: Shift left by the number of
+ limbs plus one and than fix it up by an rshift. */
+ _gcry_mpi_lshift_limbs (x, nlimbs+1);
+ gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
+ }
+
+ MPN_NORMALIZE (x->d, x->nlimbs);
+}
--- /dev/null
+/* mpi-cmp.c - MPI functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+int
+gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
+{
+ mpi_limb_t limb = v;
+
+ _gcry_mpi_normalize (u);
+
+ /* Handle the case that U contains no limb. */
+ if (u->nlimbs == 0)
+ return -(limb != 0);
+
+ /* Handle the case that U is negative. */
+ if (u->sign)
+ return -1;
+
+ if (u->nlimbs == 1)
+ {
+ /* Handle the case that U contains exactly one limb. */
+
+ if (u->d[0] > limb)
+ return 1;
+ if (u->d[0] < limb)
+ return -1;
+ return 0;
+ }
+ else
+ /* Handle the case that U contains more than one limb. */
+ return 1;
+}
+
+
+int
+gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_size_t usize;
+ mpi_size_t vsize;
+ int cmp;
+
+ if (mpi_is_opaque (u) || mpi_is_opaque (v))
+ {
+ if (mpi_is_opaque (u) && !mpi_is_opaque (v))
+ return -1;
+ if (!mpi_is_opaque (u) && mpi_is_opaque (v))
+ return 1;
+ if (!u->sign && !v->sign)
+ return 0; /* Empty buffers are identical. */
+ if (u->sign < v->sign)
+ return -1;
+ if (u->sign > v->sign)
+ return 1;
+ return memcmp (u->d, v->d, (u->sign+7)/8);
+ }
+ else
+ {
+ _gcry_mpi_normalize (u);
+ _gcry_mpi_normalize (v);
+
+ usize = u->nlimbs;
+ vsize = v->nlimbs;
+
+ /* Compare sign bits. */
+
+ if (!u->sign && v->sign)
+ return 1;
+ if (u->sign && !v->sign)
+ return -1;
+
+ /* U and V are either both positive or both negative. */
+
+ if (usize != vsize && !u->sign && !v->sign)
+ return usize - vsize;
+ if (usize != vsize && u->sign && v->sign)
+ return vsize + usize;
+ if (!usize )
+ return 0;
+ if (!(cmp = _gcry_mpih_cmp (u->d, v->d, usize)))
+ return 0;
+ if ((cmp < 0?1:0) == (u->sign?1:0))
+ return 1;
+ }
+ return -1;
+}
--- /dev/null
+/* mpi-div.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+void
+_gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ /* We need the original value of the divisor after the remainder has been
+ * preliminary calculated. We have to copy it to temporary space if it's
+ * the same variable as REM. */
+ if( rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_r( rem, dividend, divisor );
+
+ if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
+ gcry_mpi_add( rem, rem, divisor);
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+
+/****************
+ * Division rounding the quotient towards -infinity.
+ * The remainder gets the same sign as the denominator.
+ * rem is optional
+ */
+
+ulong
+_gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor )
+{
+ mpi_limb_t rlimb;
+
+ rlimb = _gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+ if( rlimb && dividend->sign )
+ rlimb = divisor - rlimb;
+
+ if( rem ) {
+ rem->d[0] = rlimb;
+ rem->nlimbs = rlimb? 1:0;
+ }
+ return rlimb;
+}
+
+
+void
+_gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ gcry_mpi_t tmp = mpi_alloc( mpi_get_nlimbs(quot) );
+ _gcry_mpi_fdiv_qr( quot, tmp, dividend, divisor);
+ mpi_free(tmp);
+}
+
+void
+_gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
+{
+ int divisor_sign = divisor->sign;
+ gcry_mpi_t temp_divisor = NULL;
+
+ if( quot == divisor || rem == divisor ) {
+ temp_divisor = mpi_copy( divisor );
+ divisor = temp_divisor;
+ }
+
+ _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
+
+ if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
+ gcry_mpi_sub_ui( quot, quot, 1 );
+ gcry_mpi_add( rem, rem, divisor);
+ }
+
+ if( temp_divisor )
+ mpi_free(temp_divisor);
+}
+
+
+/* If den == quot, den needs temporary storage.
+ * If den == rem, den needs temporary storage.
+ * If num == quot, num needs temporary storage.
+ * If den has temporary storage, it can be normalized while being copied,
+ * i.e no extra storage should be allocated.
+ */
+
+void
+_gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ _gcry_mpi_tdiv_qr(NULL, rem, num, den );
+}
+
+void
+_gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den)
+{
+ mpi_ptr_t np, dp;
+ mpi_ptr_t qp, rp;
+ mpi_size_t nsize = num->nlimbs;
+ mpi_size_t dsize = den->nlimbs;
+ mpi_size_t qsize, rsize;
+ mpi_size_t sign_remainder = num->sign;
+ mpi_size_t sign_quotient = num->sign ^ den->sign;
+ unsigned normalization_steps;
+ mpi_limb_t q_limb;
+ mpi_ptr_t marker[5];
+ unsigned int marker_nlimbs[5];
+ int markidx=0;
+
+ /* Ensure space is enough for quotient and remainder.
+ * We need space for an extra limb in the remainder, because it's
+ * up-shifted (normalized) below. */
+ rsize = nsize + 1;
+ mpi_resize( rem, rsize);
+
+ qsize = rsize - dsize; /* qsize cannot be bigger than this. */
+ if( qsize <= 0 ) {
+ if( num != rem ) {
+ rem->nlimbs = num->nlimbs;
+ rem->sign = num->sign;
+ MPN_COPY(rem->d, num->d, nsize);
+ }
+ if( quot ) {
+ /* This needs to follow the assignment to rem, in case the
+ * numerator and quotient are the same. */
+ quot->nlimbs = 0;
+ quot->sign = 0;
+ }
+ return;
+ }
+
+ if( quot )
+ mpi_resize( quot, qsize);
+
+ /* Read pointers here, when reallocation is finished. */
+ np = num->d;
+ dp = den->d;
+ rp = rem->d;
+
+ /* Optimize division by a single-limb divisor. */
+ if( dsize == 1 ) {
+ mpi_limb_t rlimb;
+ if( quot ) {
+ qp = quot->d;
+ rlimb = _gcry_mpih_divmod_1( qp, np, nsize, dp[0] );
+ qsize -= qp[qsize - 1] == 0;
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+ else
+ rlimb = _gcry_mpih_mod_1( np, nsize, dp[0] );
+ rp[0] = rlimb;
+ rsize = rlimb != 0?1:0;
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ return;
+ }
+
+
+ if( quot ) {
+ qp = quot->d;
+ /* Make sure QP and NP point to different objects. Otherwise the
+ * numerator would be gradually overwritten by the quotient limbs. */
+ if(qp == np) { /* Copy NP object to temporary space. */
+ marker_nlimbs[markidx] = nsize;
+ np = marker[markidx++] = mpi_alloc_limb_space(nsize,
+ mpi_is_secure(quot));
+ MPN_COPY(np, qp, nsize);
+ }
+ }
+ else /* Put quotient at top of remainder. */
+ qp = rp + dsize;
+
+ count_leading_zeros( normalization_steps, dp[dsize - 1] );
+
+ /* Normalize the denominator, i.e. make its most significant bit set by
+ * shifting it NORMALIZATION_STEPS bits to the left. Also shift the
+ * numerator the same number of steps (to keep the quotient the same!).
+ */
+ if( normalization_steps ) {
+ mpi_ptr_t tp;
+ mpi_limb_t nlimb;
+
+ /* Shift up the denominator setting the most significant bit of
+ * the most significant word. Use temporary storage not to clobber
+ * the original contents of the denominator. */
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,mpi_is_secure(den));
+ _gcry_mpih_lshift( tp, dp, dsize, normalization_steps );
+ dp = tp;
+
+ /* Shift up the numerator, possibly introducing a new most
+ * significant word. Move the shifted numerator in the remainder
+ * meanwhile. */
+ nlimb = _gcry_mpih_lshift(rp, np, nsize, normalization_steps);
+ if( nlimb ) {
+ rp[nsize] = nlimb;
+ rsize = nsize + 1;
+ }
+ else
+ rsize = nsize;
+ }
+ else {
+ /* The denominator is already normalized, as required. Copy it to
+ * temporary space if it overlaps with the quotient or remainder. */
+ if( dp == rp || (quot && (dp == qp))) {
+ mpi_ptr_t tp;
+
+ marker_nlimbs[markidx] = dsize;
+ tp = marker[markidx++] = mpi_alloc_limb_space(dsize,
+ mpi_is_secure(den));
+ MPN_COPY( tp, dp, dsize );
+ dp = tp;
+ }
+
+ /* Move the numerator to the remainder. */
+ if( rp != np )
+ MPN_COPY(rp, np, nsize);
+
+ rsize = nsize;
+ }
+
+ q_limb = _gcry_mpih_divrem( qp, 0, rp, rsize, dp, dsize );
+
+ if( quot ) {
+ qsize = rsize - dsize;
+ if(q_limb) {
+ qp[qsize] = q_limb;
+ qsize += 1;
+ }
+
+ quot->nlimbs = qsize;
+ quot->sign = sign_quotient;
+ }
+
+ rsize = dsize;
+ MPN_NORMALIZE (rp, rsize);
+
+ if( normalization_steps && rsize ) {
+ _gcry_mpih_rshift(rp, rp, rsize, normalization_steps);
+ rsize -= rp[rsize - 1] == 0?1:0;
+ }
+
+ rem->nlimbs = rsize;
+ rem->sign = sign_remainder;
+ while( markidx )
+ {
+ markidx--;
+ _gcry_mpi_free_limb_space (marker[markidx], marker_nlimbs[markidx]);
+ }
+}
+
+void
+_gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned int count )
+{
+ mpi_size_t usize, wsize;
+ mpi_size_t limb_cnt;
+
+ usize = u->nlimbs;
+ limb_cnt = count / BITS_PER_MPI_LIMB;
+ wsize = usize - limb_cnt;
+ if( limb_cnt >= usize )
+ w->nlimbs = 0;
+ else {
+ mpi_ptr_t wp;
+ mpi_ptr_t up;
+
+ RESIZE_IF_NEEDED( w, wsize );
+ wp = w->d;
+ up = u->d;
+
+ count %= BITS_PER_MPI_LIMB;
+ if( count ) {
+ _gcry_mpih_rshift( wp, up + limb_cnt, wsize, count );
+ wsize -= !wp[wsize - 1];
+ }
+ else {
+ MPN_COPY_INCR( wp, up + limb_cnt, wsize);
+ }
+
+ w->nlimbs = wsize;
+ }
+}
+
+/****************
+ * Check whether dividend is divisible by divisor
+ * (note: divisor must fit into a limb)
+ */
+int
+_gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor )
+{
+ return !_gcry_mpih_mod_1( dividend->d, dividend->nlimbs, divisor );
+}
+
+
+void
+gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+{
+ if (!round)
+ {
+ if (!rem)
+ {
+ gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs(quot));
+ _gcry_mpi_tdiv_qr (quot, tmp, dividend, divisor);
+ mpi_free (tmp);
+ }
+ else
+ _gcry_mpi_tdiv_qr (quot, rem, dividend, divisor);
+ }
+ else if (round < 0)
+ {
+ if (!rem)
+ _gcry_mpi_fdiv_q (quot, dividend, divisor);
+ else if (!quot)
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+ else
+ _gcry_mpi_fdiv_qr (quot, rem, dividend, divisor);
+ }
+ else
+ log_bug ("mpi rounding to ceiling not yet implemented\n");
+}
--- /dev/null
+/* mpi-gcd.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+/****************
+ * Find the greatest common divisor G of A and B.
+ * Return: true if this 1, false in all other cases
+ */
+int
+gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
+{
+ gcry_mpi_t a, b;
+
+ a = mpi_copy(xa);
+ b = mpi_copy(xb);
+
+ /* TAOCP Vol II, 4.5.2, Algorithm A */
+ a->sign = 0;
+ b->sign = 0;
+ while( gcry_mpi_cmp_ui( b, 0 ) ) {
+ _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
+ mpi_set(a,b);
+ mpi_set(b,g);
+ }
+ mpi_set(g, a);
+
+ mpi_free(a);
+ mpi_free(b);
+ return !gcry_mpi_cmp_ui( g, 1);
+}
--- /dev/null
+/* mpi-inline.c
+ * Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* put the inline functions as real functions into the lib */
+#define G10_MPI_INLINE_DECL
+
+#include "mpi-internal.h"
+
+/* always include the header because it is only
+ * included by mpi-internal if __GCC__ is defined but we
+ * need it here in all cases and the above definition of
+ * of the macro allows us to do so
+ */
+#include "mpi-inline.h"
--- /dev/null
+/* mpi-inline.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 1999,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INLINE_H
+#define G10_MPI_INLINE_H
+
+#ifndef G10_MPI_INLINE_DECL
+#define G10_MPI_INLINE_DECL extern __inline__
+#endif
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb)
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb += x;
+ *res_ptr++ = s2_limb;
+ if( s2_limb < x ) { /* sum is less than the left operand: handle carry */
+ while( --s1_size ) {
+ x = *s1_ptr++ + 1; /* add carry */
+ *res_ptr++ = x; /* and store */
+ if( x ) /* not 0 (no overflow): we can stop */
+ goto leave;
+ }
+ return 1; /* return carry (size of s1 to small) */
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) { /* not the same variable */
+ mpi_size_t i; /* copy the rest */
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0; /* no carry */
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_add_n( res_ptr, s1_ptr, s2_ptr, s2_size );
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_add_1( res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb )
+{
+ mpi_limb_t x;
+
+ x = *s1_ptr++;
+ s2_limb = x - s2_limb;
+ *res_ptr++ = s2_limb;
+ if( s2_limb > x ) {
+ while( --s1_size ) {
+ x = *s1_ptr++;
+ *res_ptr++ = x - 1;
+ if( x )
+ goto leave;
+ }
+ return 1;
+ }
+
+ leave:
+ if( res_ptr != s1_ptr ) {
+ mpi_size_t i;
+ for( i=0; i < s1_size-1; i++ )
+ res_ptr[i] = s1_ptr[i];
+ }
+ return 0;
+}
+
+
+
+G10_MPI_INLINE_DECL mpi_limb_t
+_gcry_mpih_sub( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size)
+{
+ mpi_limb_t cy = 0;
+
+ if( s2_size )
+ cy = _gcry_mpih_sub_n(res_ptr, s1_ptr, s2_ptr, s2_size);
+
+ if( s1_size - s2_size )
+ cy = _gcry_mpih_sub_1(res_ptr + s2_size, s1_ptr + s2_size,
+ s1_size - s2_size, cy);
+ return cy;
+}
+
+/****************
+ * Compare OP1_PTR/OP1_SIZE with OP2_PTR/OP2_SIZE.
+ * There are no restrictions on the relative sizes of
+ * the two arguments.
+ * Return 1 if OP1 > OP2, 0 if they are equal, and -1 if OP1 < OP2.
+ */
+G10_MPI_INLINE_DECL int
+_gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t op1_word, op2_word;
+
+ for( i = size - 1; i >= 0 ; i--) {
+ op1_word = op1_ptr[i];
+ op2_word = op2_ptr[i];
+ if( op1_word != op2_word )
+ goto diff;
+ }
+ return 0;
+
+ diff:
+ /* This can *not* be simplified to
+ * op2_word - op2_word
+ * since that expression might give signed overflow. */
+ return (op1_word > op2_word) ? 1 : -1;
+}
+
+
+#endif /*G10_MPI_INLINE_H*/
--- /dev/null
+/* mpi-internal.h - Internal to the Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998, 2000, 2002,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_INTERNAL_H
+#define G10_MPI_INTERNAL_H
+
+#include "mpi-asm-defs.h"
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#include "mpi.h"
+
+/* If KARATSUBA_THRESHOLD is not already defined, define it to a
+ * value which is good on most machines. */
+
+/* tested 4, 16, 32 and 64, where 16 gave the best performance when
+ * checking a 768 and a 1024 bit ElGamal signature.
+ * (wk 22.12.97) */
+#ifndef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 16
+#endif
+
+/* The code can't handle KARATSUBA_THRESHOLD smaller than 2. */
+#if KARATSUBA_THRESHOLD < 2
+#undef KARATSUBA_THRESHOLD
+#define KARATSUBA_THRESHOLD 2
+#endif
+
+
+typedef mpi_limb_t *mpi_ptr_t; /* pointer to a limb */
+typedef int mpi_size_t; /* (must be a signed type) */
+
+#define ABS(x) (x >= 0 ? x : -x)
+#define MIN(l,o) ((l) < (o) ? (l) : (o))
+#define MAX(h,i) ((h) > (i) ? (h) : (i))
+#define RESIZE_IF_NEEDED(a,b) \
+ do { \
+ if( (a)->alloced < (b) ) \
+ mpi_resize((a), (b)); \
+ } while(0)
+
+/* Copy N limbs from S to D. */
+#define MPN_COPY( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+#define MPN_COPY_INCR( d, s, n) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = (d)[_i]; \
+ } while (0)
+
+#define MPN_COPY_DECR( d, s, n ) \
+ do { \
+ mpi_size_t _i; \
+ for( _i = (n)-1; _i >= 0; _i--) \
+ (d)[_i] = (s)[_i]; \
+ } while(0)
+
+/* Zero N limbs at D */
+#define MPN_ZERO(d, n) \
+ do { \
+ int _i; \
+ for( _i = 0; _i < (n); _i++ ) \
+ (d)[_i] = 0; \
+ } while (0)
+
+#define MPN_NORMALIZE(d, n) \
+ do { \
+ while( (n) > 0 ) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_NORMALIZE_NOT_ZERO(d, n) \
+ do { \
+ for(;;) { \
+ if( (d)[(n)-1] ) \
+ break; \
+ (n)--; \
+ } \
+ } while(0)
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+
+/* Divide the two-limb number in (NH,,NL) by D, with DI being the largest
+ * limb not larger than (2**(2*BITS_PER_MP_LIMB))/D - (2**BITS_PER_MP_LIMB).
+ * If this would yield overflow, DI should be the largest possible number
+ * (i.e., only ones). For correct operation, the most significant bit of D
+ * has to be set. Put the quotient in Q and the remainder in R.
+ */
+#define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
+ do { \
+ mpi_limb_t _q, _ql, _r; \
+ mpi_limb_t _xh, _xl; \
+ umul_ppmm (_q, _ql, (nh), (di)); \
+ _q += (nh); /* DI is 2**BITS_PER_MPI_LIMB too small */ \
+ umul_ppmm (_xh, _xl, _q, (d)); \
+ sub_ddmmss (_xh, _r, (nh), (nl), _xh, _xl); \
+ if( _xh ) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ if( _xh) { \
+ sub_ddmmss (_xh, _r, _xh, _r, 0, (d)); \
+ _q++; \
+ } \
+ } \
+ if( _r >= (d) ) { \
+ _r -= (d); \
+ _q++; \
+ } \
+ (r) = _r; \
+ (q) = _q; \
+ } while (0)
+
+
+/*-- mpiutil.c --*/
+#define mpi_alloc_limb_space(n,f) _gcry_mpi_alloc_limb_space((n),(f))
+mpi_ptr_t _gcry_mpi_alloc_limb_space( unsigned nlimbs, int sec );
+void _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs );
+void _gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned nlimbs );
+
+/*-- mpi-bit.c --*/
+#define mpi_rshift_limbs(a,n) _gcry_mpi_rshift_limbs ((a), (n))
+#define mpi_lshift_limbs(a,n) _gcry_mpi_lshift_limbs ((a), (n))
+
+void _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count );
+void _gcry_mpi_lshift_limbs( gcry_mpi_t a, unsigned int count );
+
+
+/*-- mpih-add.c --*/
+mpi_limb_t _gcry_mpih_add_1(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_add_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_add(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-sub.c --*/
+mpi_limb_t _gcry_mpih_sub_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb );
+mpi_limb_t _gcry_mpih_sub_n( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_ptr_t s2_ptr, mpi_size_t size);
+mpi_limb_t _gcry_mpih_sub(mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, mpi_size_t s1_size,
+ mpi_ptr_t s2_ptr, mpi_size_t s2_size);
+
+/*-- mpih-cmp.c --*/
+int _gcry_mpih_cmp( mpi_ptr_t op1_ptr, mpi_ptr_t op2_ptr, mpi_size_t size );
+
+/*-- mpih-mul.c --*/
+
+struct karatsuba_ctx {
+ struct karatsuba_ctx *next;
+ mpi_ptr_t tspace;
+ unsigned int tspace_nlimbs;
+ mpi_size_t tspace_size;
+ mpi_ptr_t tp;
+ unsigned int tp_nlimbs;
+ mpi_size_t tp_size;
+};
+
+void _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx );
+
+mpi_limb_t _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+mpi_limb_t _gcry_mpih_submul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+void _gcry_mpih_mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size);
+mpi_limb_t _gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize);
+void _gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size );
+void _gcry_mpih_sqr_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size,
+ mpi_ptr_t tspace);
+
+void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx );
+
+
+/*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/
+mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr,
+ mpi_size_t s1_size, mpi_limb_t s2_limb);
+
+/*-- mpih-div.c --*/
+mpi_limb_t _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+mpi_limb_t _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize);
+mpi_limb_t _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb);
+
+/*-- mpih-shift.c --*/
+mpi_limb_t _gcry_mpih_lshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+mpi_limb_t _gcry_mpih_rshift( mpi_ptr_t wp, mpi_ptr_t up, mpi_size_t usize,
+ unsigned cnt);
+
+
+/* Define stuff for longlong.h. */
+#define W_TYPE_SIZE BITS_PER_MPI_LIMB
+ typedef mpi_limb_t UWtype;
+ typedef unsigned int UHWtype;
+#if defined (__GNUC__)
+ typedef unsigned int UQItype __attribute__ ((mode (QI)));
+ typedef int SItype __attribute__ ((mode (SI)));
+ typedef unsigned int USItype __attribute__ ((mode (SI)));
+ typedef int DItype __attribute__ ((mode (DI)));
+ typedef unsigned int UDItype __attribute__ ((mode (DI)));
+#else
+ typedef unsigned char UQItype;
+ typedef long SItype;
+ typedef unsigned long USItype;
+#endif
+
+#ifdef __GNUC__
+#include "mpi-inline.h"
+#endif
+
+#endif /*G10_MPI_INTERNAL_H*/
--- /dev/null
+/* mpi-inv.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+/****************
+ * Calculate the multiplicative inverse X of A mod N
+ * That is: Find the solution x for
+ * 1 = (a*x) mod n
+ */
+int
+gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
+{
+#if 0
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
+ gcry_mpi_t ta, tb, tc;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_alloc_set_ui(0);
+ v2 = mpi_alloc_set_ui(1);
+ v3 = mpi_copy(v);
+ q = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t1 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t2 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ t3 = mpi_alloc( mpi_get_nlimbs(u)+1 );
+ while( mpi_cmp_ui( v3, 0 ) ) {
+ mpi_fdiv_q( q, u3, v3 );
+ mpi_mul(t1, v1, q); mpi_mul(t2, v2, q); mpi_mul(t3, v3, q);
+ mpi_sub(t1, u1, t1); mpi_sub(t2, u2, t2); mpi_sub(t3, u3, t3);
+ mpi_set(u1, v1); mpi_set(u2, v2); mpi_set(u3, v3);
+ mpi_set(v1, t1); mpi_set(v2, t2); mpi_set(v3, t3);
+ }
+ /* log_debug("result:\n");
+ log_mpidump("q =", q );
+ log_mpidump("u1=", u1);
+ log_mpidump("u2=", u2);
+ log_mpidump("u3=", u3);
+ log_mpidump("v1=", v1);
+ log_mpidump("v2=", v2); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(q);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+ mpi_free(u);
+ mpi_free(v);
+#elif 0
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35 */
+
+ /* FIXME: we can simplify this in most cases (see Knuth) */
+ gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, t1, t2, t3;
+ unsigned k;
+ int sign;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+
+
+ u1 = mpi_alloc_set_ui(1);
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v); /* !-- used as const 1 */
+ v2 = mpi_alloc( mpi_get_nlimbs(u) ); mpi_sub( v2, u1, u );
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, k ); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(u2);
+ mpi_free(u3);
+ mpi_free(v1);
+ mpi_free(v2);
+ mpi_free(v3);
+ mpi_free(t1);
+ mpi_free(t2);
+ mpi_free(t3);
+#else
+ /* Extended Euclid's algorithm (See TAOCP Vol II, 4.5.2, Alg X)
+ * modified according to Michael Penk's solution for Exercise 35
+ * with further enhancement */
+ gcry_mpi_t u, v, u1, u2=NULL, u3, v1, v2=NULL, v3, t1, t2=NULL, t3;
+ unsigned k;
+ int sign;
+ int odd ;
+
+ u = mpi_copy(a);
+ v = mpi_copy(n);
+
+ for(k=0; !mpi_test_bit(u,0) && !mpi_test_bit(v,0); k++ ) {
+ mpi_rshift(u, u, 1);
+ mpi_rshift(v, v, 1);
+ }
+ odd = mpi_test_bit(v,0);
+
+ u1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ u2 = mpi_alloc_set_ui(0);
+ u3 = mpi_copy(u);
+ v1 = mpi_copy(v);
+ if( !odd ) {
+ v2 = mpi_alloc( mpi_get_nlimbs(u) );
+ mpi_sub( v2, u1, u ); /* U is used as const 1 */
+ }
+ v3 = mpi_copy(v);
+ if( mpi_test_bit(u, 0) ) { /* u is odd */
+ t1 = mpi_alloc_set_ui(0);
+ if( !odd ) {
+ t2 = mpi_alloc_set_ui(1); t2->sign = 1;
+ }
+ t3 = mpi_copy(v); t3->sign = !t3->sign;
+ goto Y4;
+ }
+ else {
+ t1 = mpi_alloc_set_ui(1);
+ if( !odd )
+ t2 = mpi_alloc_set_ui(0);
+ t3 = mpi_copy(u);
+ }
+ do {
+ do {
+ if( !odd ) {
+ if( mpi_test_bit(t1, 0) || mpi_test_bit(t2, 0) ) { /* one is odd */
+ mpi_add(t1, t1, v);
+ mpi_sub(t2, t2, u);
+ }
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t2, t2, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ else {
+ if( mpi_test_bit(t1, 0) )
+ mpi_add(t1, t1, v);
+ mpi_rshift(t1, t1, 1);
+ mpi_rshift(t3, t3, 1);
+ }
+ Y4:
+ ;
+ } while( !mpi_test_bit( t3, 0 ) ); /* while t3 is even */
+
+ if( !t3->sign ) {
+ mpi_set(u1, t1);
+ if( !odd )
+ mpi_set(u2, t2);
+ mpi_set(u3, t3);
+ }
+ else {
+ mpi_sub(v1, v, t1);
+ sign = u->sign; u->sign = !u->sign;
+ if( !odd )
+ mpi_sub(v2, u, t2);
+ u->sign = sign;
+ sign = t3->sign; t3->sign = !t3->sign;
+ mpi_set(v3, t3);
+ t3->sign = sign;
+ }
+ mpi_sub(t1, u1, v1);
+ if( !odd )
+ mpi_sub(t2, u2, v2);
+ mpi_sub(t3, u3, v3);
+ if( t1->sign ) {
+ mpi_add(t1, t1, v);
+ if( !odd )
+ mpi_sub(t2, t2, u);
+ }
+ } while( mpi_cmp_ui( t3, 0 ) ); /* while t3 != 0 */
+ /* mpi_lshift( u3, k ); */
+ mpi_set(x, u1);
+
+ mpi_free(u1);
+ mpi_free(v1);
+ mpi_free(t1);
+ if( !odd ) {
+ mpi_free(u2);
+ mpi_free(v2);
+ mpi_free(t2);
+ }
+ mpi_free(u3);
+ mpi_free(v3);
+ mpi_free(t3);
+
+ mpi_free(u);
+ mpi_free(v);
+#endif
+ return 1;
+}
--- /dev/null
+/* mpi-mod.c - Modular reduction
+ Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s
+{
+ gcry_mpi_t m; /* The modulus - may not be modified. */
+ int m_copied; /* If true, M needs to be released. */
+ int k;
+ gcry_mpi_t y;
+ gcry_mpi_t r1; /* Helper MPI. */
+ gcry_mpi_t r2; /* Helper MPI. */
+ gcry_mpi_t r3; /* Helper MPI allocated on demand. */
+};
+
+
+
+void
+_gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_fdiv_r (rem, dividend, divisor);
+ rem->sign = 0;
+}
+
+
+/* This function returns a new context for Barrett based operations on
+ the modulus M. This context needs to be released using
+ _gcry_mpi_barrett_free. If COPY is true M will be transferred to
+ the context and the user may change M. If COPY is false, M may not
+ be changed until gcry_mpi_barrett_free has been called. */
+mpi_barrett_t
+_gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
+{
+ mpi_barrett_t ctx;
+ gcry_mpi_t tmp;
+
+ mpi_normalize (m);
+ ctx = gcry_xcalloc (1, sizeof *ctx);
+
+ if (copy)
+ {
+ ctx->m = mpi_copy (m);
+ ctx->m_copied = 1;
+ }
+ else
+ ctx->m = m;
+
+ ctx->k = mpi_get_nlimbs (m);
+ tmp = mpi_alloc (ctx->k + 1);
+
+ /* Barrett precalculation: y = floor(b^(2k) / m). */
+ mpi_set_ui (tmp, 1);
+ mpi_lshift_limbs (tmp, 2 * ctx->k);
+ mpi_fdiv_q (tmp, tmp, m);
+
+ ctx->y = tmp;
+ ctx->r1 = mpi_alloc ( 2 * ctx->k + 1 );
+ ctx->r2 = mpi_alloc ( 2 * ctx->k + 1 );
+
+ return ctx;
+}
+
+void
+_gcry_mpi_barrett_free (mpi_barrett_t ctx)
+{
+ if (ctx)
+ {
+ mpi_free (ctx->y);
+ mpi_free (ctx->r1);
+ mpi_free (ctx->r2);
+ if (ctx->r3)
+ mpi_free (ctx->r3);
+ if (ctx->m_copied)
+ mpi_free (ctx->m);
+ gcry_free (ctx);
+ }
+}
+
+
+/* R = X mod M
+
+ Using Barrett reduction. Before using this function
+ _gcry_mpi_barrett_init must have been called to do the
+ precalculations. CTX is the context created by this precalculation
+ and also conveys M. If the Barret reduction could no be done a
+ starightforward reduction method is used.
+
+ We assume that these conditions are met:
+ Input: x =(x_2k-1 ...x_0)_b
+ m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ Output: r = x mod m
+ */
+void
+_gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
+{
+ gcry_mpi_t m = ctx->m;
+ int k = ctx->k;
+ gcry_mpi_t y = ctx->y;
+ gcry_mpi_t r1 = ctx->r1;
+ gcry_mpi_t r2 = ctx->r2;
+
+ mpi_normalize (x);
+ if (mpi_get_nlimbs (x) > 2*k )
+ {
+ mpi_mod (r, x, m);
+ return;
+ }
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set ( r2, x );
+ mpi_rshift_limbs ( r2, k-1 );
+ mpi_mul ( r2, r2, y );
+ mpi_rshift_limbs ( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set ( r1, x );
+ if ( r1->nlimbs > k+1 ) /* Quick modulo operation. */
+ r1->nlimbs = k+1;
+ mpi_mul ( r2, r2, m );
+ if ( r2->nlimbs > k+1 ) /* Quick modulo operation. */
+ r2->nlimbs = k+1;
+ mpi_sub ( r, r1, r2 );
+
+ if ( mpi_is_neg( r ) )
+ {
+ if (!ctx->r3)
+ {
+ ctx->r3 = mpi_alloc ( k + 2 );
+ mpi_set_ui (ctx->r3, 1);
+ mpi_lshift_limbs (ctx->r3, k + 1 );
+ }
+ mpi_add ( r, r, ctx->r3 );
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while ( mpi_cmp( r, m ) >= 0 )
+ mpi_sub ( r, r, m );
+
+}
+
+
+void
+_gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx)
+{
+ gcry_mpi_mul (w, u, v);
+ mpi_mod_barrett (w, w, ctx);
+}
--- /dev/null
+/* mpi-mpow.c - MPI functions
+ * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+
+/* Barrett is slower than the classical way. It can be tweaked by
+ * using partial multiplications
+ */
+/*#define USE_BARRETT*/
+
+
+
+#ifdef USE_BARRETT
+static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
+static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 );
+#else
+#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) )
+#endif
+
+
+static int
+build_index( gcry_mpi_t *exparray, int k, int i, int t )
+{
+ int j, bitno;
+ int idx = 0;
+
+ bitno = t-i;
+ for(j=k-1; j >= 0; j-- ) {
+ idx <<= 1;
+ if( mpi_test_bit( exparray[j], bitno ) )
+ idx |= 1;
+ }
+ /*log_debug("t=%d i=%d idx=%d\n", t, i, idx );*/
+ return idx;
+}
+
+/****************
+ * RES = (BASE[0] ^ EXP[0]) * (BASE[1] ^ EXP[1]) * ... * mod M
+ */
+void
+_gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t m)
+{
+ int k; /* number of elements */
+ int t; /* bit size of largest exponent */
+ int i, j, idx;
+ gcry_mpi_t *G; /* table with precomputed values of size 2^k */
+ gcry_mpi_t tmp;
+#ifdef USE_BARRETT
+ gcry_mpi_t barrett_y, barrett_r1, barrett_r2;
+ int barrett_k;
+#endif
+
+ for(k=0; basearray[k]; k++ )
+ ;
+ gcry_assert(k);
+ for(t=0, i=0; (tmp=exparray[i]); i++ ) {
+ /*log_mpidump("exp: ", tmp );*/
+ j = mpi_get_nbits(tmp);
+ if( j > t )
+ t = j;
+ }
+ /*log_mpidump("mod: ", m );*/
+ gcry_assert (i==k);
+ gcry_assert (t);
+ gcry_assert (k < 10);
+
+ G = gcry_xcalloc( (1<<k) , sizeof *G );
+#ifdef USE_BARRETT
+ barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
+#endif
+ /* and calculate */
+ tmp = mpi_alloc( mpi_get_nlimbs(m)+1 );
+ mpi_set_ui( res, 1 );
+ for(i = 1; i <= t; i++ ) {
+ barrett_mulm(tmp, res, res, m, barrett_y, barrett_k,
+ barrett_r1, barrett_r2 );
+ idx = build_index( exparray, k, i, t );
+ gcry_assert (idx >= 0 && idx < (1<<k));
+ if( !G[idx] ) {
+ if( !idx )
+ G[0] = mpi_alloc_set_ui( 1 );
+ else {
+ for(j=0; j < k; j++ ) {
+ if( (idx & (1<<j) ) ) {
+ if( !G[idx] )
+ G[idx] = mpi_copy( basearray[j] );
+ else
+ barrett_mulm( G[idx], G[idx], basearray[j],
+ m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+ }
+ if( !G[idx] )
+ G[idx] = mpi_alloc(0);
+ }
+ }
+ barrett_mulm(res, tmp, G[idx], m, barrett_y, barrett_k, barrett_r1, barrett_r2 );
+ }
+
+ /* cleanup */
+ mpi_free(tmp);
+#ifdef USE_BARRETT
+ mpi_free(barrett_y);
+ mpi_free(barrett_r1);
+ mpi_free(barrett_r2);
+#endif
+ for(i=0; i < (1<<k); i++ )
+ mpi_free(G[i]);
+ gcry_free(G);
+}
+
+
+
+#ifdef USE_BARRETT
+static void
+barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ mpi_mul(w, u, v);
+ if( calc_barrett( w, w, m, y, k, r1, r2 ) )
+ mpi_fdiv_r( w, w, m );
+}
+
+/****************
+ * Barrett precalculation: y = floor(b^(2k) / m)
+ */
+static gcry_mpi_t
+init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 )
+{
+ gcry_mpi_t tmp;
+
+ mpi_normalize( m );
+ *k = mpi_get_nlimbs( m );
+ tmp = mpi_alloc( *k + 1 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, 2 * *k );
+ mpi_fdiv_q( tmp, tmp, m );
+ *r1 = mpi_alloc( 2* *k + 1 );
+ *r2 = mpi_alloc( 2* *k + 1 );
+ return tmp;
+}
+
+/****************
+ * Barrett reduction: We assume that these conditions are met:
+ * Given x =(x_2k-1 ...x_0)_b
+ * m =(m_k-1 ....m_0)_b with m_k-1 != 0
+ * Output r = x mod m
+ * Before using this function init_barret must be used to calucalte y and k.
+ * Returns: false = no error
+ * true = can't perform barret reduction
+ */
+static int
+calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2 )
+{
+ int xx = k > 3 ? k-3:0;
+
+ mpi_normalize( x );
+ if( mpi_get_nlimbs(x) > 2*k )
+ return 1; /* can't do it */
+
+ /* 1. q1 = floor( x / b^k-1)
+ * q2 = q1 * y
+ * q3 = floor( q2 / b^k+1 )
+ * Actually, we don't need qx, we can work direct on r2
+ */
+ mpi_set( r2, x );
+ mpi_rshift_limbs( r2, k-1 );
+ mpi_mul( r2, r2, y );
+ mpi_rshift_limbs( r2, k+1 );
+
+ /* 2. r1 = x mod b^k+1
+ * r2 = q3 * m mod b^k+1
+ * r = r1 - r2
+ * 3. if r < 0 then r = r + b^k+1
+ */
+ mpi_set( r1, x );
+ if( r1->nlimbs > k+1 ) /* quick modulo operation */
+ r1->nlimbs = k+1;
+ mpi_mul( r2, r2, m );
+ if( r2->nlimbs > k+1 ) /* quick modulo operation */
+ r2->nlimbs = k+1;
+ mpi_sub( r, r1, r2 );
+
+ if( mpi_is_neg( r ) ) {
+ gcry_mpi_t tmp;
+
+ tmp = mpi_alloc( k + 2 );
+ mpi_set_ui( tmp, 1 );
+ mpi_lshift_limbs( tmp, k+1 );
+ mpi_add( r, r, tmp );
+ mpi_free(tmp);
+ }
+
+ /* 4. while r >= m do r = r - m */
+ while( mpi_cmp( r, m ) >= 0 )
+ mpi_sub( r, r, m );
+
+ return 0;
+}
+#endif /* USE_BARRETT */
--- /dev/null
+/* mpi-mul.c - MPI functions
+ * Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+
+
+void
+gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
+{
+ mpi_size_t size, prod_size;
+ mpi_ptr_t prod_ptr;
+ mpi_limb_t cy;
+ int sign;
+
+ size = mult->nlimbs;
+ sign = mult->sign;
+
+ if( !size || !small_mult ) {
+ prod->nlimbs = 0;
+ prod->sign = 0;
+ return;
+ }
+
+ prod_size = size + 1;
+ if( prod->alloced < prod_size )
+ mpi_resize( prod, prod_size );
+ prod_ptr = prod->d;
+
+ cy = _gcry_mpih_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
+ if( cy )
+ prod_ptr[size++] = cy;
+ prod->nlimbs = size;
+ prod->sign = sign;
+}
+
+
+void
+gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ mpi_size_t usize, wsize, limb_cnt;
+ mpi_ptr_t wp;
+ mpi_limb_t wlimb;
+ int usign, wsign;
+
+ usize = u->nlimbs;
+ usign = u->sign;
+
+ if( !usize ) {
+ w->nlimbs = 0;
+ w->sign = 0;
+ return;
+ }
+
+ limb_cnt = cnt / BITS_PER_MPI_LIMB;
+ wsize = usize + limb_cnt + 1;
+ if( w->alloced < wsize )
+ mpi_resize(w, wsize );
+ wp = w->d;
+ wsize = usize + limb_cnt;
+ wsign = usign;
+
+ cnt %= BITS_PER_MPI_LIMB;
+ if( cnt ) {
+ wlimb = _gcry_mpih_lshift( wp + limb_cnt, u->d, usize, cnt );
+ if( wlimb ) {
+ wp[wsize] = wlimb;
+ wsize++;
+ }
+ }
+ else {
+ MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
+ }
+
+ /* Zero all whole limbs at low end. Do it here and not before calling
+ * mpn_lshift, not to lose for U == W. */
+ MPN_ZERO( wp, limb_cnt );
+
+ w->nlimbs = wsize;
+ w->sign = wsign;
+}
+
+
+void
+gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ mpi_size_t usize, vsize, wsize;
+ mpi_ptr_t up, vp, wp;
+ mpi_limb_t cy;
+ int usign, vsign, usecure, vsecure, sign_product;
+ int assign_wp=0;
+ mpi_ptr_t tmp_limb=NULL;
+ unsigned int tmp_limb_nlimbs = 0;
+
+ if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
+ usize = v->nlimbs;
+ usign = v->sign;
+ usecure = mpi_is_secure(v);
+ up = v->d;
+ vsize = u->nlimbs;
+ vsign = u->sign;
+ vsecure = mpi_is_secure(u);
+ vp = u->d;
+ }
+ else {
+ usize = u->nlimbs;
+ usign = u->sign;
+ usecure = mpi_is_secure(u);
+ up = u->d;
+ vsize = v->nlimbs;
+ vsign = v->sign;
+ vsecure = mpi_is_secure(v);
+ vp = v->d;
+ }
+ sign_product = usign ^ vsign;
+ wp = w->d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
+ /* w is not allocated in secure space but u or v is. To make sure
+ * that no temporray results are stored in w, we temporary use
+ * a newly allocated limb space for w */
+ wp = mpi_alloc_limb_space( wsize, 1 );
+ assign_wp = 2; /* mark it as 2 so that we can later copy it back to
+ * mormal memory */
+ }
+ else if( w->alloced < wsize ) {
+ if( wp == up || wp == vp ) {
+ wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
+ assign_wp = 1;
+ }
+ else {
+ mpi_resize(w, wsize );
+ wp = w->d;
+ }
+ }
+ else { /* Make U and V not overlap with W. */
+ if( wp == up ) {
+ /* W and U are identical. Allocate temporary space for U. */
+ tmp_limb_nlimbs = usize;
+ up = tmp_limb = mpi_alloc_limb_space( usize, usecure );
+ /* Is V identical too? Keep it identical with U. */
+ if( wp == vp )
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY( up, wp, usize );
+ }
+ else if( wp == vp ) {
+ /* W and V are identical. Allocate temporary space for V. */
+ tmp_limb_nlimbs = vsize;
+ vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
+ /* Copy to the temporary space. */
+ MPN_COPY( vp, wp, vsize );
+ }
+ }
+
+ if( !vsize )
+ wsize = 0;
+ else {
+ cy = _gcry_mpih_mul( wp, up, usize, vp, vsize );
+ wsize -= cy? 0:1;
+ }
+
+ if( assign_wp ) {
+ if (assign_wp == 2) {
+ /* copy the temp wp from secure memory back to normal memory */
+ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
+ MPN_COPY (tmp_wp, wp, wsize);
+ _gcry_mpi_free_limb_space (wp, 0);
+ wp = tmp_wp;
+ }
+ _gcry_mpi_assign_limb_space( w, wp, wsize );
+ }
+ w->nlimbs = wsize;
+ w->sign = sign_product;
+ if( tmp_limb )
+ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs);
+}
+
+
+void
+gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ gcry_mpi_mul(w, u, v);
+ _gcry_mpi_fdiv_r( w, w, m );
+}
--- /dev/null
+/* mpi-pow.c - MPI functions for exponentiation
+ * Copyright (C) 1994, 1996, 1998, 2000, 2002
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ */
+void
+gcry_mpi_powm (gcry_mpi_t res,
+ gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+ /* Pointer to the limbs of the arguments, their size and signs. */
+ mpi_ptr_t rp, ep, mp, bp;
+ mpi_size_t esize, msize, bsize, rsize;
+ int msign, bsign, rsign;
+ /* Flags telling the secure allocation status of the arguments. */
+ int esec, msec, bsec;
+ /* Size of the result including space for temporary values. */
+ mpi_size_t size;
+ /* Helper. */
+ int mod_shift_cnt;
+ int negative_result;
+ mpi_ptr_t mp_marker = NULL;
+ mpi_ptr_t bp_marker = NULL;
+ mpi_ptr_t ep_marker = NULL;
+ mpi_ptr_t xp_marker = NULL;
+ unsigned int mp_nlimbs = 0;
+ unsigned int bp_nlimbs = 0;
+ unsigned int ep_nlimbs = 0;
+ unsigned int xp_nlimbs = 0;
+ mpi_ptr_t tspace = NULL;
+ mpi_size_t tsize = 0;
+
+
+ esize = expo->nlimbs;
+ msize = mod->nlimbs;
+ size = 2 * msize;
+ msign = mod->sign;
+
+ esec = mpi_is_secure(expo);
+ msec = mpi_is_secure(mod);
+ bsec = mpi_is_secure(base);
+
+ rp = res->d;
+ ep = expo->d;
+
+ if (!msize)
+ msize = 1 / msize; /* Provoke a signal. */
+
+ if (!esize)
+ {
+ /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+ on if MOD equals 1. */
+ rp[0] = 1;
+ res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ res->sign = 0;
+ goto leave;
+ }
+
+ /* Normalize MOD (i.e. make its most significant bit set) as
+ required by mpn_divrem. This will make the intermediate values
+ in the calculation slightly larger, but the correct result is
+ obtained after a final reduction using the original MOD value. */
+ mp_nlimbs = msec? msize:0;
+ mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+ count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+ if (mod_shift_cnt)
+ _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+ else
+ MPN_COPY( mp, mod->d, msize );
+
+ bsize = base->nlimbs;
+ bsign = base->sign;
+ if (bsize > msize)
+ {
+ /* The base is larger than the module. Reduce it.
+
+ Allocate (BSIZE + 1) with space for remainder and quotient.
+ (The quotient is (bsize - msize + 1) limbs.) */
+ bp_nlimbs = bsec ? (bsize + 1):0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+ MPN_COPY ( bp, base->d, bsize );
+ /* We don't care about the quotient, store it above the
+ * remainder, at BP + MSIZE. */
+ _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+ bsize = msize;
+ /* Canonicalize the base, since we are going to multiply with it
+ quite a few times. */
+ MPN_NORMALIZE( bp, bsize );
+ }
+ else
+ bp = base->d;
+
+ if (!bsize)
+ {
+ res->nlimbs = 0;
+ res->sign = 0;
+ goto leave;
+ }
+
+
+ /* Make BASE, EXPO and MOD not overlap with RES. */
+ if ( rp == bp )
+ {
+ /* RES and BASE are identical. Allocate temp. space for BASE. */
+ gcry_assert (!bp_marker);
+ bp_nlimbs = bsec? bsize:0;
+ bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+ MPN_COPY(bp, rp, bsize);
+ }
+ if ( rp == ep )
+ {
+ /* RES and EXPO are identical. Allocate temp. space for EXPO. */
+ ep_nlimbs = esec? esize:0;
+ ep = ep_marker = mpi_alloc_limb_space( esize, esec );
+ MPN_COPY(ep, rp, esize);
+ }
+ if ( rp == mp )
+ {
+ /* RES and MOD are identical. Allocate temporary space for MOD.*/
+ gcry_assert (!mp_marker);
+ mp_nlimbs = msec?msize:0;
+ mp = mp_marker = mpi_alloc_limb_space( msize, msec );
+ MPN_COPY(mp, rp, msize);
+ }
+
+ /* Copy base to the result. */
+ if (res->alloced < size)
+ {
+ mpi_resize (res, size);
+ rp = res->d;
+ }
+ MPN_COPY ( rp, bp, bsize );
+ rsize = bsize;
+ rsign = bsign;
+
+ /* Main processing. */
+ {
+ mpi_size_t i;
+ mpi_ptr_t xp;
+ int c;
+ mpi_limb_t e;
+ mpi_limb_t carry_limb;
+ struct karatsuba_ctx karactx;
+
+ xp_nlimbs = msec? (2 * (msize + 1)):0;
+ xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+
+ memset( &karactx, 0, sizeof karactx );
+ negative_result = (ep[0] & 1) && base->sign;
+
+ i = esize - 1;
+ e = ep[i];
+ count_leading_zeros (c, e);
+ e = (e << c) << 1; /* Shift the expo bits to the left, lose msb. */
+ c = BITS_PER_MPI_LIMB - 1 - c;
+
+ /* Main loop.
+
+ Make the result be pointed to alternately by XP and RP. This
+ helps us avoid block copying, which would otherwise be
+ necessary with the overlap restrictions of
+ _gcry_mpih_divmod. With 50% probability the result after this
+ loop will be in the area originally pointed by RP (==RES->d),
+ and with 50% probability in the area originally pointed to by XP. */
+ for (;;)
+ {
+ while (c)
+ {
+ mpi_ptr_t tp;
+ mpi_size_t xsize;
+
+ /*mpih_mul_n(xp, rp, rp, rsize);*/
+ if ( rsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( xp, rp, rsize );
+ else
+ {
+ if ( !tspace )
+ {
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space( tsize, 0 );
+ }
+ else if ( tsize < (2*rsize) )
+ {
+ _gcry_mpi_free_limb_space (tspace, 0);
+ tsize = 2 * rsize;
+ tspace = mpi_alloc_limb_space (tsize, 0 );
+ }
+ _gcry_mpih_sqr_n (xp, rp, rsize, tspace);
+ }
+
+ xsize = 2 * rsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+
+ if ( (mpi_limb_signed_t)e < 0 )
+ {
+ /*mpih_mul( xp, rp, rsize, bp, bsize );*/
+ if( bsize < KARATSUBA_THRESHOLD )
+ _gcry_mpih_mul ( xp, rp, rsize, bp, bsize );
+ else
+ _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, bp, bsize,
+ &karactx);
+
+ xsize = rsize + bsize;
+ if ( xsize > msize )
+ {
+ _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
+ xsize = msize;
+ }
+
+ tp = rp; rp = xp; xp = tp;
+ rsize = xsize;
+ }
+ e <<= 1;
+ c--;
+ }
+
+ i--;
+ if ( i < 0 )
+ break;
+ e = ep[i];
+ c = BITS_PER_MPI_LIMB;
+ }
+
+ /* We shifted MOD, the modulo reduction argument, left
+ MOD_SHIFT_CNT steps. Adjust the result by reducing it with the
+ original MOD.
+
+ Also make sure the result is put in RES->d (where it already
+ might be, see above). */
+ if ( mod_shift_cnt )
+ {
+ carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+ rp = res->d;
+ if ( carry_limb )
+ {
+ rp[rsize] = carry_limb;
+ rsize++;
+ }
+ }
+ else if (res->d != rp)
+ {
+ MPN_COPY (res->d, rp, rsize);
+ rp = res->d;
+ }
+
+ if ( rsize >= msize )
+ {
+ _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+ rsize = msize;
+ }
+
+ /* Remove any leading zero words from the result. */
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+ MPN_NORMALIZE (rp, rsize);
+
+ _gcry_mpih_release_karatsuba_ctx (&karactx );
+ }
+
+ /* Fixup for negative results. */
+ if ( negative_result && rsize )
+ {
+ if ( mod_shift_cnt )
+ _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+ _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+ rsize = msize;
+ rsign = msign;
+ MPN_NORMALIZE(rp, rsize);
+ }
+ gcry_assert (res->d == rp);
+ res->nlimbs = rsize;
+ res->sign = rsign;
+
+ leave:
+ if (mp_marker)
+ _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+ if (bp_marker)
+ _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+ if (ep_marker)
+ _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+ if (xp_marker)
+ _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+ if (tspace)
+ _gcry_mpi_free_limb_space( tspace, 0 );
+}
--- /dev/null
+/* mpi-scan.c - MPI functions
+ * Copyright (C) 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+/****************
+ * Scan through an mpi and return byte for byte. a -1 is returned to indicate
+ * the end of the mpi. Scanning is done from the lsb to the msb, returned
+ * values are in the range of 0 .. 255.
+ *
+ * FIXME: This code is VERY ugly!
+ */
+int
+_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx )
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb;
+
+ ap = a->d;
+ for(n=0,i=0; i < a->nlimbs; i++ ) {
+ limb = ap[i];
+ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+ if( n == idx )
+ return (limb >> j*8) & 0xff;
+ }
+ return -1;
+}
+
+
+/****************
+ * Put a value at position IDX into A. idx counts from lsb to msb
+ */
+void
+_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc )
+{
+ int i, j;
+ unsigned n;
+ mpi_ptr_t ap;
+ mpi_limb_t limb, c;
+
+ c = xc & 0xff;
+ ap = a->d;
+ for(n=0,i=0; i < a->alloced; i++ ) {
+ limb = ap[i];
+ for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
+ if( n == idx ) {
+ #if BYTES_PER_MPI_LIMB == 4
+ if( j == 0 )
+ limb = (limb & 0xffffff00) | c;
+ else if( j == 1 )
+ limb = (limb & 0xffff00ff) | (c<<8);
+ else if( j == 2 )
+ limb = (limb & 0xff00ffff) | (c<<16);
+ else
+ limb = (limb & 0x00ffffff) | (c<<24);
+ #elif BYTES_PER_MPI_LIMB == 8
+ if( j == 0 )
+ limb = (limb & 0xffffffffffffff00) | c;
+ else if( j == 1 )
+ limb = (limb & 0xffffffffffff00ff) | (c<<8);
+ else if( j == 2 )
+ limb = (limb & 0xffffffffff00ffff) | (c<<16);
+ else if( j == 3 )
+ limb = (limb & 0xffffffff00ffffff) | (c<<24);
+ else if( j == 4 )
+ limb = (limb & 0xffffff00ffffffff) | (c<<32);
+ else if( j == 5 )
+ limb = (limb & 0xffff00ffffffffff) | (c<<40);
+ else if( j == 6 )
+ limb = (limb & 0xff00ffffffffffff) | (c<<48);
+ else
+ limb = (limb & 0x00ffffffffffffff) | (c<<56);
+ #else
+ #error please enhance this function, its ugly - i know.
+ #endif
+ if( a->nlimbs <= i )
+ a->nlimbs = i+1;
+ ap[i] = limb;
+ return;
+ }
+ }
+ abort(); /* index out of range */
+}
+
+
+/****************
+ * Count the number of zerobits at the low end of A
+ */
+unsigned
+_gcry_mpi_trailing_zeros( gcry_mpi_t a )
+{
+ unsigned n, count = 0;
+
+ for(n=0; n < a->nlimbs; n++ ) {
+ if( a->d[n] ) {
+ unsigned nn;
+ mpi_limb_t alimb = a->d[n];
+
+ count_trailing_zeros( nn, alimb );
+ count += nn;
+ break;
+ }
+ count += BITS_PER_MPI_LIMB;
+ }
+ return count;
+
+}
--- /dev/null
+/* mpicoder.c - Coder for the external representation of MPIs
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "mpi-internal.h"
+#include "g10lib.h"
+
+#define MAX_EXTERN_MPI_BITS 16384
+
+/* Helper used to scan PGP style MPIs. Returns NULL on failure. */
+static gcry_mpi_t
+mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
+ int secure)
+{
+ int i, j;
+ unsigned int nbits, nbytes, nlimbs, nread=0;
+ mpi_limb_t a;
+ gcry_mpi_t val = MPI_NULL;
+
+ if ( *ret_nread < 2 )
+ goto leave;
+ nbits = buffer[0] << 8 | buffer[1];
+ if ( nbits > MAX_EXTERN_MPI_BITS )
+ {
+/* log_debug ("mpi too large (%u bits)\n", nbits); */
+ goto leave;
+ }
+ buffer += 2;
+ nread = 2;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+ val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
+ i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
+ i %= BYTES_PER_MPI_LIMB;
+ j= val->nlimbs = nlimbs;
+ val->sign = 0;
+ for ( ; j > 0; j-- )
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++ )
+ {
+ if ( ++nread > *ret_nread )
+ {
+/* log_debug ("mpi larger than buffer"); */
+ mpi_free (val);
+ val = NULL;
+ goto leave;
+ }
+ a <<= 8;
+ a |= *buffer++;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ leave:
+ *ret_nread = nread;
+ return val;
+}
+
+
+/****************
+ * Fill the mpi VAL from the hex string in STR.
+ */
+static int
+mpi_fromstr (gcry_mpi_t val, const char *str)
+{
+ int sign = 0;
+ int prepend_zero = 0;
+ int i, j, c, c1, c2;
+ unsigned int nbits, nbytes, nlimbs;
+ mpi_limb_t a;
+
+ if ( *str == '-' )
+ {
+ sign = 1;
+ str++;
+ }
+
+ /* Skip optional hex prefix. */
+ if ( *str == '0' && str[1] == 'x' )
+ str += 2;
+
+ nbits = 4 * strlen (str);
+ if ((nbits % 8))
+ prepend_zero = 1;
+
+ nbytes = (nbits+7) / 8;
+ nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
+
+ if ( val->alloced < nlimbs )
+ mpi_resize (val, nlimbs);
+
+ i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
+ i %= BYTES_PER_MPI_LIMB;
+ j = val->nlimbs = nlimbs;
+ val->sign = sign;
+ for (; j > 0; j--)
+ {
+ a = 0;
+ for (; i < BYTES_PER_MPI_LIMB; i++)
+ {
+ if (prepend_zero)
+ {
+ c1 = '0';
+ prepend_zero = 0;
+ }
+ else
+ c1 = *str++;
+
+ if (!c1)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c2 = *str++;
+ if (!c2)
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ if ( c1 >= '0' && c1 <= '9' )
+ c = c1 - '0';
+ else if ( c1 >= 'a' && c1 <= 'f' )
+ c = c1 - 'a' + 10;
+ else if ( c1 >= 'A' && c1 <= 'F' )
+ c = c1 - 'A' + 10;
+ else
+ {
+ mpi_clear (val);
+ return 1; /* Error. */
+ }
+ c <<= 4;
+ if ( c2 >= '0' && c2 <= '9' )
+ c |= c2 - '0';
+ else if( c2 >= 'a' && c2 <= 'f' )
+ c |= c2 - 'a' + 10;
+ else if( c2 >= 'A' && c2 <= 'F' )
+ c |= c2 - 'A' + 10;
+ else
+ {
+ mpi_clear(val);
+ return 1; /* Error. */
+ }
+ a <<= 8;
+ a |= c;
+ }
+ i = 0;
+ val->d[j-1] = a;
+ }
+
+ return 0; /* Okay. */
+}
+
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void
+gcry_mpi_dump (const gcry_mpi_t a)
+{
+ int i;
+
+ log_printf (" ");
+ if (!a)
+ log_printf ("[MPI_NULL]");
+ else
+ {
+ if (a->sign)
+ log_printf ( "-");
+#if BYTES_PER_MPI_LIMB == 2
+# define X "4"
+#elif BYTES_PER_MPI_LIMB == 4
+# define X "8"
+#elif BYTES_PER_MPI_LIMB == 8
+# define X "16"
+#elif BYTES_PER_MPI_LIMB == 16
+# define X "32"
+#else
+# error please define the format here
+#endif
+ for (i=a->nlimbs; i > 0 ; i-- )
+ {
+ log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
+ }
+#undef X
+ if (!a->nlimbs)
+ log_printf ("0");
+ }
+}
+
+/* Convience function used internally. */
+void
+_gcry_log_mpidump (const char *text, gcry_mpi_t a)
+{
+ log_printf ("%s:", text);
+ gcry_mpi_dump (a);
+ log_printf ("\n");
+}
+
+
+/* Return an allocated buffer with the MPI (msb first). NBYTES
+ receives the length of this buffer. Caller must free the return
+ string. This function returns an allocated buffer with NBYTES set
+ to zero if the value of A is zero. If sign is not NULL, it will be
+ set to the sign of the A. On error NULL is returned and ERRNO set
+ appropriately. */
+static unsigned char *
+do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
+{
+ unsigned char *p, *buffer;
+ mpi_limb_t alimb;
+ int i;
+ size_t n;
+
+ if (sign)
+ *sign = a->sign;
+
+ *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
+ n = *nbytes? *nbytes:1; /* Allocate at least one byte. */
+ p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
+ : gcry_malloc (n);
+ if (!buffer)
+ return NULL;
+
+ for (i=a->nlimbs-1; i >= 0; i--)
+ {
+ alimb = a->d[i];
+#if BYTES_PER_MPI_LIMB == 4
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#elif BYTES_PER_MPI_LIMB == 8
+ *p++ = alimb >> 56;
+ *p++ = alimb >> 48;
+ *p++ = alimb >> 40;
+ *p++ = alimb >> 32;
+ *p++ = alimb >> 24;
+ *p++ = alimb >> 16;
+ *p++ = alimb >> 8;
+ *p++ = alimb ;
+#else
+# error please implement for this limb size.
+#endif
+ }
+
+ /* This is sub-optimal but we need to do the shift operation because
+ the caller has to free the returned buffer. */
+ for (p=buffer; !*p && *nbytes; p++, --*nbytes)
+ ;
+ if (p != buffer)
+ memmove (buffer,p, *nbytes);
+ return buffer;
+}
+
+
+byte *
+_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
+{
+ return do_get_buffer (a, nbytes, sign, 0);
+}
+
+byte *
+_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
+{
+ return do_get_buffer (a, nbytes, sign, 1);
+}
+
+
+/*
+ * Use the NBYTES at BUFFER_ARG to update A. Set the sign of a to
+ * SIGN.
+ */
+void
+_gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
+ unsigned int nbytes, int sign)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ const unsigned char *p;
+ mpi_limb_t alimb;
+ int nlimbs;
+ int i;
+
+ nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
+ RESIZE_IF_NEEDED(a, nlimbs);
+ a->sign = sign;
+
+ for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = *p-- ;
+ alimb |= *p-- << 8 ;
+ alimb |= *p-- << 16 ;
+ alimb |= *p-- << 24 ;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p-- ;
+ alimb |= (mpi_limb_t)*p-- << 8 ;
+ alimb |= (mpi_limb_t)*p-- << 16 ;
+ alimb |= (mpi_limb_t)*p-- << 24 ;
+ alimb |= (mpi_limb_t)*p-- << 32 ;
+ alimb |= (mpi_limb_t)*p-- << 40 ;
+ alimb |= (mpi_limb_t)*p-- << 48 ;
+ alimb |= (mpi_limb_t)*p-- << 56 ;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ if ( p >= buffer )
+ {
+#if BYTES_PER_MPI_LIMB == 4
+ alimb = *p--;
+ if (p >= buffer)
+ alimb |= *p-- << 8;
+ if (p >= buffer)
+ alimb |= *p-- << 16;
+ if (p >= buffer)
+ alimb |= *p-- << 24;
+#elif BYTES_PER_MPI_LIMB == 8
+ alimb = (mpi_limb_t)*p--;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 8;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 16;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 24;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 32;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 40;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 48;
+ if (p >= buffer)
+ alimb |= (mpi_limb_t)*p-- << 56;
+#else
+# error please implement for this limb size.
+#endif
+ a->d[i++] = alimb;
+ }
+ a->nlimbs = i;
+ gcry_assert (i == nlimbs);
+}
+
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NBYTES is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t
+gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
+ const void *buffer_arg, size_t buflen, size_t *nscanned)
+{
+ const unsigned char *buffer = (const unsigned char*)buffer_arg;
+ struct gcry_mpi *a = NULL;
+ unsigned int len;
+ int secure = (buffer && gcry_is_secure (buffer));
+
+ if (format == GCRYMPI_FMT_SSH)
+ len = 0;
+ else
+ len = buflen;
+
+ if (format == GCRYMPI_FMT_STD)
+ {
+ const unsigned char *s = buffer;
+
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (len)
+ {
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ /* FIXME: we have to convert from 2compl to magnitude format */
+ mpi_free (a);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+ else
+ _gcry_mpi_set_buffer (a, s, len, 0);
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+
+ if (len)
+ _gcry_mpi_set_buffer (a, buffer, len, 0);
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ a = mpi_read_from_buffer (buffer, &len, secure);
+ if (nscanned)
+ *nscanned = len;
+ if (ret_mpi && a)
+ {
+ mpi_normalize (a);
+ *ret_mpi = a;
+ }
+ else if (a)
+ {
+ mpi_free(a);
+ a = NULL;
+ }
+ return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ const unsigned char *s = buffer;
+ size_t n;
+
+ /* This test is not strictly necessary and an assert (!len)
+ would be sufficient. We keep this test in case we later
+ allow the BUFLEN argument to act as a sanitiy check. Same
+ below. */
+ if (len && len < 4)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+
+ n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+ s += 4;
+ if (len)
+ len -= 4;
+ if (len && n > len)
+ return gcry_error (GPG_ERR_TOO_LARGE);
+
+ a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
+ /BYTES_PER_MPI_LIMB)
+ : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
+ if (n)
+ {
+ a->sign = !!(*s & 0x80);
+ if (a->sign)
+ {
+ /* FIXME: we have to convert from 2compl to magnitude format */
+ mpi_free(a);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+ else
+ _gcry_mpi_set_buffer( a, s, n, 0 );
+ }
+ if (nscanned)
+ *nscanned = n+4;
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ /* We can only handle C strings for now. */
+ if (buflen)
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
+ if (mpi_fromstr (a, (const char *)buffer))
+ {
+ mpi_free (a);
+ return gcry_error (GPG_ERR_INV_OBJ);
+ }
+ if (ret_mpi)
+ {
+ mpi_normalize ( a );
+ *ret_mpi = a;
+ }
+ else
+ mpi_free(a);
+ return 0;
+ }
+ else
+ return gcry_error (GPG_ERR_INV_ARG);
+}
+
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. BUFFER may be NULL to query the required
+ length. */
+gcry_error_t
+gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten, struct gcry_mpi *a)
+{
+ unsigned int nbits = mpi_get_nbits (a);
+ size_t len;
+ size_t dummy_nwritten;
+
+ if (!nwritten)
+ nwritten = &dummy_nwritten;
+
+ len = buflen;
+ *nwritten = 0;
+ if (format == GCRYMPI_FMT_STD)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ if (a->sign)
+ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (n && (*tmp & 0x80))
+ {
+ n++;
+ extra=1;
+ }
+
+ if (buffer && n > len)
+ {
+ /* The provided buffer is too short. */
+ gcry_free (tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (extra)
+ *s++ = 0;
+ memcpy (s, tmp, n-extra);
+ }
+ gcry_free(tmp);
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_USG)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* Note: We ignore the sign for this format. */
+ /* FIXME: for performance reasons we should put this into
+ mpi_aprint because we can then use the buffer directly. */
+ if (buffer && n > len)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ if (buffer)
+ {
+ unsigned char *tmp;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ memcpy (buffer, tmp, n);
+ gcry_free (tmp);
+ }
+ *nwritten = n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_PGP)
+ {
+ unsigned int n = (nbits + 7)/8;
+
+ /* The PGP format can only handle unsigned integers. */
+ if( a->sign )
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ if (buffer && n+2 > len)
+ return gcry_error (GPG_ERR_TOO_SHORT);
+
+ if (buffer)
+ {
+ unsigned char *tmp;
+ unsigned char *s = buffer;
+
+ s[0] = nbits >> 8;
+ s[1] = nbits;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ memcpy (s+2, tmp, n);
+ gcry_free (tmp);
+ }
+ *nwritten = n+2;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_SSH)
+ {
+ unsigned char *tmp;
+ int extra = 0;
+ unsigned int n;
+
+ if (a->sign)
+ return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (n && (*tmp & 0x80))
+ {
+ n++;
+ extra=1;
+ }
+
+ if (buffer && n+4 > len)
+ {
+ gcry_free(tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ *s++ = n >> 24;
+ *s++ = n >> 16;
+ *s++ = n >> 8;
+ *s++ = n;
+ if (extra)
+ *s++ = 0;
+
+ memcpy (s, tmp, n-extra);
+ }
+ gcry_free (tmp);
+ *nwritten = 4+n;
+ return 0;
+ }
+ else if (format == GCRYMPI_FMT_HEX)
+ {
+ unsigned char *tmp;
+ int i;
+ int extra = 0;
+ unsigned int n = 0;
+
+ tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+ if (!tmp)
+ return gpg_error_from_syserror ();
+ if (!n || (*tmp & 0x80))
+ extra = 2;
+
+ if (buffer && 2*n + extra + !!a->sign + 1 > len)
+ {
+ gcry_free(tmp);
+ return gcry_error (GPG_ERR_TOO_SHORT);
+ }
+ if (buffer)
+ {
+ unsigned char *s = buffer;
+
+ if (a->sign)
+ *s++ = '-';
+ if (extra)
+ {
+ *s++ = '0';
+ *s++ = '0';
+ }
+
+ for (i=0; i < n; i++)
+ {
+ unsigned int c = tmp[i];
+
+ *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
+ c &= 15;
+ *s++ = c < 10? '0'+c : 'A'+c-10 ;
+ }
+ *s++ = 0;
+ *nwritten = s - buffer;
+ }
+ else
+ {
+ *nwritten = 2*n + extra + !!a->sign + 1;
+ }
+ gcry_free (tmp);
+ return 0;
+ }
+ else
+ return gcry_error (GPG_ERR_INV_ARG);
+}
+
+
+/*
+ * Like gcry_mpi_print but this function allocates the buffer itself.
+ * The caller has to supply the address of a pointer. NWRITTEN may be
+ * NULL.
+ */
+gcry_error_t
+gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ struct gcry_mpi *a)
+{
+ size_t n;
+ gcry_error_t rc;
+
+ *buffer = NULL;
+ rc = gcry_mpi_print (format, NULL, 0, &n, a);
+ if (rc)
+ return rc;
+
+ *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
+ if (!*buffer)
+ return gpg_error_from_syserror ();
+ rc = gcry_mpi_print( format, *buffer, n, &n, a );
+ if (rc)
+ {
+ gcry_free(*buffer);
+ *buffer = NULL;
+ }
+ else if (nwritten)
+ *nwritten = n;
+ return rc;
+}
--- /dev/null
+/* mpih-div.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+
+#ifndef UMUL_TIME
+#define UMUL_TIME 1
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME UMUL_TIME
+#endif
+
+/* FIXME: We should be using invert_limb (or invert_normalized_limb)
+ * here (not udiv_qrnnd).
+ */
+
+mpi_limb_t
+_gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ /* Botch: Should this be handled at all? Rely on callers? */
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ *
+ * Special case for DIVISOR_LIMB == 100...000.
+ */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ i--;
+
+ for( ; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV(dummy, r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if( UDIV_NEEDS_NORMALIZATION ) {
+ int normalization_steps;
+
+ count_leading_zeros(normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for(i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (dummy, r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ i--;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (dummy, r, r, n0, divisor_limb);
+ }
+ return r;
+ }
+}
+
+/* Divide num (NP/NSIZE) by den (DP/DSIZE) and write
+ * the NSIZE-DSIZE least significant quotient limbs at QP
+ * and the DSIZE long remainder at NP. If QEXTRA_LIMBS is
+ * non-zero, generate that many fraction bits and append them after the
+ * other quotient limbs.
+ * Return the most significant limb of the quotient, this is always 0 or 1.
+ *
+ * Preconditions:
+ * 0. NSIZE >= DSIZE.
+ * 1. The most significant bit of the divisor must be set.
+ * 2. QP must either not overlap with the input operands at all, or
+ * QP + DSIZE >= NP must hold true. (This means that it's
+ * possible to put the quotient in the high part of NUM, right after the
+ * remainder in NUM.
+ * 3. NSIZE >= DSIZE, even if QEXTRA_LIMBS is non-zero.
+ */
+
+mpi_limb_t
+_gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
+ mpi_ptr_t np, mpi_size_t nsize,
+ mpi_ptr_t dp, mpi_size_t dsize)
+{
+ mpi_limb_t most_significant_q_limb = 0;
+
+ switch(dsize) {
+ case 0:
+ /* We are asked to divide by zero, so go ahead and do it! (To make
+ the compiler not remove this statement, return the value.) */
+ return 1 / dsize;
+
+ case 1:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1;
+ mpi_limb_t d;
+
+ d = dp[0];
+ n1 = np[nsize - 1];
+
+ if( n1 >= d ) {
+ n1 -= d;
+ most_significant_q_limb = 1;
+ }
+
+ qp += qextra_limbs;
+ for( i = nsize - 2; i >= 0; i--)
+ udiv_qrnnd( qp[i], n1, n1, np[i], d );
+ qp -= qextra_limbs;
+
+ for( i = qextra_limbs - 1; i >= 0; i-- )
+ udiv_qrnnd (qp[i], n1, n1, 0, d);
+
+ np[0] = n1;
+ }
+ break;
+
+ case 2:
+ {
+ mpi_size_t i;
+ mpi_limb_t n1, n0, n2;
+ mpi_limb_t d1, d0;
+
+ np += nsize - 2;
+ d1 = dp[1];
+ d0 = dp[0];
+ n1 = np[1];
+ n0 = np[0];
+
+ if( n1 >= d1 && (n1 > d1 || n0 >= d0) ) {
+ sub_ddmmss (n1, n0, n1, n0, d1, d0);
+ most_significant_q_limb = 1;
+ }
+
+ for( i = qextra_limbs + nsize - 2 - 1; i >= 0; i-- ) {
+ mpi_limb_t q;
+ mpi_limb_t r;
+
+ if( i >= qextra_limbs )
+ np--;
+ else
+ np[0] = 0;
+
+ if( n1 == d1 ) {
+ /* Q should be either 111..111 or 111..110. Need special
+ * treatment of this rare case as normal division would
+ * give overflow. */
+ q = ~(mpi_limb_t)0;
+
+ r = n0 + d1;
+ if( r < d1 ) { /* Carry in the addition? */
+ add_ssaaaa( n1, n0, r - d0, np[0], 0, d0 );
+ qp[i] = q;
+ continue;
+ }
+ n1 = d0 - (d0 != 0?1:0);
+ n0 = -d0;
+ }
+ else {
+ udiv_qrnnd (q, r, n1, n0, d1);
+ umul_ppmm (n1, n0, d0, q);
+ }
+
+ n2 = np[0];
+ q_test:
+ if( n1 > r || (n1 == r && n0 > n2) ) {
+ /* The estimated Q was too large. */
+ q--;
+ sub_ddmmss (n1, n0, n1, n0, 0, d0);
+ r += d1;
+ if( r >= d1 ) /* If not carry, test Q again. */
+ goto q_test;
+ }
+
+ qp[i] = q;
+ sub_ddmmss (n1, n0, r, n2, n1, n0);
+ }
+ np[1] = n1;
+ np[0] = n0;
+ }
+ break;
+
+ default:
+ {
+ mpi_size_t i;
+ mpi_limb_t dX, d1, n0;
+
+ np += nsize - dsize;
+ dX = dp[dsize - 1];
+ d1 = dp[dsize - 2];
+ n0 = np[dsize - 1];
+
+ if( n0 >= dX ) {
+ if(n0 > dX || _gcry_mpih_cmp(np, dp, dsize - 1) >= 0 ) {
+ _gcry_mpih_sub_n(np, np, dp, dsize);
+ n0 = np[dsize - 1];
+ most_significant_q_limb = 1;
+ }
+ }
+
+ for( i = qextra_limbs + nsize - dsize - 1; i >= 0; i--) {
+ mpi_limb_t q;
+ mpi_limb_t n1, n2;
+ mpi_limb_t cy_limb;
+
+ if( i >= qextra_limbs ) {
+ np--;
+ n2 = np[dsize];
+ }
+ else {
+ n2 = np[dsize - 1];
+ MPN_COPY_DECR (np + 1, np, dsize - 1);
+ np[0] = 0;
+ }
+
+ if( n0 == dX ) {
+ /* This might over-estimate q, but it's probably not worth
+ * the extra code here to find out. */
+ q = ~(mpi_limb_t)0;
+ }
+ else {
+ mpi_limb_t r;
+
+ udiv_qrnnd(q, r, n0, np[dsize - 1], dX);
+ umul_ppmm(n1, n0, d1, q);
+
+ while( n1 > r || (n1 == r && n0 > np[dsize - 2])) {
+ q--;
+ r += dX;
+ if( r < dX ) /* I.e. "carry in previous addition?" */
+ break;
+ n1 -= n0 < d1;
+ n0 -= d1;
+ }
+ }
+
+ /* Possible optimization: We already have (q * n0) and (1 * n1)
+ * after the calculation of q. Taking advantage of that, we
+ * could make this loop make two iterations less. */
+ cy_limb = _gcry_mpih_submul_1(np, dp, dsize, q);
+
+ if( n2 != cy_limb ) {
+ _gcry_mpih_add_n(np, np, dp, dsize);
+ q--;
+ }
+
+ qp[i] = q;
+ n0 = np[dsize - 1];
+ }
+ }
+ }
+
+ return most_significant_q_limb;
+}
+
+
+/****************
+ * Divide (DIVIDEND_PTR,,DIVIDEND_SIZE) by DIVISOR_LIMB.
+ * Write DIVIDEND_SIZE limbs of quotient at QUOT_PTR.
+ * Return the single-limb remainder.
+ * There are no constraints on the value of the divisor.
+ *
+ * QUOT_PTR and DIVIDEND_PTR might point to the same limb.
+ */
+
+mpi_limb_t
+_gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
+ mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
+ mpi_limb_t divisor_limb)
+{
+ mpi_size_t i;
+ mpi_limb_t n1, n0, r;
+ int dummy;
+
+ if( !dividend_size )
+ return 0;
+
+ /* If multiplication is much faster than division, and the
+ * dividend is large, pre-invert the divisor, and use
+ * only multiplications in the inner loop.
+ *
+ * This test should be read:
+ * Does it ever help to use udiv_qrnnd_preinv?
+ * && Does what we save compensate for the inversion overhead?
+ */
+ if( UDIV_TIME > (2 * UMUL_TIME + 6)
+ && (UDIV_TIME - (2 * UMUL_TIME + 6)) * dividend_size > UDIV_TIME ) {
+ int normalization_steps;
+
+ count_leading_zeros( normalization_steps, divisor_limb );
+ if( normalization_steps ) {
+ mpi_limb_t divisor_limb_inverted;
+
+ divisor_limb <<= normalization_steps;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t)0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb, divisor_limb_inverted);
+ n1 = n0;
+ }
+ UDIV_QRNND_PREINV( quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb, divisor_limb_inverted);
+ return r >> normalization_steps;
+ }
+ else {
+ mpi_limb_t divisor_limb_inverted;
+
+ /* Compute (2**2N - 2**N * DIVISOR_LIMB) / DIVISOR_LIMB. The
+ * result is a (N+1)-bit approximation to 1/DIVISOR_LIMB, with the
+ * most significant bit (with weight 2**N) implicit.
+ */
+ /* Special case for DIVISOR_LIMB == 100...000. */
+ if( !(divisor_limb << 1) )
+ divisor_limb_inverted = ~(mpi_limb_t) 0;
+ else
+ udiv_qrnnd(divisor_limb_inverted, dummy,
+ -divisor_limb, 0, divisor_limb);
+
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if( r >= divisor_limb )
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for( ; i >= 0; i-- ) {
+ n0 = dividend_ptr[i];
+ UDIV_QRNND_PREINV( quot_ptr[i], r, r,
+ n0, divisor_limb, divisor_limb_inverted);
+ }
+ return r;
+ }
+ }
+ else {
+ if(UDIV_NEEDS_NORMALIZATION) {
+ int normalization_steps;
+
+ count_leading_zeros (normalization_steps, divisor_limb);
+ if( normalization_steps ) {
+ divisor_limb <<= normalization_steps;
+
+ n1 = dividend_ptr[dividend_size - 1];
+ r = n1 >> (BITS_PER_MPI_LIMB - normalization_steps);
+
+ /* Possible optimization:
+ * if (r == 0
+ * && divisor_limb > ((n1 << normalization_steps)
+ * | (dividend_ptr[dividend_size - 2] >> ...)))
+ * ...one division less...
+ */
+ for( i = dividend_size - 2; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd (quot_ptr[i + 1], r, r,
+ ((n1 << normalization_steps)
+ | (n0 >> (BITS_PER_MPI_LIMB - normalization_steps))),
+ divisor_limb);
+ n1 = n0;
+ }
+ udiv_qrnnd (quot_ptr[0], r, r,
+ n1 << normalization_steps,
+ divisor_limb);
+ return r >> normalization_steps;
+ }
+ }
+ /* No normalization needed, either because udiv_qrnnd doesn't require
+ * it, or because DIVISOR_LIMB is already normalized. */
+ i = dividend_size - 1;
+ r = dividend_ptr[i];
+
+ if(r >= divisor_limb)
+ r = 0;
+ else
+ quot_ptr[i--] = 0;
+
+ for(; i >= 0; i--) {
+ n0 = dividend_ptr[i];
+ udiv_qrnnd( quot_ptr[i], r, r, n0, divisor_limb );
+ }
+ return r;
+ }
+}
--- /dev/null
+/* mpih-mul.c - MPI helper functions
+ * Copyright (C) 1994, 1996, 1998, 1999, 2000,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+
+#define MPN_MUL_N_RECURSE(prodp, up, vp, size, tspace) \
+ do { \
+ if( (size) < KARATSUBA_THRESHOLD ) \
+ mul_n_basecase (prodp, up, vp, size); \
+ else \
+ mul_n (prodp, up, vp, size, tspace); \
+ } while (0);
+
+#define MPN_SQR_N_RECURSE(prodp, up, size, tspace) \
+ do { \
+ if ((size) < KARATSUBA_THRESHOLD) \
+ _gcry_mpih_sqr_n_basecase (prodp, up, size); \
+ else \
+ _gcry_mpih_sqr_n (prodp, up, size, tspace); \
+ } while (0);
+
+
+
+
+/* Multiply the natural numbers u (pointed to by UP) and v (pointed to by VP),
+ * both with SIZE limbs, and store the result at PRODP. 2 * SIZE limbs are
+ * always stored. Return the most significant limb.
+ *
+ * Argument constraints:
+ * 1. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ *
+ *
+ * Handle simple cases with traditional multiplication.
+ *
+ * This is the most critical code of multiplication. All multiplies rely
+ * on this, both small and huge. Small ones arrive here immediately. Huge
+ * ones arrive here as this is the base case for Karatsuba's recursive
+ * algorithm below.
+ */
+
+static mpi_limb_t
+mul_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up,
+ mpi_ptr_t vp, mpi_size_t size)
+{
+ mpi_size_t i;
+ mpi_limb_t cy;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO( prodp, size );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < size; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy;
+ prodp++;
+ }
+
+ return cy;
+}
+
+
+static void
+mul_n( mpi_ptr_t prodp, mpi_ptr_t up, mpi_ptr_t vp,
+ mpi_size_t size, mpi_ptr_t tspace )
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, vp[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, vp, size, up[esize] );
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ /* Anatolij Alekseevich Karatsuba's divide-and-conquer algorithm.
+ *
+ * Split U in two pieces, U1 and U0, such that
+ * U = U0 + U1*(B**n),
+ * and V in V1 and V0, such that
+ * V = V0 + V1*(B**n).
+ *
+ * UV is then computed recursively using the identity
+ *
+ * 2n n n n
+ * UV = (B + B )U V + B (U -U )(V -V ) + (B + 1)U V
+ * 1 1 1 0 0 1 0 0
+ *
+ * Where B = 2**BITS_PER_MP_LIMB.
+ */
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+ int negflg;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x V1____||____U0 x V0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(prodp + size, up + hsize, vp + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(V0-V1)_|
+ */
+ if( _gcry_mpih_cmp(up + hsize, up, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp, up + hsize, up, hsize);
+ negflg = 0;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp, up, up + hsize, hsize);
+ negflg = 1;
+ }
+ if( _gcry_mpih_cmp(vp + hsize, vp, hsize) >= 0 ) {
+ _gcry_mpih_sub_n(prodp + hsize, vp + hsize, vp, hsize);
+ negflg ^= 1;
+ }
+ else {
+ _gcry_mpih_sub_n(prodp + hsize, vp, vp + hsize, hsize);
+ /* No change of NEGFLG. */
+ }
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, prodp, prodp + hsize, hsize, tspace + size);
+
+ /* Add/copy product H. */
+ MPN_COPY (prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n( prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number) */
+ if(negflg)
+ cy -= _gcry_mpih_sub_n(prodp + hsize, prodp + hsize, tspace, size);
+ else
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x V0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_MUL_N_RECURSE(tspace, up, vp, hsize, tspace + size);
+
+ /* Add/copy Product L (twice) */
+
+ cy += _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size, hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n(prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1(prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n_basecase( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t size )
+{
+ mpi_size_t i;
+ mpi_limb_t cy_limb;
+ mpi_limb_t v_limb;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = up[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, size );
+ else
+ MPN_ZERO(prodp, size);
+ cy_limb = 0;
+ }
+ else
+ cy_limb = _gcry_mpih_mul_1( prodp, up, size, v_limb );
+
+ prodp[size] = cy_limb;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i=1; i < size; i++) {
+ v_limb = up[i];
+ if( v_limb <= 1 ) {
+ cy_limb = 0;
+ if( v_limb == 1 )
+ cy_limb = _gcry_mpih_add_n(prodp, prodp, up, size);
+ }
+ else
+ cy_limb = _gcry_mpih_addmul_1(prodp, up, size, v_limb);
+
+ prodp[size] = cy_limb;
+ prodp++;
+ }
+}
+
+
+void
+_gcry_mpih_sqr_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t size, mpi_ptr_t tspace)
+{
+ if( size & 1 ) {
+ /* The size is odd, and the code below doesn't handle that.
+ * Multiply the least significant (size - 1) limbs with a recursive
+ * call, and handle the most significant limb of S1 and S2
+ * separately.
+ * A slightly faster way to do this would be to make the Karatsuba
+ * code below behave as if the size were even, and let it check for
+ * odd size in the end. I.e., in essence move this code to the end.
+ * Doing so would save us a recursive call, and potentially make the
+ * stack grow a lot less.
+ */
+ mpi_size_t esize = size - 1; /* even size */
+ mpi_limb_t cy_limb;
+
+ MPN_SQR_N_RECURSE( prodp, up, esize, tspace );
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, esize, up[esize] );
+ prodp[esize + esize] = cy_limb;
+ cy_limb = _gcry_mpih_addmul_1( prodp + esize, up, size, up[esize] );
+
+ prodp[esize + size] = cy_limb;
+ }
+ else {
+ mpi_size_t hsize = size >> 1;
+ mpi_limb_t cy;
+
+ /* Product H. ________________ ________________
+ * |_____U1 x U1____||____U0 x U0_____|
+ * Put result in upper part of PROD and pass low part of TSPACE
+ * as new TSPACE.
+ */
+ MPN_SQR_N_RECURSE(prodp + size, up + hsize, hsize, tspace);
+
+ /* Product M. ________________
+ * |_(U1-U0)(U0-U1)_|
+ */
+ if( _gcry_mpih_cmp( up + hsize, up, hsize) >= 0 )
+ _gcry_mpih_sub_n( prodp, up + hsize, up, hsize);
+ else
+ _gcry_mpih_sub_n (prodp, up, up + hsize, hsize);
+
+ /* Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE(tspace, prodp, hsize, tspace + size);
+
+ /* Add/copy product H */
+ MPN_COPY(prodp + hsize, prodp + size, hsize);
+ cy = _gcry_mpih_add_n(prodp + size, prodp + size,
+ prodp + size + hsize, hsize);
+
+ /* Add product M (if NEGFLG M is a negative number). */
+ cy -= _gcry_mpih_sub_n (prodp + hsize, prodp + hsize, tspace, size);
+
+ /* Product L. ________________ ________________
+ * |________________||____U0 x U0_____|
+ * Read temporary operands from low part of PROD.
+ * Put result in low part of TSPACE using upper part of TSPACE
+ * as new TSPACE. */
+ MPN_SQR_N_RECURSE (tspace, up, hsize, tspace + size);
+
+ /* Add/copy Product L (twice). */
+ cy += _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace, size);
+ if( cy )
+ _gcry_mpih_add_1(prodp + hsize + size, prodp + hsize + size,
+ hsize, cy);
+
+ MPN_COPY(prodp, tspace, hsize);
+ cy = _gcry_mpih_add_n (prodp + hsize, prodp + hsize, tspace + hsize, hsize);
+ if( cy )
+ _gcry_mpih_add_1 (prodp + size, prodp + size, size, 1);
+ }
+}
+
+
+/* This should be made into an inline function in gmp.h. */
+void
+_gcry_mpih_mul_n( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_ptr_t vp, mpi_size_t size)
+{
+ int secure;
+
+ if( up == vp ) {
+ if( size < KARATSUBA_THRESHOLD )
+ _gcry_mpih_sqr_n_basecase( prodp, up, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = gcry_is_secure( up );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ _gcry_mpih_sqr_n( prodp, up, size, tspace );
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+ else {
+ if( size < KARATSUBA_THRESHOLD )
+ mul_n_basecase( prodp, up, vp, size );
+ else {
+ mpi_ptr_t tspace;
+ secure = gcry_is_secure( up ) || gcry_is_secure( vp );
+ tspace = mpi_alloc_limb_space( 2 * size, secure );
+ mul_n (prodp, up, vp, size, tspace);
+ _gcry_mpi_free_limb_space (tspace, 2 * size );
+ }
+ }
+}
+
+
+
+void
+_gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
+ mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize,
+ struct karatsuba_ctx *ctx )
+{
+ mpi_limb_t cy;
+
+ if( !ctx->tspace || ctx->tspace_size < vsize ) {
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ ctx->tspace_nlimbs = 2 * vsize;
+ ctx->tspace = mpi_alloc_limb_space( 2 * vsize,
+ (gcry_is_secure( up )
+ || gcry_is_secure( vp )) );
+ ctx->tspace_size = vsize;
+ }
+
+ MPN_MUL_N_RECURSE( prodp, up, vp, vsize, ctx->tspace );
+
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ if( usize >= vsize ) {
+ if( !ctx->tp || ctx->tp_size < vsize ) {
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ ctx->tp_nlimbs = 2 * vsize;
+ ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up )
+ || gcry_is_secure( vp ) );
+ ctx->tp_size = vsize;
+ }
+
+ do {
+ MPN_MUL_N_RECURSE( ctx->tp, up, vp, vsize, ctx->tspace );
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tp, vsize );
+ _gcry_mpih_add_1( prodp + vsize, ctx->tp + vsize, vsize, cy );
+ prodp += vsize;
+ up += vsize;
+ usize -= vsize;
+ } while( usize >= vsize );
+ }
+
+ if( usize ) {
+ if( usize < KARATSUBA_THRESHOLD ) {
+ _gcry_mpih_mul( ctx->tspace, vp, vsize, up, usize );
+ }
+ else {
+ if( !ctx->next ) {
+ ctx->next = gcry_xcalloc( 1, sizeof *ctx );
+ }
+ _gcry_mpih_mul_karatsuba_case( ctx->tspace,
+ vp, vsize,
+ up, usize,
+ ctx->next );
+ }
+
+ cy = _gcry_mpih_add_n( prodp, prodp, ctx->tspace, vsize);
+ _gcry_mpih_add_1( prodp + vsize, ctx->tspace + vsize, usize, cy );
+ }
+}
+
+
+void
+_gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
+{
+ struct karatsuba_ctx *ctx2;
+
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ for( ctx=ctx->next; ctx; ctx = ctx2 ) {
+ ctx2 = ctx->next;
+ if( ctx->tp )
+ _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
+ if( ctx->tspace )
+ _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
+ gcry_free( ctx );
+ }
+}
+
+/* Multiply the natural numbers u (pointed to by UP, with USIZE limbs)
+ * and v (pointed to by VP, with VSIZE limbs), and store the result at
+ * PRODP. USIZE + VSIZE limbs are always stored, but if the input
+ * operands are normalized. Return the most significant limb of the
+ * result.
+ *
+ * NOTE: The space pointed to by PRODP is overwritten before finished
+ * with U and V, so overlap is an error.
+ *
+ * Argument constraints:
+ * 1. USIZE >= VSIZE.
+ * 2. PRODP != UP and PRODP != VP, i.e. the destination
+ * must be distinct from the multiplier and the multiplicand.
+ */
+
+mpi_limb_t
+_gcry_mpih_mul( mpi_ptr_t prodp, mpi_ptr_t up, mpi_size_t usize,
+ mpi_ptr_t vp, mpi_size_t vsize)
+{
+ mpi_ptr_t prod_endp = prodp + usize + vsize - 1;
+ mpi_limb_t cy;
+ struct karatsuba_ctx ctx;
+
+ if( vsize < KARATSUBA_THRESHOLD ) {
+ mpi_size_t i;
+ mpi_limb_t v_limb;
+
+ if( !vsize )
+ return 0;
+
+ /* Multiply by the first limb in V separately, as the result can be
+ * stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ if( v_limb <= 1 ) {
+ if( v_limb == 1 )
+ MPN_COPY( prodp, up, usize );
+ else
+ MPN_ZERO( prodp, usize );
+ cy = 0;
+ }
+ else
+ cy = _gcry_mpih_mul_1( prodp, up, usize, v_limb );
+
+ prodp[usize] = cy;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ * U with one limb from V, and add it to PROD. */
+ for( i = 1; i < vsize; i++ ) {
+ v_limb = vp[i];
+ if( v_limb <= 1 ) {
+ cy = 0;
+ if( v_limb == 1 )
+ cy = _gcry_mpih_add_n(prodp, prodp, up, usize);
+ }
+ else
+ cy = _gcry_mpih_addmul_1(prodp, up, usize, v_limb);
+
+ prodp[usize] = cy;
+ prodp++;
+ }
+
+ return cy;
+ }
+
+ memset( &ctx, 0, sizeof ctx );
+ _gcry_mpih_mul_karatsuba_case( prodp, up, usize, vp, vsize, &ctx );
+ _gcry_mpih_release_karatsuba_ctx( &ctx );
+ return *prod_endp;
+}
--- /dev/null
+/* mpiutil.ac - Utility functions for MPI
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003,
+ * 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi-internal.h"
+#include "mod-source-info.h"
+
+
+const char *
+_gcry_mpi_get_hw_config (void)
+{
+ return mod_source_info + 1;
+}
+
+
+/****************
+ * Note: It was a bad idea to use the number of limbs to allocate
+ * because on a alpha the limbs are large but we normally need
+ * integers of n bits - So we should change this to bits (or bytes).
+ *
+ * But mpi_alloc is used in a lot of places :-(. New code
+ * should use mpi_new.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = gcry_xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
+ a->alloced = nlimbs;
+ a->nlimbs = 0;
+ a->sign = 0;
+ a->flags = 0;
+ return a;
+}
+
+void
+_gcry_mpi_m_check( gcry_mpi_t a )
+{
+ _gcry_check_heap(a);
+ _gcry_check_heap(a->d);
+}
+
+gcry_mpi_t
+_gcry_mpi_alloc_secure( unsigned nlimbs )
+{
+ gcry_mpi_t a;
+
+ a = gcry_xmalloc( sizeof *a );
+ a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
+ a->alloced = nlimbs;
+ a->flags = 1;
+ a->nlimbs = 0;
+ a->sign = 0;
+ return a;
+}
+
+
+
+mpi_ptr_t
+_gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
+{
+ mpi_ptr_t p;
+ size_t len;
+
+ len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
+ p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
+ if (! nlimbs)
+ *p = 0;
+
+ return p;
+}
+
+void
+_gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
+{
+ if (a)
+ {
+ size_t len = nlimbs * sizeof(mpi_limb_t);
+
+ /* If we have information on the number of allocated limbs, we
+ better wipe that space out. This is a failsafe feature if
+ secure memory has been disabled or was not properly
+ implemented in user provided allocation functions. */
+ if (len)
+ wipememory (a, len);
+ gcry_free(a);
+ }
+}
+
+
+void
+_gcry_mpi_assign_limb_space( gcry_mpi_t a, mpi_ptr_t ap, unsigned int nlimbs )
+{
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+ a->d = ap;
+ a->alloced = nlimbs;
+}
+
+
+
+/****************
+ * Resize the array of A to NLIMBS. The additional space is cleared
+ * (set to 0).
+ */
+void
+_gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
+{
+ size_t i;
+
+ if (nlimbs <= a->alloced)
+ {
+ /* We only need to clear the new space (this is a nop if the
+ limb space is already of the correct size. */
+ for (i=a->nlimbs; i < a->alloced; i++)
+ a->d[i] = 0;
+ return;
+ }
+
+ /* Actually resize the limb space. */
+ if (a->d)
+ {
+ a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+ for (i=a->alloced; i < nlimbs; i++)
+ a->d[i] = 0;
+ }
+ else
+ {
+ if (a->flags & 1)
+ /* Secure memory is wanted. */
+ a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
+ else
+ /* Standard memory. */
+ a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
+ }
+ a->alloced = nlimbs;
+}
+
+void
+_gcry_mpi_clear( gcry_mpi_t a )
+{
+ a->nlimbs = 0;
+ a->flags = 0;
+}
+
+
+void
+_gcry_mpi_free( gcry_mpi_t a )
+{
+ if (!a )
+ return;
+ if ((a->flags & 4))
+ gcry_free( a->d );
+ else
+ {
+ _gcry_mpi_free_limb_space(a->d, a->alloced);
+ }
+ if ((a->flags & ~7))
+ log_bug("invalid flag value in mpi\n");
+ gcry_free(a);
+}
+
+static void
+mpi_set_secure( gcry_mpi_t a )
+{
+ mpi_ptr_t ap, bp;
+
+ if ( (a->flags & 1) )
+ return;
+ a->flags |= 1;
+ ap = a->d;
+ if (!a->nlimbs)
+ {
+ gcry_assert (!ap);
+ return;
+ }
+ bp = mpi_alloc_limb_space (a->nlimbs, 1);
+ MPN_COPY( bp, ap, a->nlimbs );
+ a->d = bp;
+ _gcry_mpi_free_limb_space (ap, a->alloced);
+}
+
+
+gcry_mpi_t
+gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
+{
+ if (!a)
+ a = mpi_alloc(0);
+
+ if( a->flags & 4 )
+ gcry_free( a->d );
+ else
+ _gcry_mpi_free_limb_space (a->d, a->alloced);
+
+ a->d = p;
+ a->alloced = 0;
+ a->nlimbs = 0;
+ a->sign = nbits;
+ a->flags = 4;
+ return a;
+}
+
+
+void *
+gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
+{
+ if( !(a->flags & 4) )
+ log_bug("mpi_get_opaque on normal mpi\n");
+ if( nbits )
+ *nbits = a->sign;
+ return a->d;
+}
+
+
+/****************
+ * Note: This copy function should not interpret the MPI
+ * but copy it transparently.
+ */
+gcry_mpi_t
+gcry_mpi_copy( gcry_mpi_t a )
+{
+ int i;
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
+ : gcry_xmalloc( (a->sign+7)/8 );
+ memcpy( p, a->d, (a->sign+7)/8 );
+ b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = a->nlimbs;
+ b->sign = a->sign;
+ b->flags = a->flags;
+ for(i=0; i < b->nlimbs; i++ )
+ b->d[i] = a->d[i];
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+/****************
+ * This function allocates an MPI which is optimized to hold
+ * a value as large as the one given in the argument and allocates it
+ * with the same flags as A.
+ */
+gcry_mpi_t
+_gcry_mpi_alloc_like( gcry_mpi_t a )
+{
+ gcry_mpi_t b;
+
+ if( a && (a->flags & 4) ) {
+ int n = (a->sign+7)/8;
+ void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
+ : gcry_malloc( n );
+ memcpy( p, a->d, n );
+ b = gcry_mpi_set_opaque( NULL, p, a->sign );
+ }
+ else if( a ) {
+ b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
+ : mpi_alloc( a->nlimbs );
+ b->nlimbs = 0;
+ b->sign = 0;
+ b->flags = a->flags;
+ }
+ else
+ b = NULL;
+ return b;
+}
+
+
+gcry_mpi_t
+gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
+{
+ mpi_ptr_t wp, up;
+ mpi_size_t usize = u->nlimbs;
+ int usign = u->sign;
+
+ if (!w)
+ w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+ RESIZE_IF_NEEDED(w, usize);
+ wp = w->d;
+ up = u->d;
+ MPN_COPY( wp, up, usize );
+ w->nlimbs = usize;
+ w->flags = u->flags;
+ w->sign = usign;
+ return w;
+}
+
+
+gcry_mpi_t
+gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
+{
+ if (!w)
+ w = _gcry_mpi_alloc (1);
+ /* FIXME: If U is 0 we have no need to resize and thus possible
+ allocating the the limbs. */
+ RESIZE_IF_NEEDED(w, 1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ w->flags = 0;
+ return w;
+}
+
+gcry_err_code_t
+_gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ unsigned long x = 0;
+
+ if (w->nlimbs > 1)
+ err = GPG_ERR_TOO_LARGE;
+ else if (w->nlimbs == 1)
+ x = w->d[0];
+ else
+ x = 0;
+
+ if (! err)
+ *u = x;
+
+ return err;
+}
+
+gcry_error_t
+gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+
+ err = _gcry_mpi_get_ui (w, u);
+
+ return gcry_error (err);
+}
+
+gcry_mpi_t
+_gcry_mpi_alloc_set_ui( unsigned long u)
+{
+ gcry_mpi_t w = mpi_alloc(1);
+ w->d[0] = u;
+ w->nlimbs = u? 1:0;
+ w->sign = 0;
+ return w;
+}
+
+void
+gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
+{
+ struct gcry_mpi tmp;
+
+ tmp = *a; *a = *b; *b = tmp;
+}
+
+
+gcry_mpi_t
+gcry_mpi_new( unsigned int nbits )
+{
+ return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+
+gcry_mpi_t
+gcry_mpi_snew( unsigned int nbits )
+{
+ return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
+ / BITS_PER_MPI_LIMB );
+}
+
+void
+gcry_mpi_release( gcry_mpi_t a )
+{
+ _gcry_mpi_free( a );
+}
+
+void
+gcry_mpi_randomize( gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level )
+{
+ unsigned char *p;
+ size_t nbytes = (nbits+7)/8;
+
+ if (level == GCRY_WEAK_RANDOM)
+ {
+ p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
+ : gcry_xmalloc (nbytes);
+ gcry_create_nonce (p, nbytes);
+ }
+ else
+ {
+ p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
+ : gcry_random_bytes (nbytes, level);
+ }
+ _gcry_mpi_set_buffer( w, p, nbytes, 0 );
+ gcry_free (p);
+}
+
+
+void
+gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ switch( flag ) {
+ case GCRYMPI_FLAG_SECURE: mpi_set_secure(a); break;
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+void
+gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ (void)a; /* Not yet used. */
+
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE:
+ case GCRYMPI_FLAG_OPAQUE:
+ default: log_bug("invalid flag value\n");
+ }
+}
+
+int
+gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+{
+ switch (flag)
+ {
+ case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
+ case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
+ default: log_bug("invalid flag value\n");
+ }
+ /*NOTREACHED*/
+ return 0;
+}
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-lshift.S
+mpih-rshift.S
+$names$ iQCVAwUAP+LmVjEAnp832S/7AQKlEQQAv2+x/d+Z0t8FwwHlxKpIKOJDr9e+Y2i8y8orcIEa3dnwU5LMOH3EzFoNSD9crc31FMokgm/X5xeLjqRTdcmGHyJJQJDPJVJyuaOm6qHJaFzzfJjrfMW66nJxfNSXIiIm4DgpP20NmumaorLCkiIZ5Z81KGAc8FiRggbRVYx+wxo==Vjh9
--- /dev/null
+Manifest
+mpih-lshift.S
+mpih-rshift.S
+
--- /dev/null
+/* hppa lshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_lshift
+ .label _gcry_mpih_lshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ sh2add %r24,%r25,%r25
+ sh2add %r24,%r26,%r26
+ ldws,mb -4(0,%r25),%r22
+ subi 32,%r23,%r1
+ mtsar %r1
+ addib,= -1,%r24,L$0004
+ vshd %r0,%r22,%r28 ; compute carry out limb
+ ldws,mb -4(0,%r25),%r29
+ addib,<= -5,%r24,L$rest
+ vshd %r22,%r29,%r20
+
+ .label L$loop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -4,%r24,L$loop
+ vshd %r22,%r29,%r20
+
+ .label L$rest
+ addib,= 4,%r24,L$end1
+ nop
+ .label L$eloop
+ ldws,mb -4(0,%r25),%r22
+ stws,mb %r20,-4(0,%r26)
+ addib,<= -1,%r24,L$end2
+ vshd %r29,%r22,%r20
+ ldws,mb -4(0,%r25),%r29
+ stws,mb %r20,-4(0,%r26)
+ addib,> -1,%r24,L$eloop
+ vshd %r22,%r29,%r20
+
+ .label L$end1
+ stws,mb %r20,-4(0,%r26)
+ vshd %r29,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+ .label L$end2
+ stws,mb %r20,-4(0,%r26)
+ .label L$0004
+ vshd %r22,%r0,%r20
+ bv 0(%r2)
+ stw %r20,-4(0,%r26)
+
+ .exit
+ .procend
+
+
+
--- /dev/null
+/* hppa rshift
+ * optimized for the PA7100, where it runs at 3.25 cycles/limb
+ *
+ * Copyright (C) 1992, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (gr26)
+ * mpi_ptr_t up, (gr25)
+ * mpi_size_t usize, (gr24)
+ * unsigned cnt) (gr23)
+ */
+
+ .code
+ .export _gcry_mpih_rshift
+ .label _gcry_mpih_rshift
+ .proc
+ .callinfo frame=64,no_calls
+ .entry
+
+ ldws,ma 4(0,%r25),%r22
+ mtsar %r23
+ addib,= -1,%r24,L$r004
+ vshd %r22,%r0,%r28 ; compute carry out limb
+ ldws,ma 4(0,%r25),%r29
+ addib,<= -5,%r24,L$rrest
+ vshd %r29,%r22,%r20
+
+ .label L$roop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ vshd %r29,%r22,%r20
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -4,%r24,L$roop
+ vshd %r29,%r22,%r20
+
+ .label L$rrest
+ addib,= 4,%r24,L$rend1
+ nop
+ .label L$eroop
+ ldws,ma 4(0,%r25),%r22
+ stws,ma %r20,4(0,%r26)
+ addib,<= -1,%r24,L$rend2
+ vshd %r22,%r29,%r20
+ ldws,ma 4(0,%r25),%r29
+ stws,ma %r20,4(0,%r26)
+ addib,> -1,%r24,L$eroop
+ vshd %r29,%r22,%r20
+
+ .label L$rend1
+ stws,ma %r20,4(0,%r26)
+ vshd %r0,%r29,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+ .label L$rend2
+ stws,ma %r20,4(0,%r26)
+ .label L$r004
+ vshd %r0,%r22,%r20
+ bv 0(%r2)
+ stw %r20,0(0,%r26)
+
+ .exit
+ .procend
+
+
--- /dev/null
+Copyright 2001 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or (at your
+option) any later version.
+
+The GNU MP 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+
+
+
+ INTEL PENTIUM-4 MPN SUBROUTINES
+
+
+This directory contains mpn functions optimized for Intel Pentium-4.
+
+The mmx subdirectory has routines using MMX instructions, the sse2
+subdirectory has routines using SSE2 instructions. All P4s have these, the
+separate directories are just so configure can omit that code if the
+assembler doesn't support it.
+
+
+STATUS
+
+ cycles/limb
+
+ mpn_add_n/sub_n 4 normal, 6 in-place
+
+ mpn_mul_1 4 normal, 6 in-place
+ mpn_addmul_1 6
+ mpn_submul_1 7
+
+ mpn_mul_basecase 6 cycles/crossproduct (approx)
+
+ mpn_sqr_basecase 3.5 cycles/crossproduct (approx)
+ or 7.0 cycles/triangleproduct (approx)
+
+ mpn_l/rshift 1.75
+
+
+
+The shifts ought to be able to go at 1.5 c/l, but not much effort has been
+applied to them yet.
+
+In-place operations, and all addmul, submul, mul_basecase and sqr_basecase
+calls, suffer from pipeline anomalies associated with write combining and
+movd reads and writes to the same or nearby locations. The movq
+instructions do not trigger the same hardware problems. Unfortunately,
+using movq and splitting/combining seems to require too many extra
+instructions to help. Perhaps future chip steppings will be better.
+
+
+
+NOTES
+
+The Pentium-4 pipeline "Netburst", provides for quite a number of surprises.
+Many traditional x86 instructions run very slowly, requiring use of
+alterative instructions for acceptable performance.
+
+adcl and sbbl are quite slow at 8 cycles for reg->reg. paddq of 32-bits
+within a 64-bit mmx register seems better, though the combination
+paddq/psrlq when propagating a carry is still a 4 cycle latency.
+
+incl and decl should be avoided, instead use add $1 and sub $1. Apparently
+the carry flag is not separately renamed, so incl and decl depend on all
+previous flags-setting instructions.
+
+shll and shrl have a 4 cycle latency, or 8 times the latency of the fastest
+integer instructions (addl, subl, orl, andl, and some more). shldl and
+shrdl seem to have 13 and 15 cycles latency, respectively. Bizarre.
+
+movq mmx -> mmx does have 6 cycle latency, as noted in the documentation.
+pxor/por or similar combination at 2 cycles latency can be used instead.
+The movq however executes in the float unit, thereby saving MMX execution
+resources. With the right juggling, data moves shouldn't be on a dependent
+chain.
+
+L1 is write-through, but the write-combining sounds like it does enough to
+not require explicit destination prefetching.
+
+xmm registers so far haven't found a use, but not much effort has been
+expended. A configure test for whether the operating system knows
+fxsave/fxrestor will be needed if they're used.
+
+
+
+REFERENCES
+
+Intel Pentium-4 processor manuals,
+
+ http://developer.intel.com/design/pentium4/manuals
+
+"Intel Pentium 4 Processor Optimization Reference Manual", Intel, 2001,
+order number 248966. Available on-line:
+
+ http://developer.intel.com/design/pentium4/manuals/248966.htm
+
+
+
+----------------
+Local variables:
+mode: text
+fill-column: 76
+End:
--- /dev/null
+README
+
+
--- /dev/null
+mpih-lshift.S
+mpih-rshift.S
--- /dev/null
+/* Intel Pentium-4 mpn_lshift -- left shift.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift:)
+
+
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ movl -4(%ebx,%eax,4), %edi
+ decl %eax
+
+ jnz .Lsimple
+
+ shldl %cl, %edi, %eax
+
+ shll %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx,%eax,4), %mm5
+
+ movd %ecx, %mm6
+ negl %ecx
+
+ psllq %mm6, %mm5
+ addl $32, %ecx
+
+ movd %ecx, %mm7
+ psrlq $32, %mm5
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -4(%ebx,%eax,4), %mm0
+ decl %eax
+
+ psrlq %mm7, %mm0
+
+
+
+ movd %mm0, 4(%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+
+ movd %mm5, %eax
+ psllq %mm6, %mm0
+
+ popl %edi
+ popl %ebx
+
+ movd %mm0, (%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd -4(%ebx,%eax,4), %mm5
+ leal (%ebx,%eax,4), %edi
+
+ movd %ecx, %mm6
+ andl $4, %edi
+
+ psllq %mm6, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq -8(%ebx,%eax,4), %mm0
+
+ psllq %mm6, %mm0
+ decl %eax
+
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, (%edx,%eax,4)
+.Lstart_src_aligned:
+
+ movq -8(%ebx,%eax,4), %mm1
+ leal (%edx,%eax,4), %edi
+
+ andl $4, %edi
+ psrlq $32, %mm5
+
+ movq -16(%ebx,%eax,4), %mm3
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psllq %mm6, %mm0
+
+ movd %ecx, %mm6
+ psrlq $32, %mm0
+
+
+
+ movd %mm0, -4(%edx,%eax,4)
+ subl $4, %edx
+.Lstart_dst_aligned:
+
+
+ psllq %mm6, %mm1
+ negl %ecx
+
+ addl $64, %ecx
+ movq %mm3, %mm2
+
+ movd %ecx, %mm7
+ subl $8, %eax
+
+ psrlq %mm7, %mm3
+
+ por %mm1, %mm3
+ jc .Lfinish
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq (%ebx,%eax,4), %mm3
+ psllq %mm6, %mm1
+
+ movq %mm0, 16(%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psrlq %mm7, %mm3
+ subl $4, %eax
+
+ por %mm1, %mm3
+ jnc .Lunroll_loop
+
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jz .Lfinish_no_two
+
+ movq 8(%ebx,%eax,4), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ movq %mm3, 24(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ subl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ movd %mm5, %eax
+
+ popl %edi
+ jz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm0
+ psllq %mm6, %mm2
+
+ movq %mm3, 12(%edx)
+ psllq $32, %mm0
+
+ movq %mm0, %mm1
+ psrlq %mm7, %mm0
+
+ por %mm2, %mm0
+ psllq %mm6, %mm1
+
+ movq %mm0, 4(%edx)
+ psrlq $32, %mm1
+
+ andl $32, %ecx
+ popl %ebx
+
+ jz .Lfinish_one_unaligned
+
+ movd %mm1, (%edx)
+.Lfinish_one_unaligned:
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 8(%edx)
+ andl $32, %ecx
+
+ psllq %mm6, %mm2
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, (%edx)
+.Lfinish_zero_unaligned:
+
+ psrlq $32, %mm2
+ popl %ebx
+
+ movd %mm5, %eax
+
+ movd %mm2, 4(%edx)
+
+ emms
+
+ ret
--- /dev/null
+/* Intel Pentium-4 mpn_rshift -- right shift.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (sp + 4)
+ * mpi_ptr_t up, (sp + 8)
+ * mpi_size_t usize, (sp + 12)
+ * unsigned cnt) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 1.75 cycles/limb
+ * P4 Prescott: 2.0 cycles/limb
+ */
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift:)
+ pushl %ebx
+ pushl %edi
+
+
+ movl 20(%esp), %eax
+ movl 12(%esp), %edx
+
+ movl 16(%esp), %ebx
+ movl 24(%esp), %ecx
+
+ cmp $5, %eax
+ jae .Lunroll
+
+ decl %eax
+ movl (%ebx), %edi
+
+ jnz .Lsimple
+
+ shrdl %cl, %edi, %eax
+
+ shrl %cl, %edi
+
+ movl %edi, (%edx)
+ popl %edi
+
+ popl %ebx
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lsimple:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ leal (%ebx,%eax,4), %ebx
+
+ movd %ecx, %mm6
+ leal -4(%edx,%eax,4), %edx
+
+ psllq $32, %mm5
+ negl %eax
+
+
+
+
+
+
+
+.Lsimple_top:
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ incl %eax
+
+ psrlq %mm6, %mm0
+
+ movd %mm0, (%edx,%eax,4)
+ jnz .Lsimple_top
+
+
+ movd (%ebx), %mm0
+ psrlq %mm6, %mm5
+
+ psrlq %mm6, %mm0
+ popl %edi
+
+ movd %mm5, %eax
+ popl %ebx
+
+ movd %mm0, 4(%edx)
+
+ emms
+
+ ret
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll:
+
+
+
+
+
+
+
+
+
+ movd (%ebx), %mm5
+ movl $4, %edi
+
+ movd %ecx, %mm6
+ testl %edi, %ebx
+
+ psllq $32, %mm5
+ jz .Lstart_src_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx), %mm0
+
+ psrlq %mm6, %mm0
+ addl $4, %ebx
+
+ decl %eax
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_src_aligned:
+
+
+ movq (%ebx), %mm1
+ testl %edi, %edx
+
+ psrlq %mm6, %mm5
+ jz .Lstart_dst_aligned
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm1, %mm0
+ addl $32, %ecx
+
+ psrlq %mm6, %mm0
+
+ movd %ecx, %mm6
+
+ movd %mm0, (%edx)
+ addl $4, %edx
+.Lstart_dst_aligned:
+
+
+ movq 8(%ebx), %mm3
+ negl %ecx
+
+ movq %mm3, %mm2
+ addl $64, %ecx
+
+ movd %ecx, %mm7
+ psrlq %mm6, %mm1
+
+ leal -12(%ebx,%eax,4), %ebx
+ leal -20(%edx,%eax,4), %edx
+
+ psllq %mm7, %mm3
+ subl $7, %eax
+
+ por %mm1, %mm3
+ negl %eax
+
+ jns .Lfinish
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .align 8, 0x90
+.Lunroll_loop:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq 8(%ebx,%eax,4), %mm3
+ psrlq %mm6, %mm1
+
+ movq %mm0, (%edx,%eax,4)
+ movq %mm3, %mm2
+
+ psllq %mm7, %mm3
+ addl $4, %eax
+
+ por %mm1, %mm3
+ js .Lunroll_loop
+
+
+.Lfinish:
+
+
+ testb $2, %al
+
+ jnz .Lfinish_no_two
+
+ movq (%ebx,%eax,4), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, -8(%edx,%eax,4)
+ por %mm2, %mm0
+
+ movq %mm1, %mm2
+ movq %mm0, %mm3
+
+ addl $2, %eax
+.Lfinish_no_two:
+
+
+
+
+
+
+
+ testb $1, %al
+ popl %edi
+
+ movd %mm5, %eax
+ jnz .Lfinish_zero
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movd 8(%ebx), %mm0
+ psrlq %mm6, %mm2
+
+ movq %mm0, %mm1
+ psllq %mm7, %mm0
+
+ movq %mm3, (%edx)
+ por %mm2, %mm0
+
+ psrlq %mm6, %mm1
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_one_unaligned
+
+
+ movd %mm1, 16(%edx)
+.Lfinish_one_unaligned:
+
+ movq %mm0, 8(%edx)
+
+ emms
+
+ ret
+
+
+
+
+.Lfinish_zero:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ movq %mm3, 4(%edx)
+ psrlq %mm6, %mm2
+
+ movd %mm2, 12(%edx)
+ andl $32, %ecx
+
+ popl %ebx
+ jz .Lfinish_zero_unaligned
+
+ movq %mm2, 12(%edx)
+.Lfinish_zero_unaligned:
+
+ emms
+
+ ret
--- /dev/null
+mpih-add1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-sub1.S
--- /dev/null
+/* Intel Pentium-4 mpn_add_n -- mpn addition.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+ /*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The 4 c/l achieved here isn't particularly good, but is better than 9 c/l
+ * for a basic adc loop.
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n:)
+
+ pxor %mm0, %mm0
+
+ movl 8(%esp), %eax /* s1_ptr */
+ movl %ebx, 8(%esp) /* re-use parameter space */
+ movl 12(%esp), %ebx /* res_ptr */
+ movl 4(%esp), %edx /* s2_ptr */
+ movl 16(%esp), %ecx /* size */
+
+ leal (%eax,%ecx,4), %eax /* src1 end */
+ leal (%ebx,%ecx,4), %ebx /* src2 end */
+ leal (%edx,%ecx,4), %edx /* dst end */
+ negl %ecx /* -size */
+
+Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ paddq %mm2, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $32, %mm0
+
+ addl $1, %ecx
+ jnz Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx /* restore saved EBX */
+ emms
+ ret
--- /dev/null
+/* Intel Pentium-4 mpn_mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * src != dst src == dst
+ * P6 model 9 (Banias) ?.?
+ * P6 model 13 (Dothan) 4.75 4.75
+ * P4 model 0 (Willamette) 4.0 6.0
+ * P4 model 1 (?) 4.0 6.0
+ * P4 model 2 (Northwood) 4.0 6.0
+ * P4 model 3 (Prescott) ?.? ?.?
+ * P4 model 4 (Nocona) ?.? ?.?
+ * Unfortunately when src==dst the write-combining described in
+ * pentium4/README takes us up to 6 c/l.
+ *
+ */
+
+ TEXT
+ ALIGN (3)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1:);
+
+ pxor %mm0, %mm0
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movd 16(%esp), %mm7
+ movl 4(%esp), %edx
+ movl 12(%esp), %ecx
+
+.Ltop:
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx counter, size iterations
+ C edx dst, incrementing
+ C
+ C mm0 carry limb
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm1
+ addl $4, %eax
+ pmuludq %mm7, %mm1
+
+ paddq %mm1, %mm0
+ movd %mm0, (%edx)
+ addl $4, %edx
+
+ psrlq $32, %mm0
+
+ subl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ emms
+ ret
+
--- /dev/null
+/* Intel Pentium-4 mpn_addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P3 model 9 (Banias) ?.?
+ * P3 model 13 (Dothan) 5.8
+ * P4 model 0 (Willamette) 5.5
+ * P4 model 1 (?) 5.5
+ * P4 model 2 (Northwood) 5.5
+ * P4 model 3 (Prescott) 6.0
+ * P4 model 4 (Nocona)
+ *
+ * Only the carry limb propagation is on the dependent chain, but some other
+ * Pentium4 pipeline magic brings down performance to 6 cycles/l from the
+ * ideal 4 cycles/l.
+ */
+
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1:)
+
+ pxor %mm4, %mm4
+.Lstart_1c:
+ movl 8(%esp), %eax
+ movl 12(%esp), %ecx
+ movl 4(%esp), %edx
+ movd 16(%esp), %mm7
+
+/*
+ C eax src, incrementing ; 5B
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm4 carry, low 32-bits
+ C mm7 multiplier
+*/
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+
+ shrl $1, %ecx
+ jnc .Leven
+
+ leal 4(%eax), %eax
+ movd (%edx), %mm1
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ testl %ecx, %ecx
+ jz .Lrtn
+ leal 4(%edx), %edx
+
+ movd (%eax), %mm2
+ pmuludq %mm7, %mm2
+.Leven:
+ movd 4(%eax), %mm0
+ movd (%edx), %mm1
+ pmuludq %mm7, %mm0
+
+ subl $1, %ecx
+ jz .Lend
+.Lloop:
+ paddq %mm2, %mm1
+ movd 8(%eax), %mm2
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ pmuludq %mm7, %mm2
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+
+ paddq %mm0, %mm3
+ movd 12(%eax), %mm0
+ paddq %mm3, %mm4
+ movd 8(%edx), %mm1
+ pmuludq %mm7, %mm0
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+
+ leal 8(%eax), %eax
+ leal 8(%edx), %edx
+ subl $1, %ecx
+ jnz .Lloop
+.Lend:
+ paddq %mm2, %mm1
+ paddq %mm1, %mm4
+ movd 4(%edx), %mm3
+ movd %mm4, (%edx)
+ psrlq $32, %mm4
+ paddq %mm0, %mm3
+ paddq %mm3, %mm4
+ movd %mm4, 4(%edx)
+ psrlq $32, %mm4
+.Lrtn:
+ movd %mm4, %eax
+ emms
+ ret
--- /dev/null
+/* Intel Pentium-4 mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_size_t s1_size, (sp + 12)
+ * mpi_limb_t s2_limb) (sp + 16)
+ *
+ * P4: 7 cycles/limb, unstable timing, at least on early Pentium4 silicon
+ * (stepping 10).
+ *
+ * This code is not particularly good at 7 c/l. The dependent chain is only
+ * 4 c/l and there's only 4 MMX unit instructions, so it's not clear why that
+ * speed isn't achieved.
+ *
+ * The arrangements made here to get a two instruction dependent chain are
+ * slightly subtle. In the loop the carry (or borrow rather) is a negative
+ * so that a paddq can be used to give a low limb ready to store, and a high
+ * limb ready to become the new carry after a psrlq.
+ *
+ * If the carry was a simple twos complement negative then the psrlq shift
+ * would need to bring in 0 bits or 1 bits according to whether the high was
+ * zero or non-zero, since a non-zero value would represent a negative
+ * needing sign extension. That wouldn't be particularly easy to arrange and
+ * certainly would add an instruction to the dependent chain, so instead an
+ * offset is applied so that the high limb will be 0xFFFFFFFF+c. With c in
+ * the range -0xFFFFFFFF to 0, the value 0xFFFFFFFF+c is in the range 0 to
+ * 0xFFFFFFFF and is therefore always positive and can always have 0 bits
+ * shifted in, which is what psrlq does.
+ *
+ * The extra 0xFFFFFFFF must be subtracted before c is used, but that can be
+ * done off the dependent chain. The total adjustment then is to add
+ * 0xFFFFFFFF00000000 to offset the new carry, and subtract
+ * 0x00000000FFFFFFFF to remove the offset from the current carry, for a net
+ * add of 0xFFFFFFFE00000001. In the code this is applied to the destination
+ * limb when fetched.
+ *
+ * It's also possible to view the 0xFFFFFFFF adjustment as a ones-complement
+ * negative, which is how it's undone for the return value, but that doesn't
+ * seem as clear.
+*/
+
+ TEXT
+ ALIGN (4)
+ GLOBL C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1:)
+
+ pxor %mm1, %mm1
+
+.Lstart_1c:
+ movl 8(%esp), %eax
+ pcmpeqd %mm0, %mm0
+
+ movd 16(%esp), %mm7
+ pcmpeqd %mm6, %mm6
+
+ movl 4(%esp), %edx
+ psrlq $32, %mm0
+
+ movl 12(%esp), %ecx
+ psllq $32, %mm6
+
+ psubq %mm0, %mm6
+
+ psubq %mm1, %mm0
+
+/*
+ C eax src, incrementing
+ C ebx
+ C ecx loop counter, decrementing
+ C edx dst, incrementing
+ C
+ C mm0 0xFFFFFFFF - borrow
+ C mm6 0xFFFFFFFE00000001
+ C mm7 multiplier
+*/
+
+.Lloop:
+ movd (%eax), %mm1
+ leal 4(%eax), %eax
+ movd (%edx), %mm2
+ paddq %mm6, %mm2
+ pmuludq %mm7, %mm1
+ psubq %mm1, %mm2
+ paddq %mm2, %mm0
+ subl $1, %ecx
+ movd %mm0, (%edx)
+ psrlq $32, %mm0
+ leal 4(%edx), %edx
+ jnz .Lloop
+
+ movd %mm0, %eax
+ notl %eax
+ emms
+ ret
--- /dev/null
+/* Intel Pentium-4 mpn_sub_n -- mpn subtraction.
+ *
+ * Copyright 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (sp + 4)
+ * mpi_ptr_t s1_ptr, (sp + 8)
+ * mpi_ptr_t s2_ptr, (sp + 12)
+ * mpi_size_t size) (sp + 16)
+ *
+ * P4 Willamette, Northwood: 4.0 cycles/limb if dst!=src1 and dst!=src2
+ * 6.0 cycles/limb if dst==src1 or dst==src2
+ * P4 Prescott: >= 5 cycles/limb
+ *
+ * The main loop code is 2x unrolled so that the carry bit can alternate
+ * between mm0 and mm1.
+ */
+
+
+.text
+ ALIGN (3)
+ .globl C_SYMBOL_NAME(_gcry_mpih_sub_n)
+C_SYMBOL_NAME(_gcry_mpih_sub_n:)
+
+ pxor %mm0, %mm0
+.Lstart_nc:
+ movl 8(%esp), %eax
+ movl %ebx, 8(%esp)
+ movl 12(%esp), %ebx
+ movl 4(%esp), %edx
+ movl 16(%esp), %ecx
+
+ leal (%eax,%ecx,4), %eax
+ leal (%ebx,%ecx,4), %ebx
+ leal (%edx,%ecx,4), %edx
+ negl %ecx
+
+.Ltop:
+/*
+ C eax src1 end
+ C ebx src2 end
+ C ecx counter, limbs, negative
+ C edx dst end
+ C mm0 carry bit
+*/
+
+ movd (%eax,%ecx,4), %mm1
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm1
+
+ psubq %mm0, %mm1
+ movd %mm1, (%edx,%ecx,4)
+
+ psrlq $63, %mm1
+
+ addl $1, %ecx
+ jz .Ldone_mm1
+
+ movd (%eax,%ecx,4), %mm0
+ movd (%ebx,%ecx,4), %mm2
+ psubq %mm2, %mm0
+
+ psubq %mm1, %mm0
+ movd %mm0, (%edx,%ecx,4)
+
+ psrlq $63, %mm0
+
+ addl $1, %ecx
+ jnz .Ltop
+
+
+ movd %mm0, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
+
+
+
+.Ldone_mm1:
+ movd %mm1, %eax
+ movl 8(%esp), %ebx
+ emms
+ ret
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
+$names$ iQCVAwUAP+LmXTEAnp832S/7AQJ+ngP/XYr5Fvl/8WGVHcIKaehxvnKcSD2ILTWZNGubgnWp8ebIxVijjQCxYneTTy+zO0sNaB002neyscyiwaJj/JQIwZXfr06uGweIqlSpwpj9ndkoJc8E4/FZu+5NTO+E3RaBDAD+Tpo+MTfbC1s18p5i+an93VrSTgNck5PPYQrUcPA==sl3t
--- /dev/null
+Manifest
+mpih-add1.S
+mpih-lshift.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-rshift.S
+mpih-sub1.S
--- /dev/null
+/* IBM POWER add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1996, 1999,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ a 7,0,8 # add least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ aze 3,10 # use the fact that r10 is zero...
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ ae 7,0,8 # add limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ ae 11,9,10 # add previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ ae 7,0,8 # add previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: ae 11,9,10 # add limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ lil 3,0 # load cy into ...
+ aze 3,3 # ... return value register
+ br
+
--- /dev/null
+/* IBM POWER lshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+ */
+
+ .toc
+ .extern _gcry_mpih_lshift[DS]
+ .extern ._gcry_mpih_lshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_lshift:
+ sli 0,5,2
+ cax 9,3,0
+ cax 4,4,0
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ lu 0,-4(4) # read most significant limb
+ sre 3,0,8 # compute carry out limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,-4(4) # read 2:nd most significant limb
+ sreq 7,0,8 # compute most significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,-4(4) # load next lower limb
+ stu 7,-4(9) # store previous result during read latency
+ sreq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,-4(9) # store 2:nd least significant limb
+Lend2: sle 7,0,6 # compute least significant limb
+ st 7,-4(9) # store it
+ br
+
--- /dev/null
+/* IBM POWER mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ ai 0,0,0 # reset carry
+ cax 9,9,7
+ blt Lneg
+Lpos: bdz Lend
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ cax 10,10,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,9
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ cax 9,9,0 # adjust high limb for negative s2_limb
+ mfmq 0
+ ae 8,0,10
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
--- /dev/null
+/* IBM POWER addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 8
+ cax 9,9,7
+ l 7,4(3)
+ a 8,8,7 # add res_limb
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 8,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 8,0,10
+ l 7,4(3)
+ aze 9,9
+ a 8,8,7
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 8,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 8,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ a 8,8,7 # add res_limb
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
--- /dev/null
+/* IBM POWER submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# size r5
+# s2_limb r6
+
+# The RS/6000 has no unsigned 32x32->64 bit multiplication instruction. To
+# obtain that operation, we have to use the 32x32->64 signed multiplication
+# instruction, and add the appropriate compensation to the high limb of the
+# result. We add the multiplicand if the multiplier has its most significant
+# bit set, and we add the multiplier if the multiplicand has its most
+# significant bit set. We need to preserve the carry flag between each
+# iteration, so we have to compute the compensation carefully (the natural,
+# srai+and doesn't work). Since the POWER architecture has a branch unit
+# we can branch in zero cycles, so that's how we perform the additions.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+
+ cal 3,-4(3)
+ l 0,0(4)
+ cmpi 0,6,0
+ mtctr 5
+ mul 9,0,6
+ srai 7,0,31
+ and 7,7,6
+ mfmq 11
+ cax 9,9,7
+ l 7,4(3)
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ blt Lneg
+Lpos: bdz Lend
+
+Lploop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 0
+ ae 11,0,9 # low limb + old_cy_limb + old cy
+ l 7,4(3)
+ aze 10,10 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Lp0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 0
+ ae 11,0,10
+ l 7,4(3)
+ aze 9,9
+ sf 8,11,7
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Lp1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Lp1: bdn Lploop
+
+ b Lend
+
+Lneg: cax 9,9,0
+ bdz Lend
+Lnloop: lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 10,0,6
+ mfmq 7
+ ae 11,7,9
+ l 7,4(3)
+ ae 10,10,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln0
+ cax 10,10,6 # adjust high limb for negative limb from s1
+Ln0: bdz Lend0
+ lu 0,4(4)
+ stu 8,4(3)
+ cmpi 0,0,0
+ mul 9,0,6
+ mfmq 7
+ ae 11,7,10
+ l 7,4(3)
+ ae 9,9,0 # propagate cy to new cy_limb
+ sf 8,11,7 # add res_limb
+ a 11,8,11 # invert cy (r11 is junk)
+ bge Ln1
+ cax 9,9,6 # adjust high limb for negative limb from s1
+Ln1: bdn Lnloop
+ b Lend
+
+Lend0: cal 9,0(10)
+Lend: st 8,4(3)
+ aze 3,9
+ br
+
--- /dev/null
+/* IBM POWER rshift
+ *
+ * Copyright (C) 1992, 1994, 1999, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s_ptr r4
+# size r5
+# cnt r6
+*/
+
+ .toc
+ .extern _gcry_mpih_rshift[DS]
+ .extern ._gcry_mpih_rshift
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_rshift:
+ sfi 8,6,32
+ mtctr 5 # put limb count in CTR loop register
+ l 0,0(4) # read least significant limb
+ ai 9,3,-4 # adjust res_ptr since it's offset in the stu:s
+ sle 3,0,8 # compute carry limb, and init MQ register
+ bdz Lend2 # if just one limb, skip loop
+ lu 0,4(4) # read 2:nd least significant limb
+ sleq 7,0,8 # compute least significant limb of result
+ bdz Lend # if just two limb, skip loop
+Loop: lu 0,4(4) # load next higher limb
+ stu 7,4(9) # store previous result during read latency
+ sleq 7,0,8 # compute result limb
+ bdn Loop # loop back until CTR is zero
+Lend: stu 7,4(9) # store 2:nd most significant limb
+Lend2: sre 7,0,6 # compute most significant limb
+ st 7,4(9) # store it
+ br
+
+
--- /dev/null
+/* IBM POWER sub_n -- Subtract two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1996, 1999,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+/*
+# INPUT PARAMETERS
+# res_ptr r3
+# s1_ptr r4
+# s2_ptr r5
+# size r6
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ andil. 10,6,1 # odd or even number of limbs?
+ l 8,0(4) # load least significant s1 limb
+ l 0,0(5) # load least significant s2 limb
+ cal 3,-4(3) # offset res_ptr, it's updated before it's used
+ sri 10,6,1 # count for unrolled loop
+ sf 7,0,8 # subtract least significant limbs, set cy
+ mtctr 10 # copy count into CTR
+ beq 0,Leven # branch if even # of limbs (# of limbs >= 2)
+
+# We have an odd # of limbs. Add the first limbs separately.
+ cmpi 1,10,0 # is count for unrolled loop zero?
+ bne 1,L1 # branch if not
+ st 7,4(3)
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br # return
+
+# We added least significant limbs. Now reload the next limbs to enter loop.
+L1: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ stu 7,4(3)
+ sfe 7,0,8 # subtract limbs, set cy
+Leven: lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ bdz Lend # If done, skip loop
+
+Loop: lu 8,4(4) # load s1 limb and update s1_ptr
+ lu 0,4(5) # load s2 limb and update s2_ptr
+ sfe 11,10,9 # subtract previous limbs with cy, set cy
+ stu 7,4(3) #
+ lu 9,4(4) # load s1 limb and update s1_ptr
+ lu 10,4(5) # load s2 limb and update s2_ptr
+ sfe 7,0,8 # subtract previous limbs with cy, set cy
+ stu 11,4(3) #
+ bdn Loop # decrement CTR and loop back
+
+Lend: sfe 11,10,9 # subtract limbs with cy, set cy
+ st 7,4(3) #
+ st 11,8(3) #
+ sfe 3,0,0 # load !cy into ...
+ sfi 3,3,0 # ... return value register
+ br
+
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+syntax.h
+$names$ iQCVAwUAP+LmYzEAnp832S/7AQI/cQP+Mcg9rF/c/bJTY48PE1/ARt7vCMtpIlv9alZSSSrU3WHzCtv9nVczFmwHU3DdKFawigY2DljQcK92dZ5ZlOfpFNMz4PKlVMWaKDk+jKlqm2dxvlHuqEvXPpjFAE2gHrhq5qLXS5ZHeMLJIEK84GYC6fjfLUMdZU3altXTUBvoXhA==Yax+
--- /dev/null
+Manifest
+mpih-add1.S
+mpih-sub1.S
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+mpih-lshift.S
+mpih-rshift.S
+syntax.h
+
--- /dev/null
+/* PowerPC-32 add_n -- Add two limb vectors of equal, non-zero length.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_add_n[DS]
+ .extern ._gcry_mpih_add_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_add_n
+ .globl ._gcry_mpih_add_n
+ .csect _gcry_mpih_add_n[DS]
+_gcry_mpih_add_n:
+ .long ._gcry_mpih_add_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_add_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ addc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ adde 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ li 3,0 # load cy into ...
+ addze 3,3 # ... return value register
+ blr
+
+#else
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 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 "sysdep.h"
+#include "asm-syntax.h"
+
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_add_n,3,0)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ li %r10,0
+ mtctr %r7
+ bt 31,2f
+
+/* Clear the carry. */
+ addic %r0,%r0,0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ addc %r6,%r6,%r7
+ stw %r6,0(%r3)
+ beq 1f
+
+/* The loop. */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). */
+0: lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ adde %r8,%r9,%r8
+ stw %r8,4(%r3)
+ adde %r6,%r6,%r7
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the carry. */
+1: addze %r3,%r10
+ blr
+END(_gcry_mpih_add_n)
+#endif
+
--- /dev/null
+/* PowerPC-32 lshift
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_lshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_lshift
+ .globl ._gcry_mpih_lshift
+ .csect _gcry_mpih_lshift[DS]
+_gcry_mpih_lshift:
+ .long ._gcry_mpih_lshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_lshift:
+ mtctr 5 # copy size into CTR
+ slwi 0,5,2
+ add 7,3,0 # make r7 point at end of res
+ add 4,4,0 # make r4 point at end of s1
+ subfic 8,6,32
+ lwzu 11,-4(4) # load first s1 limb
+ srw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,-4(4)
+ slw 9,11,6
+ srw 12,10,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdz Lend2
+ lwzu 11,-4(4)
+ slw 9,10,6
+ srw 12,11,8
+ or 9,9,12
+ stwu 9,-4(7)
+ bdnz Loop
+
+Lend1: slw 0,11,6
+ stw 0,-4(7)
+ blr
+
+Lend2: slw 0,10,6
+ stw 0,-4(7)
+ blr
+
+#else
+/* Shift a limb left, low level routine.
+ Copyright (C) 1996, 1997 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. */
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+ unsigned int cnt) */
+
+EALIGN(_gcry_mpih_lshift,3,0)
+ mtctr %r5 # copy size into CTR
+ cmplwi %cr0,%r5,16 # is size < 16
+ slwi %r0,%r5,2
+ add %r7,%r3,%r0 # make r7 point at end of res
+ add %r4,%r4,%r0 # make r4 point at end of s1
+ lwzu %r11,-4(%r4) # load first s1 limb
+ subfic %r8,%r6,32
+ srw %r3,%r11,%r8 # compute function return value
+ bge %cr0,L(big) # branch if size >= 16
+
+ bdz L(end1)
+
+0: lwzu %r10,-4(%r4)
+ slw %r9,%r11,%r6
+ srw %r12,%r10,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdz L(end2)
+ lwzu %r11,-4(%r4)
+ slw %r9,%r10,%r6
+ srw %r12,%r11,%r8
+ or %r9,%r9,%r12
+ stwu %r9,-4(%r7)
+ bdnz 0b
+
+L(end1):slw %r0,%r11,%r6
+ stw %r0,-4(%r7)
+ blr
+
+
+/* Guaranteed not to succeed. */
+L(boom): tweq %r0,%r0
+
+/* We imitate a case statement, by using (yuk!) fixed-length code chunks,
+ of size 4*12 bytes. We have to do this (or something) to make this PIC. */
+L(big): mflr %r9
+ bltl- %cr0,L(boom) # Never taken, only used to set LR.
+ slwi %r10,%r6,4
+ mflr %r12
+ add %r10,%r12,%r10
+ slwi %r8,%r6,5
+ add %r10,%r8,%r10
+ mtctr %r10
+ addi %r5,%r5,-1
+ mtlr %r9
+ bctr
+
+L(end2):slw %r0,%r10,%r6
+ stw %r0,-4(%r7)
+ blr
+
+#define DO_LSHIFT(n) \
+ mtctr %r5; \
+0: lwzu %r10,-4(%r4); \
+ slwi %r9,%r11,n; \
+ inslwi %r9,%r10,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdz- L(end2); \
+ lwzu %r11,-4(%r4); \
+ slwi %r9,%r10,n; \
+ inslwi %r9,%r11,n,32-n; \
+ stwu %r9,-4(%r7); \
+ bdnz 0b; \
+ b L(end1)
+
+ DO_LSHIFT(1)
+ DO_LSHIFT(2)
+ DO_LSHIFT(3)
+ DO_LSHIFT(4)
+ DO_LSHIFT(5)
+ DO_LSHIFT(6)
+ DO_LSHIFT(7)
+ DO_LSHIFT(8)
+ DO_LSHIFT(9)
+ DO_LSHIFT(10)
+ DO_LSHIFT(11)
+ DO_LSHIFT(12)
+ DO_LSHIFT(13)
+ DO_LSHIFT(14)
+ DO_LSHIFT(15)
+ DO_LSHIFT(16)
+ DO_LSHIFT(17)
+ DO_LSHIFT(18)
+ DO_LSHIFT(19)
+ DO_LSHIFT(20)
+ DO_LSHIFT(21)
+ DO_LSHIFT(22)
+ DO_LSHIFT(23)
+ DO_LSHIFT(24)
+ DO_LSHIFT(25)
+ DO_LSHIFT(26)
+ DO_LSHIFT(27)
+ DO_LSHIFT(28)
+ DO_LSHIFT(29)
+ DO_LSHIFT(30)
+ DO_LSHIFT(31)
+
+END(_gcry_mpih_lshift)
+#endif
--- /dev/null
+/* PowerPC-32 mul_1 -- Multiply a limb vector with a limb and store
+ * the result in a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995,
+ * 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_mul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_mul_1[PR]
+ .align 2
+ .globl _gcry_mpih_mul_1
+ .globl ._gcry_mpih_mul_1
+ .csect _gcry_mpih_mul_1[DS]
+_gcry_mpih_mul_1:
+ .long ._gcry_mpih_mul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_mul_1[PR]
+._gcry_mpih_mul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ addi 3,3,-4 # adjust res_ptr
+ addic 5,5,0 # clear cy with dummy insn
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 7,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ bdnz Loop
+
+Lend: stw 7,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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. */
+
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate s1*s2 and put result in res_ptr; return carry. */
+
+ENTRY(_gcry_mpih_mul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ addi %r3,%r3,-4 # adjust res_ptr
+ addic %r5,%r5,0 # clear cy with dummy insn
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r7,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ bdnz 0b
+
+1: stw %r7,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_mul_1)
+#endif
--- /dev/null
+/* PowerPC-32 addmul_1 -- Multiply a limb vector with a limb and add
+ * the result to a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+
+ .toc
+ .csect ._gcry_mpih_addmul_1[PR]
+ .align 2
+ .globl _gcry_mpih_addmul_1
+ .globl ._gcry_mpih_addmul_1
+ .csect _gcry_mpih_addmul_1[DS]
+_gcry_mpih_addmul_1:
+ .long ._gcry_mpih_addmul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_addmul_1[PR]
+._gcry_mpih_addmul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ addc 8,7,9
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ addc 8,7,9
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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. */
+
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res+s1*s2 and put result back in res; return carry. */
+ENTRY(_gcry_mpih_addmul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ addc %r8,%r7,%r9
+ addi %r3,%r3,-4 /* adjust res_ptr */
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ addc %r8,%r7,%r9
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_addmul_1)
+#endif
--- /dev/null
+/* PowerPC-32 submul_1 -- Multiply a limb vector with a limb and subtract
+ * the result from a second limb vector.
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_submul_1( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_size_t s1_size, (r5)
+ * mpi_limb_t s2_limb) (r6)
+ *
+ * This is a fairly straightforward implementation. The timing of the PC601
+ * is hard to understand, so I will wait to optimize this until I have some
+ * hardware to play with.
+ *
+ * The code trivially generalizes to 64 bit limbs for the PC620.
+ */
+
+ .toc
+ .csect ._gcry_mpih_submul_1[PR]
+ .align 2
+ .globl _gcry_mpih_submul_1
+ .globl ._gcry_mpih_submul_1
+ .csect _gcry_mpih_submul_1[DS]
+_gcry_mpih_submul_1:
+ .long ._gcry_mpih_submul_1[PR], TOC[tc0], 0
+ .csect ._gcry_mpih_submul_1[PR]
+._gcry_mpih_submul_1:
+ mtctr 5
+
+ lwz 0,0(4)
+ mullw 7,0,6
+ mulhwu 10,0,6
+ lwz 9,0(3)
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ addi 3,3,-4
+ bdz Lend
+
+Loop: lwzu 0,4(4)
+ stwu 8,4(3)
+ mullw 8,0,6
+ adde 7,8,10
+ mulhwu 10,0,6
+ lwz 9,4(3)
+ addze 10,10
+ subfc 8,7,9
+ addc 7,7,8 # invert cy (r7 is junk)
+ bdnz Loop
+
+Lend: stw 8,4(3)
+ addze 3,10
+ blr
+
+#else
+/* Multiply a limb vector by a single limb, for PowerPC.
+ Copyright (C) 1993, 1994, 1995, 1997 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. */
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+ mp_size_t s1_size, mp_limb_t s2_limb)
+ Calculate res-s1*s2 and put result back in res; return carry. */
+
+ENTRY(_gcry_mpih_submul_1)
+ mtctr %r5
+
+ lwz %r0,0(%r4)
+ mullw %r7,%r0,%r6
+ mulhwu %r10,%r0,%r6
+ lwz %r9,0(%r3)
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ addi %r3,%r3,-4 # adjust res_ptr
+ bdz 1f
+
+0: lwzu %r0,4(%r4)
+ stwu %r8,4(%r3)
+ mullw %r8,%r0,%r6
+ adde %r7,%r8,%r10
+ mulhwu %r10,%r0,%r6
+ lwz %r9,4(%r3)
+ addze %r10,%r10
+ subf %r8,%r7,%r9
+ addc %r7,%r7,%r8 # invert cy (r7 is junk)
+ bdnz 0b
+
+1: stw %r8,4(%r3)
+ addze %r3,%r10
+ blr
+END(_gcry_mpih_submul_1)
+#endif
--- /dev/null
+/* PowerPC-32 rshift
+ *
+ * Copyright (C) 1995, 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_rshift( mpi_ptr_t wp, (r3)
+ * mpi_ptr_t up, (r4)
+ * mpi_size_t usize, (r5)
+ * unsigned cnt) (r6)
+ */
+
+ .toc
+.csect .text[PR]
+ .align 2
+ .globl _gcry_mpih_rshift
+ .globl ._gcry_mpih_rshift
+ .csect _gcry_mpih_rshift[DS]
+_gcry_mpih_rshift:
+ .long ._gcry_mpih_rshift, TOC[tc0], 0
+ .csect .text[PR]
+._gcry_mpih_rshift:
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz Lend1
+
+Loop: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz Lend2
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz Loop
+
+Lend1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+Lend2: srw 0,10,6
+ stw 0,4(7)
+ blr
+
+#else
+/* Shift a limb right, low level routine.
+ Copyright (C) 1995, 1997 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. */
+
+
+/* INPUT PARAMETERS
+ res_ptr r3
+ s1_ptr r4
+ size r5
+ cnt r6 */
+
+ENTRY(_gcry_mpih_rshift)
+ mtctr 5 # copy size into CTR
+ addi 7,3,-4 # move adjusted res_ptr to free return reg
+ subfic 8,6,32
+ lwz 11,0(4) # load first s1 limb
+ slw 3,11,8 # compute function return value
+ bdz 1f
+
+0: lwzu 10,4(4)
+ srw 9,11,6
+ slw 12,10,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdz 2f
+ lwzu 11,4(4)
+ srw 9,10,6
+ slw 12,11,8
+ or 9,9,12
+ stwu 9,4(7)
+ bdnz 0b
+
+1: srw 0,11,6
+ stw 0,4(7)
+ blr
+
+2: srw 0,10,6
+ stw 0,4(7)
+ blr
+END(_gcry_mpih_rshift)
+#endif
--- /dev/null
+/* PowerPC-32 sub_n -- Subtract two limb vectors of the same length > 0
+ * and store difference in a third limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include "sysdep.h"
+#include "asm-syntax.h"
+
+
+#ifndef USE_PPC_PATCHES
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_sub_n( mpi_ptr_t res_ptr, (r3)
+ * mpi_ptr_t s1_ptr, (r4)
+ * mpi_ptr_t s2_ptr, (r5)
+ * mpi_size_t size) (r6)
+ */
+
+ .toc
+ .extern _gcry_mpih_sub_n[DS]
+ .extern ._gcry_mpih_sub_n
+.csect [PR]
+ .align 2
+ .globl _gcry_mpih_sub_n
+ .globl ._gcry_mpih_sub_n
+ .csect _gcry_mpih_sub_n[DS]
+_gcry_mpih_sub_n:
+ .long ._gcry_mpih_sub_n, TOC[tc0], 0
+ .csect [PR]
+._gcry_mpih_sub_n:
+ mtctr 6 # copy size into CTR
+ lwz 8,0(4) # load least significant s1 limb
+ lwz 0,0(5) # load least significant s2 limb
+ addi 3,3,-4 # offset res_ptr, it is updated before used
+ subfc 7,0,8 # add least significant limbs, set cy
+ bdz Lend # If done, skip loop
+Loop: lwzu 8,4(4) # load s1 limb and update s1_ptr
+ lwzu 0,4(5) # load s2 limb and update s2_ptr
+ stwu 7,4(3) # store previous limb in load latency slot
+ subfe 7,0,8 # add new limbs with cy, set cy
+ bdnz Loop # decrement CTR and loop back
+Lend: stw 7,4(3) # store ultimate result limb
+ subfe 3,0,0 # load !cy into ...
+ subfic 3,3,0 # ... return value register
+ blr
+
+#else
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+ Copyright (C) 1997 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. */
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+ mp_size_t size)
+ Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1. */
+
+/* Note on optimisation: This code is optimal for the 601. Almost every other
+ possible 2-unrolled inner loop will not be. Also, watch out for the
+ alignment... */
+
+EALIGN(_gcry_mpih_sub_n,3,1)
+/* Set up for loop below. */
+ mtcrf 0x01,%r6
+ srwi. %r7,%r6,1
+ mtctr %r7
+ bt 31,2f
+
+/* Set the carry (clear the borrow). */
+ subfc %r0,%r0,%r0
+/* Adjust pointers for loop. */
+ addi %r3,%r3,-4
+ addi %r4,%r4,-4
+ addi %r5,%r5,-4
+ b 0f
+
+2: lwz %r7,0(%r5)
+ lwz %r6,0(%r4)
+ subfc %r6,%r7,%r6
+ stw %r6,0(%r3)
+ beq 1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+ last two words can be fetched in one access (for 601). This turns
+ out to be important. */
+0:
+ lwz %r9,4(%r4)
+ lwz %r8,4(%r5)
+ lwzu %r6,8(%r4)
+ lwzu %r7,8(%r5)
+ subfe %r8,%r8,%r9
+ stw %r8,4(%r3)
+ subfe %r6,%r7,%r6
+ stwu %r6,8(%r3)
+ bdnz 0b
+/* Return the borrow. */
+1: subfe %r3,%r3,%r3
+ neg %r3,%r3
+ blr
+END(_gcry_mpih_sub_n)
+#endif
--- /dev/null
+/* gmp2-2.0.2-ppc/mpn/powerpc-linux/syntax.h Tue Oct 6 19:27:01 1998 */
+/* From glibc's sysdeps/unix/sysv/linux/powerpc/sysdep.h */
+
+/* Copyright (C) 1992, 1997, 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. */
+
+
+#define USE_PPC_PATCHES 1
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+#ifdef __STDC__
+#define C_LABEL(name) C_SYMBOL_NAME(name)##:
+#else
+#define C_LABEL(name) C_SYMBOL_NAME(name)/**/:
+#endif
+
+#ifdef __STDC__
+#define L(body) .L##body
+#else
+#define L(body) .L/**/body
+#endif
+
+/* No profiling of gmp's assembly for now... */
+#define CALL_MCOUNT /* no profiling */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name)
+
+#undef END
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+udiv.S
+$names$ iQCVAwUAP+LmaDEAnp832S/7AQISHgP/Z5orU+CPKBeRFCogSQDm4p7J2VpDovU6mtfMTdjhqWuZG0U6y8WqH0aj3USfziOhtc8YjQHQ+97g3+EnIWZgLjKacWC6pScY/QbATEpF1D0Wrcea5rk3qR1t7isdBVVOrxedZ5vuj5Op2zx/0OlPI+wt6fTtW88BdG/a6w/ZU/8==Py6h
--- /dev/null
+Manifest
+mpih-lshift.S
+mpih-rshift.S
+mpih-add1.S
+udiv.S
+
--- /dev/null
+/* SPARC _add_n -- Add two limb vectors of the same length > 0 and store
+ * sum in a third limb vector.
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+
+/*******************
+ * mpi_limb_t
+ * _gcry_mpih_add_n( mpi_ptr_t res_ptr,
+ * mpi_ptr_t s1_ptr,
+ * mpi_ptr_t s2_ptr,
+ * mpi_size_t size)
+ */
+
+! INPUT PARAMETERS
+#define res_ptr %o0
+#define s1_ptr %o1
+#define s2_ptr %o2
+#define size %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_add_n)
+C_SYMBOL_NAME(_gcry_mpih_add_n):
+ xor s2_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L1 ! branch if alignment differs
+ nop
+! ** V1a **
+L0: andcc res_ptr,4,%g0 ! res_ptr unaligned? Side effect: cy=0
+ be L_v1 ! if no, branch
+ nop
+/* Add least significant limb separately to align res_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+L_v1: addx %g0,%g0,%o4 ! save cy in register
+ cmp size,2 ! if size < 2 ...
+ bl Lend2 ! ... branch to tail code
+ subcc %g0,%o4,%g0 ! restore cy
+
+ ld [s1_ptr+0],%g4
+ addcc size,-10,size
+ ld [s1_ptr+4],%g1
+ ldd [s2_ptr+0],%g2
+ blt Lfin1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+16],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+20],%g1
+ ldd [s2_ptr+16],%g2
+ std %o4,[res_ptr+8]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+24],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+28],%g1
+ ldd [s2_ptr+24],%g2
+ std %o4,[res_ptr+16]
+ addxcc %g4,%g2,%o4
+ ld [s1_ptr+32],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+36],%g1
+ ldd [s2_ptr+32],%g2
+ std %o4,[res_ptr+24]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop1
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin1: addcc size,8-2,size
+ blt Lend1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 2 limbs until less than 2 limbs remain */
+Loope1: addxcc %g4,%g2,%o4
+ ld [s1_ptr+8],%g4
+ addxcc %g1,%g3,%o5
+ ld [s1_ptr+12],%g1
+ ldd [s2_ptr+8],%g2
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope1
+ subcc %g0,%o4,%g0 ! restore cy
+Lend1: addxcc %g4,%g2,%o4
+ addxcc %g1,%g3,%o5
+ std %o4,[res_ptr+0]
+ addx %g0,%g0,%o4 ! save cy in register
+
+ andcc size,1,%g0
+ be Lret1
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+ ld [s1_ptr+8],%g4
+ ld [s2_ptr+8],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr+8]
+
+Lret1: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+L1: xor s1_ptr,res_ptr,%g1
+ andcc %g1,4,%g0
+ bne L2
+ nop
+! ** V1b **
+ mov s2_ptr,%g1
+ mov s1_ptr,s2_ptr
+ b L0
+ mov %g1,s1_ptr
+
+! ** V2 **
+/* If we come here, the alignment of s1_ptr and res_ptr as well as the
+ alignment of s2_ptr and res_ptr differ. Since there are only two ways
+ things can be aligned (that we care about) we now know that the alignment
+ of s1_ptr and s2_ptr are the same. */
+
+L2: cmp size,1
+ be Ljone
+ nop
+ andcc s1_ptr,4,%g0 ! s1_ptr unaligned? Side effect: cy=0
+ be L_v2 ! if no, branch
+ nop
+/* Add least significant limb separately to align s1_ptr and s2_ptr */
+ ld [s1_ptr],%g4
+ add s1_ptr,4,s1_ptr
+ ld [s2_ptr],%g2
+ add s2_ptr,4,s2_ptr
+ add size,-1,size
+ addcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+ add res_ptr,4,res_ptr
+
+L_v2: addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ blt Lfin2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add blocks of 8 limbs until less than 8 limbs remain */
+Loop2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ ldd [s1_ptr+8],%g2
+ ldd [s2_ptr+8],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+8]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+12]
+ ldd [s1_ptr+16],%g2
+ ldd [s2_ptr+16],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+16]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+20]
+ ldd [s1_ptr+24],%g2
+ ldd [s2_ptr+24],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+24]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+28]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-8,size
+ add s1_ptr,32,s1_ptr
+ add s2_ptr,32,s2_ptr
+ add res_ptr,32,res_ptr
+ bge Loop2
+ subcc %g0,%o4,%g0 ! restore cy
+
+Lfin2: addcc size,8-2,size
+ blt Lend2
+ subcc %g0,%o4,%g0 ! restore cy
+Loope2: ldd [s1_ptr+0],%g2
+ ldd [s2_ptr+0],%o4
+ addxcc %g2,%o4,%g2
+ st %g2,[res_ptr+0]
+ addxcc %g3,%o5,%g3
+ st %g3,[res_ptr+4]
+ addx %g0,%g0,%o4 ! save cy in register
+ addcc size,-2,size
+ add s1_ptr,8,s1_ptr
+ add s2_ptr,8,s2_ptr
+ add res_ptr,8,res_ptr
+ bge Loope2
+ subcc %g0,%o4,%g0 ! restore cy
+Lend2: andcc size,1,%g0
+ be Lret2
+ subcc %g0,%o4,%g0 ! restore cy
+/* Add last limb */
+Ljone: ld [s1_ptr],%g4
+ ld [s2_ptr],%g2
+ addxcc %g4,%g2,%o4
+ st %o4,[res_ptr]
+
+Lret2: retl
+ addx %g0,%g0,%o0 ! return carry-out from most sign. limb
+
+
+
--- /dev/null
+/* sparc lshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_lshift)
+C_SYMBOL_NAME(_gcry_mpih_lshift):
+ sll %o2,2,%g1
+ add %o1,%g1,%o1 ! make %o1 point at end of src
+ ld [%o1-4],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o0,%g1,%o0 ! make %o0 point at end of res
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ srl %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1-8],%g3
+ add %o0,-4,%o0
+ add %o1,-4,%o1
+ addcc %g4,-1,%g4
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0+0]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1-8],%g3
+ add %o0,-16,%o0
+ addcc %o2,-4,%o2
+ sll %g2,%o3,%o4
+ srl %g3,%o5,%g1
+
+ ld [%o1-12],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+12]
+ srl %g2,%o5,%g1
+
+ ld [%o1-16],%g3
+ sll %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0+8]
+ srl %g3,%o5,%g1
+
+ ld [%o1-20],%g2
+ sll %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0+4]
+ srl %g2,%o5,%g1
+
+ add %o1,-16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0+0]
+
+Lend: sll %g2,%o3,%g2
+ st %g2,[%o0-4]
+ retl
+ ld [%sp+80],%o0
+
--- /dev/null
+/* sparc rshift
+ *
+ * Copyright (C) 1995, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+! INPUT PARAMETERS
+! res_ptr %o0
+! src_ptr %o1
+! size %o2
+! cnt %o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_rshift)
+C_SYMBOL_NAME(_gcry_mpih_rshift):
+ ld [%o1],%g2 ! load first limb
+ sub %g0,%o3,%o5 ! negate shift count
+ add %o2,-1,%o2
+ andcc %o2,4-1,%g4 ! number of limbs in first loop
+ sll %g2,%o5,%g1 ! compute function result
+ be L0 ! if multiple of 4 limbs, skip first loop
+ st %g1,[%sp+80]
+
+ sub %o2,%g4,%o2 ! adjust count for main loop
+
+Loop0: ld [%o1+4],%g3
+ add %o0,4,%o0
+ add %o1,4,%o1
+ addcc %g4,-1,%g4
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+ mov %g3,%g2
+ or %o4,%g1,%o4
+ bne Loop0
+ st %o4,[%o0-4]
+
+L0: tst %o2
+ be Lend
+ nop
+
+Loop: ld [%o1+4],%g3
+ add %o0,16,%o0
+ addcc %o2,-4,%o2
+ srl %g2,%o3,%o4
+ sll %g3,%o5,%g1
+
+ ld [%o1+8],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-16]
+ sll %g2,%o5,%g1
+
+ ld [%o1+12],%g3
+ srl %g2,%o3,%o4
+ or %g4,%g1,%g4
+ st %g4,[%o0-12]
+ sll %g3,%o5,%g1
+
+ ld [%o1+16],%g2
+ srl %g3,%o3,%g4
+ or %o4,%g1,%o4
+ st %o4,[%o0-8]
+ sll %g2,%o5,%g1
+
+ add %o1,16,%o1
+ or %g4,%g1,%g4
+ bne Loop
+ st %g4,[%o0-4]
+
+Lend: srl %g2,%o3,%g2
+ st %g2,[%o0-0]
+ retl
+ ld [%sp+80],%o0
+
--- /dev/null
+/* SPARC v7 __udiv_qrnnd division support, used from longlong.h.
+ * This is for v7 CPUs without a floating-point unit.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! rem_ptr o0
+! n1 o1
+! n0 o2
+! d o3
+
+#include "sysdep.h"
+
+ .text
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ tst %o3
+ bneg Largedivisor
+ mov 8,%g1
+
+ b Lp1
+ addxcc %o2,%o2,%o2
+
+Lplop: bcc Ln1
+ addxcc %o2,%o2,%o2
+Lp1: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln2
+ addxcc %o2,%o2,%o2
+Lp2: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln3
+ addxcc %o2,%o2,%o2
+Lp3: addx %o1,%o1,%o1
+ subcc %o1,%o3,%o4
+ bcc Ln4
+ addxcc %o2,%o2,%o2
+Lp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne Lplop
+ subcc %o1,%o3,%o4
+ bcc Ln5
+ addxcc %o2,%o2,%o2
+Lp5: st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Lnlop: bcc Lp1
+ addxcc %o2,%o2,%o2
+Ln1: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp2
+ addxcc %o2,%o2,%o2
+Ln2: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp3
+ addxcc %o2,%o2,%o2
+Ln3: addx %o4,%o4,%o4
+ subcc %o4,%o3,%o1
+ bcc Lp4
+ addxcc %o2,%o2,%o2
+Ln4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne Lnlop
+ subcc %o4,%o3,%o1
+ bcc Lp5
+ addxcc %o2,%o2,%o2
+Ln5: st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Largedivisor:
+ and %o2,1,%o5 ! %o5 = n0 & 1
+
+ srl %o2,1,%o2
+ sll %o1,31,%g2
+ or %g2,%o2,%o2 ! %o2 = lo(n1n0 >> 1)
+ srl %o1,1,%o1 ! %o1 = hi(n1n0 >> 1)
+
+ and %o3,1,%g2
+ srl %o3,1,%g3 ! %g3 = floor(d / 2)
+ add %g3,%g2,%g3 ! %g3 = ceil(d / 2)
+
+ b LLp1
+ addxcc %o2,%o2,%o2
+
+LLplop: bcc LLn1
+ addxcc %o2,%o2,%o2
+LLp1: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn2
+ addxcc %o2,%o2,%o2
+LLp2: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn3
+ addxcc %o2,%o2,%o2
+LLp3: addx %o1,%o1,%o1
+ subcc %o1,%g3,%o4
+ bcc LLn4
+ addxcc %o2,%o2,%o2
+LLp4: addx %o1,%o1,%o1
+ addcc %g1,-1,%g1
+ bne LLplop
+ subcc %o1,%g3,%o4
+ bcc LLn5
+ addxcc %o2,%o2,%o2
+LLp5: add %o1,%o1,%o1 ! << 1
+ tst %g2
+ bne Oddp
+ add %o5,%o1,%o1
+ st %o1,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+LLnlop: bcc LLp1
+ addxcc %o2,%o2,%o2
+LLn1: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp2
+ addxcc %o2,%o2,%o2
+LLn2: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp3
+ addxcc %o2,%o2,%o2
+LLn3: addx %o4,%o4,%o4
+ subcc %o4,%g3,%o1
+ bcc LLp4
+ addxcc %o2,%o2,%o2
+LLn4: addx %o4,%o4,%o4
+ addcc %g1,-1,%g1
+ bne LLnlop
+ subcc %o4,%g3,%o1
+ bcc LLp5
+ addxcc %o2,%o2,%o2
+LLn5: add %o4,%o4,%o4 ! << 1
+ tst %g2
+ bne Oddn
+ add %o5,%o4,%o4
+ st %o4,[%o0]
+ retl
+ xnor %g0,%o2,%o0
+
+Oddp: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o1
+ addcc %o1,%o2,%o1
+ bcc LLp6
+ addx %o2,0,%o2
+ sub %o1,%o3,%o1
+LLp6: subcc %o1,%o3,%g0
+ bcs LLp7
+ subx %o2,-1,%o2
+ sub %o1,%o3,%o1
+LLp7: st %o1,[%o0]
+ retl
+ mov %o2,%o0
+
+Oddn: xnor %g0,%o2,%o2
+ ! q' in %o2. r' in %o4
+ addcc %o4,%o2,%o4
+ bcc LLn6
+ addx %o2,0,%o2
+ sub %o4,%o3,%o4
+LLn6: subcc %o4,%o3,%g0
+ bcs LLn7
+ subx %o2,-1,%o2
+ sub %o4,%o3,%o4
+LLn7: st %o4,[%o0]
+ retl
+ mov %o2,%o0
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+$names$ iQCVAwUAP+LmbjEAnp832S/7AQKQ2gQAotpCpY9rOJUCdZHbDLXXB9i1UUMraRKbVWimtKq493Y2d2wcqXCK2WaGs1AePK3K6Qk6msxZ0PL5Ho7KgHMkzsZ+wG0EUziiuX0yZRTWNm0r3TYerP6SdWH5GOVdSXn7ckkppk2sVOokfQTy+Tmrnah3+dlYJoujan+fmXWN6Us==DolM
--- /dev/null
+Manifest
+mpih-mul1.S
+mpih-mul2.S
+mpih-mul3.S
+
--- /dev/null
+/* SPARC v8 __mpn_mul_1 -- Multiply a limb vector with a single limb and
+ * store the product in a second limb vector.
+ *
+ * Copyright (C) 1992, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 8
+ .global C_SYMBOL_NAME(_gcry_mpih_mul_1)
+C_SYMBOL_NAME(_gcry_mpih_mul_1):
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ ld [%o1+0],%o4 ! 1
+LL:
+LL00: add %o0,-4,%o0
+ add %o1,-4,%o1
+ b Loop00 /* 4, 8, 12, ... */
+ orcc %g0,%g0,%g2
+LL01: b Loop01 /* 1, 5, 9, ... */
+ orcc %g0,%g0,%g2
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ add %o1,4,%o1
+ b Loop10
+ orcc %g0,%g0,%g2
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ add %o1,-8,%o1
+ b Loop11
+ orcc %g0,%g0,%g2
+
+Loop: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ st %g3,[%o0+0] ! 1
+ rd %y,%g2 ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ st %g3,[%o0+4] ! 2
+ rd %y,%g2 ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ add %o1,16,%o1
+ st %g3,[%o0+8] ! 3
+ rd %y,%g2 ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg Loop
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ st %g3,[%o0+0] ! 4
+ rd %y,%g2 ! 4
+
+ retl
+ addx %g0,%g2,%o0
+
+
--- /dev/null
+/* SPARC v8 __mpn_addmul_1 -- Multiply a limb vector with a limb and
+ * add the result to a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1995, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_addmul_1)
+C_SYMBOL_NAME(_gcry_mpih_addmul_1):
+ orcc %g0,%g0,%g2
+ ld [%o1+0],%o4 ! 1
+
+ sll %o2,4,%g1
+ and %g1,(4-1)<<4,%g1
+#if PIC
+ mov %o7,%g4 ! Save return address register
+ call 1f
+ add %o7,LL-1f,%g3
+1: mov %g4,%o7 ! Restore return address register
+#else
+ sethi %hi(LL),%g3
+ or %g3,%lo(LL),%g3
+#endif
+ jmp %g3+%g1
+ nop
+LL:
+LL00: add %o0,-4,%o0
+ b Loop00 /* 4, 8, 12, ... */
+ add %o1,-4,%o1
+ nop
+LL01: b Loop01 /* 1, 5, 9, ... */
+ nop
+ nop
+ nop
+LL10: add %o0,-12,%o0 /* 2, 6, 10, ... */
+ b Loop10
+ add %o1,4,%o1
+ nop
+LL11: add %o0,-8,%o0 /* 3, 7, 11, ... */
+ b Loop11
+ add %o1,-8,%o1
+ nop
+
+1: addcc %g3,%g2,%g3 ! 1
+ ld [%o1+4],%o4 ! 2
+ rd %y,%g2 ! 1
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 1
+Loop00: umul %o4,%o3,%g3 ! 2
+ ld [%o0+4],%g1 ! 2
+ addxcc %g3,%g2,%g3 ! 2
+ ld [%o1+8],%o4 ! 3
+ rd %y,%g2 ! 2
+ addx %g0,%g2,%g2
+ nop
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+4] ! 2
+Loop11: umul %o4,%o3,%g3 ! 3
+ addxcc %g3,%g2,%g3 ! 3
+ ld [%o1+12],%o4 ! 4
+ rd %y,%g2 ! 3
+ add %o1,16,%o1
+ addx %g0,%g2,%g2
+ ld [%o0+8],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+8] ! 3
+Loop10: umul %o4,%o3,%g3 ! 4
+ addxcc %g3,%g2,%g3 ! 4
+ ld [%o1+0],%o4 ! 1
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+12],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+12] ! 4
+ add %o0,16,%o0
+ addx %g0,%g2,%g2
+Loop01: addcc %o2,-4,%o2
+ bg 1b
+ umul %o4,%o3,%g3 ! 1
+
+ addcc %g3,%g2,%g3 ! 4
+ rd %y,%g2 ! 4
+ addx %g0,%g2,%g2
+ ld [%o0+0],%g1 ! 2
+ addcc %g1,%g3,%g3
+ st %g3,[%o0+0] ! 4
+ addx %g0,%g2,%o0
+
+ retl
+ nop
+
+
+! umul, ld, addxcc, rd, st
+
+! umul, ld, addxcc, rd, ld, addcc, st, addx
+
--- /dev/null
+/* SPARC v8 __mpn_submul_1 -- Multiply a limb vector with a limb and
+ * subtract the result from a second limb vector.
+ *
+ * Copyright (C) 1992, 1993, 1994, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+! INPUT PARAMETERS
+! res_ptr o0
+! s1_ptr o1
+! size o2
+! s2_limb o3
+
+#include "sysdep.h"
+
+.text
+ .align 4
+ .global C_SYMBOL_NAME(_gcry_mpih_submul_1)
+C_SYMBOL_NAME(_gcry_mpih_submul_1):
+ sub %g0,%o2,%o2 ! negate ...
+ sll %o2,2,%o2 ! ... and scale size
+ sub %o1,%o2,%o1 ! o1 is offset s1_ptr
+ sub %o0,%o2,%g1 ! g1 is offset res_ptr
+
+ mov 0,%o0 ! clear cy_limb
+
+Loop: ld [%o1+%o2],%o4
+ ld [%g1+%o2],%g2
+ umul %o4,%o3,%o5
+ rd %y,%g3
+ addcc %o5,%o0,%o5
+ addx %g3,0,%o0
+ subcc %g2,%o5,%g2
+ addx %o0,0,%o0
+ st %g2,[%g1+%o2]
+
+ addcc %o2,4,%o2
+ bne Loop
+ nop
+
+ retl
+ nop
+
+
--- /dev/null
+# Manifest - checksums
+# Copyright 2003 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+udiv.S
+$names$ iQCVAwUAP+LmdjEAnp832S/7AQIrUgQA3YmurZhK7r20DqRvg0gwNe9jMDcFfUY4ZPhW5HkGzMbmrxXtj5Dx50RIPteum72bXE+IhcngljQb/cskiN5Hi9oc2a2CPhyTqVFEeGyF+kJ170GI1pVfFOfzbVG0F4nEwm5lGHgv/nvFsvrjmmAXVW1v/yk5N35wbiLviOFrLOQ==byFc
--- /dev/null
+Manifest
+udiv.S
+
--- /dev/null
+/* SuperSPARC __udiv_qrnnd division support, used from longlong.h.
+ * This is for SuperSPARC only, to compensate for its
+ * semi-functional udiv instruction.
+ *
+ * Copyright (C) 1993, 1994, 1996, 1998,
+ * 2001, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+
+
+! INPUT PARAMETERS
+! rem_ptr i0
+! n1 i1
+! n0 i2
+! d i3
+
+#include "sysdep.h"
+#undef ret /* Kludge for glibc */
+
+ .text
+ .align 8
+LC0: .double 0r4294967296
+LC1: .double 0r2147483648
+
+ .align 4
+ .global C_SYMBOL_NAME(__udiv_qrnnd)
+C_SYMBOL_NAME(__udiv_qrnnd):
+ !#PROLOGUE# 0
+ save %sp,-104,%sp
+ !#PROLOGUE# 1
+ st %i1,[%fp-8]
+ ld [%fp-8],%f10
+ sethi %hi(LC0),%o7
+ fitod %f10,%f4
+ ldd [%o7+%lo(LC0)],%f8
+ cmp %i1,0
+ bge L248
+ mov %i0,%i5
+ faddd %f4,%f8,%f4
+L248:
+ st %i2,[%fp-8]
+ ld [%fp-8],%f10
+ fmuld %f4,%f8,%f6
+ cmp %i2,0
+ bge L249
+ fitod %f10,%f2
+ faddd %f2,%f8,%f2
+L249:
+ st %i3,[%fp-8]
+ faddd %f6,%f2,%f2
+ ld [%fp-8],%f10
+ cmp %i3,0
+ bge L250
+ fitod %f10,%f4
+ faddd %f4,%f8,%f4
+L250:
+ fdivd %f2,%f4,%f2
+ sethi %hi(LC1),%o7
+ ldd [%o7+%lo(LC1)],%f4
+ fcmped %f2,%f4
+ nop
+ fbge,a L251
+ fsubd %f2,%f4,%f2
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ b L252
+ ld [%fp-8],%i4
+L251:
+ fdtoi %f2,%f2
+ st %f2,[%fp-8]
+ ld [%fp-8],%i4
+ sethi %hi(-2147483648),%g2
+ xor %i4,%g2,%i4
+L252:
+ umul %i3,%i4,%g3
+ rd %y,%i0
+ subcc %i2,%g3,%o7
+ subxcc %i1,%i0,%g0
+ be L253
+ cmp %o7,%i3
+
+ add %i4,-1,%i0
+ add %o7,%i3,%o7
+ st %o7,[%i5]
+ ret
+ restore
+L253:
+ blu L246
+ mov %i4,%i0
+ add %i4,1,%i0
+ sub %o7,%i3,%o7
+L246:
+ st %o7,[%i5]
+ ret
+ restore
+
--- /dev/null
+2010-10-18 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (registry_poll): Disable performace fata gathering if
+ GNUPG_RNDW32_NOPERF has been set.
+
+2010-04-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * rndw32ce.c (fillup_buffer): Rewrite without using nested
+ functions, which are broken on arm/cegcc.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-24 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Revert all changes from 2010-01-21.
+
+ * rndw32ce.c: New.
+ * Makefile.am (EXTRA_librandom_la_SOURCES): Add it.
+ * random-csprng.c (getfnc_gather_random)
+ (getfnc_fast_random_poll) [USE_RNDW32CE]: Use rndw32ce.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (read_mbm_data) [W32CE]: Do not build.
+ (slow_gatherer) [W32CE]: Do not call read_mbm_data.
+ (_gcry_rndw32_gather_random_fast) [W32CE]: Exclude some calls.
+ (_gcry_rndw32_gather_random): Adjust version test for WindowsCE.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (system_is_w2000): New.
+ (_gcry_rndw32_gather_random): Set it.
+ (slow_gatherer): Ignore SystemObjectInformation on W2000. Fixes
+ bug#1167.
+
+2009-07-09 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (_gcry_rndlinux_gather_random): Print real values for
+ the progess function and call it before blocking. Suggested by
+ Christian Grothoff.
+ * rndunix.c (slow_poll): Add similar, but not yet functional, code.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * rndhw.c (poll_padlock): Asm change from Fedora.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_deinit_external_test): Do not return a
+ value. Reported Albert Chin.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_aes_driver): No re-seeding with test contexts.
+ (_gcry_rngfips_init_external_test): Fix setting of test_dt_ptr.
+ (struct rng_context): Add flag TEST_NO_DUP_CHECK.
+ (x931_aes_driver): Use that flag.
+ (_gcry_rngfips_init_external_test): Add arg FLAGS and use it to
+ modify the test.
+ * random.c (_gcry_random_init_external_test): Pass FLAGS.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_init_external_test): New.
+ (_gcry_random_run_external_test): New.
+ (_gcry_random_deinit_external_test): New.
+ * random-fips.c (struct rng_context): Turn TEST_DT_COUNTER into a
+ 32 bit integer.
+ (x931_get_dt): Ditto.
+ (selftest_kat): Intialize it accordingly.
+ (_gcry_rngfips_init_external_test): New.
+ (_gcry_rngfips_run_external_test): New.
+ (_gcry_rngfips_deinit_external_test): New.
+
+2008-09-05 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_random_selftest): Return success if not in fips
+ mode.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_get_dt) [W32]: Do not use getppid.
+ (get_entropy): Prepare for use under Windows.
+ (_gcry_rngfips_selftest): Ditto.
+ (entropy_collect_cb): Make sure that the gatherer never overflows
+ the buffers.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (SEED_TTL): New.
+ (struct rng_context): Add USE_COUNTER, remove NEED_STRONG_ENTROPY.
+ (x931_aes_driver): Do re-seeding if required.
+ (x931_generate_key, x931_generate_seed): Factor common code out to ..
+ (get_entropy): .. new. Always use /dev/random.
+ (x931_generate_key): Seed key for nonce_context from std_rng_context.
+ (x931_reseed): New. Seed nonce context from std_rng_context.
+ (get_random): Use x931_reseed.
+ (_gcry_rngfips_selftest): Return an error if no /dev/radom support
+ has been compiled in.
+ (get_random): Remove locking.
+ (_gcry_rngfips_randomize, _gcry_rngfips_create_nonce): Lock here.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c (connect_to_socket): Use GPG_ERR_ENAMETOOLONG.
+
+2008-08-25 Werner Koch <wk@g10code.com>
+
+ * random-fips.c (x931_aes): Take datetime_GT from an arg.
+ (x931_aes_driver): Call x931_get_dt here.
+ (x931_get_dt): Implement the KAT hack.
+ (x931_generate_seed): Copy the seed value to the provided buffer.
+ (selftest_kat): New.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * random.c (_gcry_update_random_seed_file): Move operational check
+ to _gcry_vcontrol.
+ (_gcry_fast_random_poll): Ditto.
+ (_gcry_random_selftest): New.
+ * random-fips.c (_gcry_rngfips_selftest): New.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * random-fips.c: Finish implementation.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * random-fips.c: New.
+
+ * random-csprng.c (process-cb, progress_cb_data): Move to
+ random.c.
+ (_gcry_register_random_progress, _gcry_random_progress): Ditto.
+ (_gcry_random_initialize): Rename to _gcry_rngcsprng_initialize.
+ (_gcry_random_dump_stats): Rename to _gcry_rngcsprng_dump_stats.
+ (_gcry_secure_random_alloc): Rename to
+ _gcry_rngcsprng_secure_alloc.
+ (_gcry_enable_quick_random_gen): Rename to
+ _gcry_rngcsprng_enable_quick_gen.
+ (_gcry_set_random_daemon_socket): Rename to
+ _gcry_rngcsprng_set_daemon_socket.
+ (_gcry_use_random_daemon): Rename to _gcry_rngcsprng_use_daemon.
+ (_gcry_random_is_faked): Rename to _gcry_rngcsprng_is_faked.
+ (gcry_random_add_bytes): Rename to _gcry_rngcsprng_add_bytes.
+ (gcry_random_bytes): Remove
+ (gcry_random_bytes_secure): Remove.
+ (gcry_randomize): Rename to _gcry_rngcsprng_randomize.
+ (_gcry_set_random_seed_file): Rename to
+ _gcry_rngcsprng_set_seed_file.
+ (_gcry_update_random_seed_file): Rename to
+ _gcry_rngcsprng_update_seed_file.
+ (_gcry_fast_random_poll): Rename to _gcry_rngcsprng_fast_poll.
+ (gcry_create_nonce): Rename to _gcry_rngcsprng_create_nonce.
+
+ * random.c: Factor all code out to random-csprng.c and implement
+ wrapper functions.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h *
+ random.c, rndegd.c, rndlinux.c, rndw32.c: Move from ../cipher/ to
+ here.
+ * Makefile.am: New.
+
+ Copyright 2008, 2009 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+# Makefile for cipher modules
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+noinst_LTLIBRARIES = librandom.la
+
+GCRYPT_MODULES = @GCRYPT_RANDOM@
+
+librandom_la_DEPENDENCIES = $(GCRYPT_MODULES)
+librandom_la_LIBADD = $(GCRYPT_MODULES)
+
+librandom_la_SOURCES = \
+random.c random.h \
+rand-internal.h \
+random-csprng.c \
+random-fips.c \
+rndhw.c
+
+if USE_RANDOM_DAEMON
+librandom_la_SOURCES += random-daemon.c
+endif USE_RANDOM_DAEMON
+
+
+EXTRA_librandom_la_SOURCES = \
+rndlinux.c \
+rndegd.c \
+rndunix.c \
+rndw32.c \
+rndw32ce.c
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile for cipher modules
+# Copyright (C) 2008 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+# Process this file with automake to produce Makefile.in
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@USE_RANDOM_DAEMON_TRUE@am__append_1 = random-daemon.c
+subdir = random
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \
+ random-csprng.c random-fips.c rndhw.c random-daemon.c
+@USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo
+am_librandom_la_OBJECTS = random.lo random-csprng.lo random-fips.lo \
+ rndhw.lo $(am__objects_1)
+librandom_la_OBJECTS = $(am_librandom_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(librandom_la_SOURCES) $(EXTRA_librandom_la_SOURCES)
+DIST_SOURCES = $(am__librandom_la_SOURCES_DIST) \
+ $(EXTRA_librandom_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+noinst_LTLIBRARIES = librandom.la
+GCRYPT_MODULES = @GCRYPT_RANDOM@
+librandom_la_DEPENDENCIES = $(GCRYPT_MODULES)
+librandom_la_LIBADD = $(GCRYPT_MODULES)
+librandom_la_SOURCES = random.c random.h rand-internal.h \
+ random-csprng.c random-fips.c rndhw.c $(am__append_1)
+EXTRA_librandom_la_SOURCES = \
+rndlinux.c \
+rndegd.c \
+rndunix.c \
+rndw32.c \
+rndw32ce.c
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu random/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu random/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+ @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES)
+ $(LINK) $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-fips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndhw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndlinux.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndunix.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndw32.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndw32ce.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-noinstLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+/* rand-internal.h - header to glue the random functions
+ * Copyright (C) 1998, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef G10_RAND_INTERNAL_H
+#define G10_RAND_INTERNAL_H
+
+#include "../src/cipher-proto.h"
+
+/* Constants used to define the origin of random added to the pool.
+ The code is sensitive to the order of the values. */
+enum random_origins
+ {
+ RANDOM_ORIGIN_INIT = 0, /* Used only for initialization. */
+ RANDOM_ORIGIN_EXTERNAL = 1, /* Added from an external source. */
+ RANDOM_ORIGIN_FASTPOLL = 2, /* Fast random poll function. */
+ RANDOM_ORIGIN_SLOWPOLL = 3, /* Slow poll function. */
+ RANDOM_ORIGIN_EXTRAPOLL = 4 /* Used to mark an extra pool seed
+ due to a GCRY_VERY_STRONG_RANDOM
+ random request. */
+ };
+
+
+
+/*-- random.c --*/
+void _gcry_random_progress (const char *what, int printchar,
+ int current, int total);
+
+
+/*-- random-csprng.c --*/
+void _gcry_rngcsprng_initialize (int full);
+void _gcry_rngcsprng_dump_stats (void);
+void _gcry_rngcsprng_secure_alloc (void);
+void _gcry_rngcsprng_enable_quick_gen (void);
+void _gcry_rngcsprng_set_daemon_socket (const char *socketname);
+int _gcry_rngcsprng_use_daemon (int onoff);
+int _gcry_rngcsprng_is_faked (void);
+gcry_error_t _gcry_rngcsprng_add_bytes (const void *buf, size_t buflen,
+ int quality);
+void *_gcry_rngcsprng_get_bytes (size_t nbytes,
+ enum gcry_random_level level);
+void *_gcry_rngcsprng_get_bytes_secure (size_t nbytes,
+ enum gcry_random_level level);
+void _gcry_rngcsprng_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+void _gcry_rngcsprng_set_seed_file (const char *name);
+void _gcry_rngcsprng_update_seed_file (void);
+void _gcry_rngcsprng_fast_poll (void);
+void _gcry_rngcsprng_create_nonce (void *buffer, size_t length);
+
+/*-- random-rngcsprng.c --*/
+void _gcry_rngfips_initialize (int full);
+void _gcry_rngfips_dump_stats (void);
+int _gcry_rngfips_is_faked (void);
+gcry_error_t _gcry_rngfips_add_bytes (const void *buf, size_t buflen,
+ int quality);
+void *_gcry_rngfips_get_bytes (size_t nbytes,
+ enum gcry_random_level level);
+void *_gcry_rngfips_get_bytes_secure (size_t nbytes,
+ enum gcry_random_level level);
+void _gcry_rngfips_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+void _gcry_rngfips_create_nonce (void *buffer, size_t length);
+
+gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report);
+
+gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context,
+ unsigned int flags,
+ const void *key,
+ size_t keylen,
+ const void *seed,
+ size_t seedlen,
+ const void *dt,
+ size_t dtlen);
+gcry_err_code_t _gcry_rngfips_run_external_test (void *context,
+ char *buffer, size_t buflen);
+void _gcry_rngfips_deinit_external_test (void *context);
+
+
+
+
+
+/*-- rndlinux.c --*/
+int _gcry_rndlinux_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+
+/*-- rndunix.c --*/
+int _gcry_rndunix_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+
+/*-- rndelg.c --*/
+int _gcry_rndegd_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+int _gcry_rndegd_connect_socket (int nofail);
+
+/*-- rndw32.c --*/
+int _gcry_rndw32_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+void _gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin );
+
+/*-- rndw32ce.c --*/
+int _gcry_rndw32ce_gather_random (void (*add) (const void *, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level);
+void _gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin );
+
+/*-- rndhw.c --*/
+int _gcry_rndhw_failed_p (void);
+void _gcry_rndhw_poll_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin);
+size_t _gcry_rndhw_poll_slow (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin);
+
+
+
+#endif /*G10_RAND_INTERNAL_H*/
--- /dev/null
+/* random-csprng.c - CSPRNG style random number generator (libgcrypt classic)
+ * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
+ * 2007, 2008, 2010 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This random number generator is modelled after the one described in
+ Peter Gutmann's 1998 Usenix Security Symposium paper: "Software
+ Generation of Practically Strong Random Numbers". See also chapter
+ 6 in his book "Cryptographic Security Architecture", New York,
+ 2004, ISBN 0-387-95387-6.
+
+ Note that the acronym CSPRNG stands for "Continuously Seeded
+ PseudoRandom Number Generator" as used in Peter's implementation of
+ the paper and not only for "Cryptographically Secure PseudoRandom
+ Number Generator".
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#ifdef HAVE_GETHRTIME
+#include <sys/times.h>
+#endif
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+#ifdef HAVE_GETRUSAGE
+#include <sys/resource.h>
+#endif
+#ifdef __MINGW32__
+#include <process.h>
+#endif
+#include "g10lib.h"
+#include "../cipher/rmd.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "cipher.h" /* Required for the rmd160_hash_buffer() prototype. */
+#include "ath.h"
+
+#ifndef RAND_MAX /* For SunOS. */
+#define RAND_MAX 32767
+#endif
+
+/* Check whether we can lock the seed file read write. */
+#if defined(HAVE_FCNTL) && defined(HAVE_FTRUNCATE) && !defined(HAVE_W32_SYSTEM)
+#define LOCK_SEED_FILE 1
+#else
+#define LOCK_SEED_FILE 0
+#endif
+
+/* Define the constant we use for transforming the pool at read-out. */
+#if SIZEOF_UNSIGNED_LONG == 8
+#define ADD_VALUE 0xa5a5a5a5a5a5a5a5
+#elif SIZEOF_UNSIGNED_LONG == 4
+#define ADD_VALUE 0xa5a5a5a5
+#else
+#error weird size for an unsigned long
+#endif
+
+/* Contstants pertaining to the hash pool. */
+#define BLOCKLEN 64 /* Hash this amount of bytes... */
+#define DIGESTLEN 20 /* ... into a digest of this length (rmd160). */
+/* POOLBLOCKS is the number of digests which make up the pool. */
+#define POOLBLOCKS 30
+/* POOLSIZE must be a multiple of the digest length to make the AND
+ operations faster, the size should also be a multiple of unsigned
+ long. */
+#define POOLSIZE (POOLBLOCKS*DIGESTLEN)
+#if (POOLSIZE % SIZEOF_UNSIGNED_LONG)
+#error Please make sure that poolsize is a multiple of unsigned long
+#endif
+#define POOLWORDS (POOLSIZE / SIZEOF_UNSIGNED_LONG)
+
+
+/* RNDPOOL is the pool we use to collect the entropy and to stir it
+ up. Its allocated size is POOLSIZE+BLOCKLEN. Note that this is
+ also an indication on whether the module has been fully
+ initialized. */
+static unsigned char *rndpool;
+
+/* KEYPOOL is used as a scratch copy to read out random from RNDPOOL.
+ Its allocated size is also POOLSIZE+BLOCKLEN. */
+static unsigned char *keypool;
+
+/* This is the offset into RNDPOOL where the next random bytes are to
+ be mixed in. */
+static size_t pool_writepos;
+
+/* When reading data out of KEYPOOL, we start the read at different
+ positions. This variable keeps track on where to read next. */
+static size_t pool_readpos;
+
+/* This flag is set to true as soon as the pool has been completely
+ filled the first time. This may happen either by rereading a seed
+ file or by adding enough entropy. */
+static int pool_filled;
+
+/* This counter is used to track whether the initial seeding has been
+ done with enough bytes from a reliable entropy source. */
+static size_t pool_filled_counter;
+
+/* If random of level GCRY_VERY_STRONG_RANDOM has been requested we
+ have stricter requirements on what kind of entropy is in the pool.
+ In particular POOL_FILLED is not sufficient. Thus we add some
+ extra seeding and set this flag to true if the extra seeding has
+ been done. */
+static int did_initial_extra_seeding;
+
+/* This variable is used to estimated the amount of fresh entropy
+ available in RNDPOOL. */
+static int pool_balance;
+
+/* After a mixing operation this variable will be set to true and
+ cleared if new entropy has been added or a remix is required for
+ other reasons. */
+static int just_mixed;
+
+/* The name of the seed file or NULL if no seed file has been defined.
+ The seed file needs to be regsitered at initialiation time. We
+ keep a malloced copy here. */
+static char *seed_file_name;
+
+/* If a seed file has been registered and maybe updated on exit this
+ flag set. */
+static int allow_seed_file_update;
+
+/* Option flag set at initialiation time to force allocation of the
+ pool in secure memory. */
+static int secure_alloc;
+
+/* This function pointer is set to the actual entropy gathering
+ function during initailization. After initialization it is
+ guaranteed to point to function. (On systems without a random
+ gatherer module a dummy function is used).*/
+static int (*slow_gather_fnc)(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int);
+
+/* This function is set to the actual fast entropy gathering function
+ during initialization. If it is NULL, no such function is
+ available. */
+static void (*fast_gather_fnc)(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins);
+
+
+/* Option flag useful for debugging and the test suite. If set
+ requests for very strong random are degraded to strong random. Not
+ used by regular applications. */
+static int quick_test;
+
+/* On systems without entropy gathering modules, this flag is set to
+ indicate that the random generator is not working properly. A
+ warning message is issued as well. This is useful only for
+ debugging and during development. */
+static int faked_rng;
+
+/* This is the lock we use to protect all pool operations. */
+static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
+
+/* This is a helper for assert calls. These calls are used to assert
+ that functions are called in a locked state. It is not meant to be
+ thread-safe but as a method to get aware of missing locks in the
+ test suite. */
+static int pool_is_locked;
+
+/* This is the lock we use to protect the buffer used by the nonce
+ generation. */
+static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
+
+
+/* We keep some counters in this structure for the sake of the
+ _gcry_random_dump_stats () function. */
+static struct
+{
+ unsigned long mixrnd;
+ unsigned long mixkey;
+ unsigned long slowpolls;
+ unsigned long fastpolls;
+ unsigned long getbytes1;
+ unsigned long ngetbytes1;
+ unsigned long getbytes2;
+ unsigned long ngetbytes2;
+ unsigned long addbytes;
+ unsigned long naddbytes;
+} rndstats;
+
+
+
+/* --- Stuff pertaining to the random daemon support. --- */
+#ifdef USE_RANDOM_DAEMON
+
+/* If ALLOW_DAEMON is true, the module will try to use the random
+ daemon first. If the daemon has failed, this variable is set to
+ back to false and the code continues as normal. Note, we don't
+ test this flag in a locked state because a wrong value does not
+ harm and the trhead will find out itself that the daemon does not
+ work and set it (again) to false. */
+static int allow_daemon;
+
+/* During initialization, the user may set a non-default socket name
+ for accessing the random daemon. If this value is NULL, the
+ default name will be used. */
+static char *daemon_socket_name;
+
+#endif /*USE_RANDOM_DAEMON*/
+
+
+
+/* --- Prototypes --- */
+static void read_pool (byte *buffer, size_t length, int level );
+static void add_randomness (const void *buffer, size_t length,
+ enum random_origins origin);
+static void random_poll (void);
+static void do_fast_random_poll (void);
+static int (*getfnc_gather_random (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int);
+static void (*getfnc_fast_random_poll (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins);
+static void read_random_source (enum random_origins origin,
+ size_t length, int level);
+static int gather_faked (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins, size_t length, int level );
+
+
+\f
+/* --- Functions --- */
+
+
+/* Basic initialization which is required to initialize mutexes and
+ such. It does not run a full initialization so that the filling of
+ the random pool can be delayed until it is actually needed. We
+ assume that this function is used before any concurrent access
+ happens. */
+static void
+initialize_basics(void)
+{
+ static int initialized;
+ int err;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ err = ath_mutex_init (&pool_lock);
+ if (err)
+ log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
+
+ err = ath_mutex_init (&nonce_buffer_lock);
+ if (err)
+ log_fatal ("failed to create the nonce buffer lock: %s\n",
+ strerror (err) );
+
+#ifdef USE_RANDOM_DAEMON
+ _gcry_daemon_initialize_basics ();
+#endif /*USE_RANDOM_DAEMON*/
+
+ /* Make sure that we are still using the values we have
+ traditionally used for the random levels. */
+ gcry_assert (GCRY_WEAK_RANDOM == 0
+ && GCRY_STRONG_RANDOM == 1
+ && GCRY_VERY_STRONG_RANDOM == 2);
+ }
+}
+
+/* Take the pool lock. */
+static void
+lock_pool (void)
+{
+ int err;
+
+ err = ath_mutex_lock (&pool_lock);
+ if (err)
+ log_fatal ("failed to acquire the pool lock: %s\n", strerror (err));
+ pool_is_locked = 1;
+}
+
+/* Release the pool lock. */
+static void
+unlock_pool (void)
+{
+ int err;
+
+ pool_is_locked = 0;
+ err = ath_mutex_unlock (&pool_lock);
+ if (err)
+ log_fatal ("failed to release the pool lock: %s\n", strerror (err));
+}
+
+
+/* Full initialization of this module. */
+static void
+initialize(void)
+{
+ /* Although the basic initialization should have happened already,
+ we call it here to make sure that all prerequisites are met. */
+ initialize_basics ();
+
+ /* Now we can look the pool and complete the initialization if
+ necessary. */
+ lock_pool ();
+ if (!rndpool)
+ {
+ /* The data buffer is allocated somewhat larger, so that we can
+ use this extra space (which is allocated in secure memory) as
+ a temporary hash buffer */
+ rndpool = (secure_alloc
+ ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+ : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+ keypool = (secure_alloc
+ ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+ : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+
+ /* Setup the slow entropy gathering function. The code requires
+ that this function exists. */
+ slow_gather_fnc = getfnc_gather_random ();
+ if (!slow_gather_fnc)
+ {
+ faked_rng = 1;
+ slow_gather_fnc = gather_faked;
+ }
+
+ /* Setup the fast entropy gathering function. */
+ fast_gather_fnc = getfnc_fast_random_poll ();
+
+ }
+ unlock_pool ();
+}
+
+
+
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the initialize and does not do anything more. Doing
+ this is not really required but when running in a threaded
+ environment we might get a race condition otherwise. */
+void
+_gcry_rngcsprng_initialize (int full)
+{
+ if (!full)
+ initialize_basics ();
+ else
+ initialize ();
+}
+
+
+void
+_gcry_rngcsprng_dump_stats (void)
+{
+ /* In theory we would need to lock the stats here. However this
+ function is usually called during cleanup and then we _might_ run
+ into problems. */
+
+ log_info ("random usage: poolsize=%d mixed=%lu polls=%lu/%lu added=%lu/%lu\n"
+ " outmix=%lu getlvl1=%lu/%lu getlvl2=%lu/%lu%s\n",
+ POOLSIZE, rndstats.mixrnd, rndstats.slowpolls, rndstats.fastpolls,
+ rndstats.naddbytes, rndstats.addbytes,
+ rndstats.mixkey, rndstats.ngetbytes1, rndstats.getbytes1,
+ rndstats.ngetbytes2, rndstats.getbytes2,
+ _gcry_rndhw_failed_p()? " (hwrng failed)":"");
+}
+
+
+/* This function should be called during initialization and before
+ initialization of this module to place the random pools into secure
+ memory. */
+void
+_gcry_rngcsprng_secure_alloc (void)
+{
+ secure_alloc = 1;
+}
+
+
+/* This may be called before full initialization to degrade the
+ quality of the RNG for the sake of a faster running test suite. */
+void
+_gcry_rngcsprng_enable_quick_gen (void)
+{
+ quick_test = 1;
+}
+
+
+void
+_gcry_rngcsprng_set_daemon_socket (const char *socketname)
+{
+#ifdef USE_RANDOM_DAEMON
+ if (daemon_socket_name)
+ BUG ();
+
+ daemon_socket_name = gcry_xstrdup (socketname);
+#else /*!USE_RANDOM_DAEMON*/
+ (void)socketname;
+#endif /*!USE_RANDOM_DAEMON*/
+}
+
+/* With ONOFF set to 1, enable the use of the daemon. With ONOFF set
+ to 0, disable the use of the daemon. With ONOF set to -1, return
+ whether the daemon has been enabled. */
+int
+_gcry_rngcsprng_use_daemon (int onoff)
+{
+#ifdef USE_RANDOM_DAEMON
+ int last;
+
+ /* This is not really thread safe. However it is expected that this
+ function is being called during initialization and at that point
+ we are for other reasons not really thread safe. We do not want
+ to lock it because we might eventually decide that this function
+ may even be called prior to gcry_check_version. */
+ last = allow_daemon;
+ if (onoff != -1)
+ allow_daemon = onoff;
+
+ return last;
+#else /*!USE_RANDOM_DAEMON*/
+ (void)onoff;
+ return 0;
+#endif /*!USE_RANDOM_DAEMON*/
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_rngcsprng_is_faked (void)
+{
+ /* We need to initialize due to the runtime determination of
+ available entropy gather modules. */
+ initialize();
+ return (faked_rng || quick_test);
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngcsprng_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ size_t nbytes;
+ const char *bufptr;
+
+ if (quality == -1)
+ quality = 35;
+ else if (quality > 100)
+ quality = 100;
+ else if (quality < 0)
+ quality = 0;
+
+ if (!buf)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ if (!buflen || quality < 10)
+ return 0; /* Take a shortcut. */
+
+ /* Because we don't increment the entropy estimation with FASTPOLL,
+ we don't need to take lock that estimation while adding from an
+ external source. This limited entropy estimation also means that
+ we can't take QUALITY into account. */
+ initialize_basics ();
+ bufptr = buf;
+ while (buflen)
+ {
+ nbytes = buflen > POOLSIZE? POOLSIZE : buflen;
+ lock_pool ();
+ if (rndpool)
+ add_randomness (bufptr, nbytes, RANDOM_ORIGIN_EXTERNAL);
+ unlock_pool ();
+ bufptr += nbytes;
+ buflen -= nbytes;
+ }
+ return 0;
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ not very strong, GCRY_STRONG_RANDOM is strong enough for most
+ usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
+ may be very slow. */
+void
+_gcry_rngcsprng_randomize (void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ unsigned char *p;
+
+ /* Make sure we are initialized. */
+ initialize ();
+
+ /* Handle our hack used for regression tests of Libgcrypt. */
+ if ( quick_test && level > GCRY_STRONG_RANDOM )
+ level = GCRY_STRONG_RANDOM;
+
+ /* Make sure the level is okay. */
+ level &= 3;
+
+#ifdef USE_RANDOM_DAEMON
+ if (allow_daemon
+ && !_gcry_daemon_randomize (daemon_socket_name, buffer, length, level))
+ return; /* The daemon succeeded. */
+ allow_daemon = 0; /* Daemon failed - switch off. */
+#endif /*USE_RANDOM_DAEMON*/
+
+ /* Acquire the pool lock. */
+ lock_pool ();
+
+ /* Update the statistics. */
+ if (level >= GCRY_VERY_STRONG_RANDOM)
+ {
+ rndstats.getbytes2 += length;
+ rndstats.ngetbytes2++;
+ }
+ else
+ {
+ rndstats.getbytes1 += length;
+ rndstats.ngetbytes1++;
+ }
+
+ /* Read the random into the provided buffer. */
+ for (p = buffer; length > 0;)
+ {
+ size_t n;
+
+ n = length > POOLSIZE? POOLSIZE : length;
+ read_pool (p, n, level);
+ length -= n;
+ p += n;
+ }
+
+ /* Release the pool lock. */
+ unlock_pool ();
+}
+
+
+
+
+/*
+ Mix the pool:
+
+ |........blocks*20byte........|20byte|..44byte..|
+ <..44byte..> <20byte>
+ | |
+ | +------+
+ +---------------------------|----------+
+ v v
+ |........blocks*20byte........|20byte|..44byte..|
+ <.....64bytes.....>
+ |
+ +----------------------------------+
+ Hash
+ v
+ |.............................|20byte|..44byte..|
+ <20byte><20byte><..44byte..>
+ | |
+ | +---------------------+
+ +-----------------------------+ |
+ v v
+ |.............................|20byte|..44byte..|
+ <.....64byte......>
+ |
+ +-------------------------+
+ Hash
+ v
+ |.............................|20byte|..44byte..|
+ <20byte><20byte><..44byte..>
+
+ and so on until we did this for all blocks.
+
+ To better protect against implementation errors in this code, we
+ xor a digest of the entire pool into the pool before mixing.
+
+ Note: this function must only be called with a locked pool.
+ */
+static void
+mix_pool(unsigned char *pool)
+{
+ static unsigned char failsafe_digest[DIGESTLEN];
+ static int failsafe_digest_valid;
+
+ unsigned char *hashbuf = pool + POOLSIZE;
+ unsigned char *p, *pend;
+ int i, n;
+ RMD160_CONTEXT md;
+
+#if DIGESTLEN != 20
+#error must have a digest length of 20 for ripe-md-160
+#endif
+
+ gcry_assert (pool_is_locked);
+ _gcry_rmd160_init( &md );
+
+ /* Loop over the pool. */
+ pend = pool + POOLSIZE;
+ memcpy(hashbuf, pend - DIGESTLEN, DIGESTLEN );
+ memcpy(hashbuf+DIGESTLEN, pool, BLOCKLEN-DIGESTLEN);
+ _gcry_rmd160_mixblock( &md, hashbuf);
+ memcpy(pool, hashbuf, 20 );
+
+ if (failsafe_digest_valid && pool == rndpool)
+ {
+ for (i=0; i < 20; i++)
+ pool[i] ^= failsafe_digest[i];
+ }
+
+ p = pool;
+ for (n=1; n < POOLBLOCKS; n++)
+ {
+ memcpy (hashbuf, p, DIGESTLEN);
+
+ p += DIGESTLEN;
+ if (p+DIGESTLEN+BLOCKLEN < pend)
+ memcpy (hashbuf+DIGESTLEN, p+DIGESTLEN, BLOCKLEN-DIGESTLEN);
+ else
+ {
+ unsigned char *pp = p + DIGESTLEN;
+
+ for (i=DIGESTLEN; i < BLOCKLEN; i++ )
+ {
+ if ( pp >= pend )
+ pp = pool;
+ hashbuf[i] = *pp++;
+ }
+ }
+
+ _gcry_rmd160_mixblock ( &md, hashbuf);
+ memcpy(p, hashbuf, 20 );
+ }
+
+ /* Our hash implementation does only leave small parts (64 bytes)
+ of the pool on the stack, so it is okay not to require secure
+ memory here. Before we use this pool, it will be copied to the
+ help buffer anyway. */
+ if ( pool == rndpool)
+ {
+ _gcry_rmd160_hash_buffer (failsafe_digest, pool, POOLSIZE);
+ failsafe_digest_valid = 1;
+ }
+
+ _gcry_burn_stack (384); /* for the rmd160_mixblock(), rmd160_hash_buffer */
+}
+
+
+void
+_gcry_rngcsprng_set_seed_file (const char *name)
+{
+ if (seed_file_name)
+ BUG ();
+ seed_file_name = gcry_xstrdup (name);
+}
+
+
+/* Lock an open file identified by file descriptor FD and wait a
+ reasonable time to succeed. With FOR_WRITE set to true a write
+ lock will be taken. FNAME is used only for diagnostics. Returns 0
+ on success or -1 on error. */
+static int
+lock_seed_file (int fd, const char *fname, int for_write)
+{
+#ifdef __GCC__
+#warning Check whether we can lock on Windows.
+#endif
+#if LOCK_SEED_FILE
+ struct flock lck;
+ struct timeval tv;
+ int backoff=0;
+
+ /* We take a lock on the entire file. */
+ memset (&lck, 0, sizeof lck);
+ lck.l_type = for_write? F_WRLCK : F_RDLCK;
+ lck.l_whence = SEEK_SET;
+
+ while (fcntl (fd, F_SETLK, &lck) == -1)
+ {
+ if (errno != EAGAIN && errno != EACCES)
+ {
+ log_info (_("can't lock `%s': %s\n"), fname, strerror (errno));
+ return -1;
+ }
+
+ if (backoff > 2) /* Show the first message after ~2.25 seconds. */
+ log_info( _("waiting for lock on `%s'...\n"), fname);
+
+ tv.tv_sec = backoff;
+ tv.tv_usec = 250000;
+ select (0, NULL, NULL, NULL, &tv);
+ if (backoff < 10)
+ backoff++ ;
+ }
+#endif /*!LOCK_SEED_FILE*/
+ return 0;
+}
+
+
+/* Read in a seed from the random_seed file and return true if this
+ was successful.
+
+ Note: Multiple instances of applications sharing the same random
+ seed file can be started in parallel, in which case they will read
+ out the same pool and then race for updating it (the last update
+ overwrites earlier updates). They will differentiate only by the
+ weak entropy that is added in read_seed_file based on the PID and
+ clock, and up to 16 bytes of weak random non-blockingly. The
+ consequence is that the output of these different instances is
+ correlated to some extent. In the perfect scenario, the attacker
+ can control (or at least guess) the PID and clock of the
+ application, and drain the system's entropy pool to reduce the "up
+ to 16 bytes" above to 0. Then the dependencies of the initial
+ states of the pools are completely known. */
+static int
+read_seed_file (void)
+{
+ int fd;
+ struct stat sb;
+ unsigned char buffer[POOLSIZE];
+ int n;
+
+ gcry_assert (pool_is_locked);
+
+ if (!seed_file_name)
+ return 0;
+
+#ifdef HAVE_DOSISH_SYSTEM
+ fd = open( seed_file_name, O_RDONLY | O_BINARY );
+#else
+ fd = open( seed_file_name, O_RDONLY );
+#endif
+ if( fd == -1 && errno == ENOENT)
+ {
+ allow_seed_file_update = 1;
+ return 0;
+ }
+
+ if (fd == -1 )
+ {
+ log_info(_("can't open `%s': %s\n"), seed_file_name, strerror(errno) );
+ return 0;
+ }
+ if (lock_seed_file (fd, seed_file_name, 0))
+ {
+ close (fd);
+ return 0;
+ }
+ if (fstat( fd, &sb ) )
+ {
+ log_info(_("can't stat `%s': %s\n"), seed_file_name, strerror(errno) );
+ close(fd);
+ return 0;
+ }
+ if (!S_ISREG(sb.st_mode) )
+ {
+ log_info(_("`%s' is not a regular file - ignored\n"), seed_file_name );
+ close(fd);
+ return 0;
+ }
+ if (!sb.st_size )
+ {
+ log_info(_("note: random_seed file is empty\n") );
+ close(fd);
+ allow_seed_file_update = 1;
+ return 0;
+ }
+ if (sb.st_size != POOLSIZE )
+ {
+ log_info(_("warning: invalid size of random_seed file - not used\n") );
+ close(fd);
+ return 0;
+ }
+
+ do
+ {
+ n = read( fd, buffer, POOLSIZE );
+ }
+ while (n == -1 && errno == EINTR );
+
+ if (n != POOLSIZE)
+ {
+ log_fatal(_("can't read `%s': %s\n"), seed_file_name,strerror(errno) );
+ close(fd);/*NOTREACHED*/
+ return 0;
+ }
+
+ close(fd);
+
+ add_randomness( buffer, POOLSIZE, RANDOM_ORIGIN_INIT );
+ /* add some minor entropy to the pool now (this will also force a mixing) */
+ {
+ pid_t x = getpid();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+ {
+ time_t x = time(NULL);
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+ {
+ clock_t x = clock();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_INIT );
+ }
+
+ /* And read a few bytes from our entropy source. By using a level
+ * of 0 this will not block and might not return anything with some
+ * entropy drivers, however the rndlinux driver will use
+ * /dev/urandom and return some stuff - Do not read too much as we
+ * want to be friendly to the scare system entropy resource. */
+ read_random_source ( RANDOM_ORIGIN_INIT, 16, GCRY_WEAK_RANDOM );
+
+ allow_seed_file_update = 1;
+ return 1;
+}
+
+
+void
+_gcry_rngcsprng_update_seed_file (void)
+{
+ unsigned long *sp, *dp;
+ int fd, i;
+
+ /* We do only a basic initialization so that we can lock the pool.
+ This is required to cope with the case that this function is
+ called by some cleanup code at a point where the RNG has never
+ been initialized. */
+ initialize_basics ();
+ lock_pool ();
+
+ if ( !seed_file_name || !rndpool || !pool_filled )
+ {
+ unlock_pool ();
+ return;
+ }
+ if ( !allow_seed_file_update )
+ {
+ unlock_pool ();
+ log_info(_("note: random_seed file not updated\n"));
+ return;
+ }
+
+ /* At this point we know that there is something in the pool and
+ thus we can conclude that the pool has been fully initialized. */
+
+
+ /* Copy the entropy pool to a scratch pool and mix both of them. */
+ for (i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ {
+ *dp = *sp + ADD_VALUE;
+ }
+ mix_pool(rndpool); rndstats.mixrnd++;
+ mix_pool(keypool); rndstats.mixkey++;
+
+#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
+ fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,
+ S_IRUSR|S_IWUSR );
+#else
+# if LOCK_SEED_FILE
+ fd = open (seed_file_name, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR );
+# else
+ fd = open (seed_file_name, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
+# endif
+#endif
+
+ if (fd == -1 )
+ log_info (_("can't create `%s': %s\n"), seed_file_name, strerror(errno) );
+ else if (lock_seed_file (fd, seed_file_name, 1))
+ {
+ close (fd);
+ }
+#if LOCK_SEED_FILE
+ else if (ftruncate (fd, 0))
+ {
+ log_info(_("can't write `%s': %s\n"), seed_file_name, strerror(errno));
+ close (fd);
+ }
+#endif /*LOCK_SEED_FILE*/
+ else
+ {
+ do
+ {
+ i = write (fd, keypool, POOLSIZE );
+ }
+ while (i == -1 && errno == EINTR);
+ if (i != POOLSIZE)
+ log_info (_("can't write `%s': %s\n"),seed_file_name, strerror(errno));
+ if (close(fd))
+ log_info (_("can't close `%s': %s\n"),seed_file_name, strerror(errno));
+ }
+
+ unlock_pool ();
+}
+
+
+/* Read random out of the pool. This function is the core of the
+ public random functions. Note that Level GCRY_WEAK_RANDOM is not
+ anymore handled special and in fact is an alias in the API for
+ level GCRY_STRONG_RANDOM. Must be called with the pool already
+ locked. */
+static void
+read_pool (byte *buffer, size_t length, int level)
+{
+ int i;
+ unsigned long *sp, *dp;
+ /* The volatile is there to make sure the compiler does not optimize
+ the code away in case the getpid function is badly attributed.
+ Note that we keep a pid in a static variable as well as in a
+ stack based one; the latter is to detect ill behaving thread
+ libraries, ignoring the pool mutexes. */
+ static volatile pid_t my_pid = (pid_t)(-1);
+ volatile pid_t my_pid2;
+
+ gcry_assert (pool_is_locked);
+
+ retry:
+ /* Get our own pid, so that we can detect a fork. */
+ my_pid2 = getpid ();
+ if (my_pid == (pid_t)(-1))
+ my_pid = my_pid2;
+ if ( my_pid != my_pid2 )
+ {
+ /* We detected a plain fork; i.e. we are now the child. Update
+ the static pid and add some randomness. */
+ pid_t x;
+
+ my_pid = my_pid2;
+ x = my_pid;
+ add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT);
+ just_mixed = 0; /* Make sure it will get mixed. */
+ }
+
+ gcry_assert (pool_is_locked);
+
+ /* Our code does not allow to extract more than POOLSIZE. Better
+ check it here. */
+ if (length > POOLSIZE)
+ {
+ log_bug("too many random bits requested\n");
+ }
+
+ if (!pool_filled)
+ {
+ if (read_seed_file() )
+ pool_filled = 1;
+ }
+
+ /* For level 2 quality (key generation) we always make sure that the
+ pool has been seeded enough initially. */
+ if (level == GCRY_VERY_STRONG_RANDOM && !did_initial_extra_seeding)
+ {
+ size_t needed;
+
+ pool_balance = 0;
+ needed = length - pool_balance;
+ if (needed < POOLSIZE/2)
+ needed = POOLSIZE/2;
+ else if( needed > POOLSIZE )
+ BUG ();
+ read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed,
+ GCRY_VERY_STRONG_RANDOM);
+ pool_balance += needed;
+ did_initial_extra_seeding = 1;
+ }
+
+ /* For level 2 make sure that there is enough random in the pool. */
+ if (level == GCRY_VERY_STRONG_RANDOM && pool_balance < length)
+ {
+ size_t needed;
+
+ if (pool_balance < 0)
+ pool_balance = 0;
+ needed = length - pool_balance;
+ if (needed > POOLSIZE)
+ BUG ();
+ read_random_source (RANDOM_ORIGIN_EXTRAPOLL, needed,
+ GCRY_VERY_STRONG_RANDOM);
+ pool_balance += needed;
+ }
+
+ /* Make sure the pool is filled. */
+ while (!pool_filled)
+ random_poll();
+
+ /* Always do a fast random poll (we have to use the unlocked version). */
+ do_fast_random_poll();
+
+ /* Mix the pid in so that we for sure won't deliver the same random
+ after a fork. */
+ {
+ pid_t apid = my_pid;
+ add_randomness (&apid, sizeof (apid), RANDOM_ORIGIN_INIT);
+ }
+
+ /* Mix the pool (if add_randomness() didn't it). */
+ if (!just_mixed)
+ {
+ mix_pool(rndpool);
+ rndstats.mixrnd++;
+ }
+
+ /* Create a new pool. */
+ for(i=0,dp=(unsigned long*)keypool, sp=(unsigned long*)rndpool;
+ i < POOLWORDS; i++, dp++, sp++ )
+ *dp = *sp + ADD_VALUE;
+
+ /* Mix both pools. */
+ mix_pool(rndpool); rndstats.mixrnd++;
+ mix_pool(keypool); rndstats.mixkey++;
+
+ /* Read the requested data. We use a read pointer to read from a
+ different position each time. */
+ while (length--)
+ {
+ *buffer++ = keypool[pool_readpos++];
+ if (pool_readpos >= POOLSIZE)
+ pool_readpos = 0;
+ pool_balance--;
+ }
+
+ if (pool_balance < 0)
+ pool_balance = 0;
+
+ /* Clear the keypool. */
+ memset (keypool, 0, POOLSIZE);
+
+ /* We need to detect whether a fork has happened. A fork might have
+ an identical pool and thus the child and the parent could emit
+ the very same random number. This test here is to detect forks
+ in a multi-threaded process. It does not work with all thread
+ implementations in particular not with pthreads. However it is
+ good enough for GNU Pth. */
+ if ( getpid () != my_pid2 )
+ {
+ pid_t x = getpid();
+ add_randomness (&x, sizeof(x), RANDOM_ORIGIN_INIT);
+ just_mixed = 0; /* Make sure it will get mixed. */
+ my_pid = x; /* Also update the static pid. */
+ goto retry;
+ }
+}
+
+
+
+/* Add LENGTH bytes of randomness from buffer to the pool. ORIGIN is
+ used to specify the randomness origin. This is one of the
+ RANDOM_ORIGIN_* values. */
+static void
+add_randomness (const void *buffer, size_t length, enum random_origins origin)
+{
+ const unsigned char *p = buffer;
+ size_t count = 0;
+
+ gcry_assert (pool_is_locked);
+
+ rndstats.addbytes += length;
+ rndstats.naddbytes++;
+ while (length-- )
+ {
+ rndpool[pool_writepos++] ^= *p++;
+ count++;
+ if (pool_writepos >= POOLSIZE )
+ {
+ /* It is possible that we are invoked before the pool is
+ filled using an unreliable origin of entropy, for example
+ the fast random poll. To avoid flagging the pool as
+ filled in this case, we track the initial filling state
+ separately. See also the remarks about the seed file. */
+ if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled)
+ {
+ pool_filled_counter += count;
+ count = 0;
+ if (pool_filled_counter >= POOLSIZE)
+ pool_filled = 1;
+ }
+ pool_writepos = 0;
+ mix_pool(rndpool); rndstats.mixrnd++;
+ just_mixed = !length;
+ }
+ }
+}
+
+
+
+static void
+random_poll()
+{
+ rndstats.slowpolls++;
+ read_random_source (RANDOM_ORIGIN_SLOWPOLL, POOLSIZE/5, GCRY_STRONG_RANDOM);
+}
+
+
+/* Runtime determination of the slow entropy gathering module. */
+static int (*
+getfnc_gather_random (void))(void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins, size_t, int)
+{
+ int (*fnc)(void (*)(const void*, size_t, enum random_origins),
+ enum random_origins, size_t, int);
+
+#if USE_RNDLINUX
+ if ( !access (NAME_OF_DEV_RANDOM, R_OK)
+ && !access (NAME_OF_DEV_URANDOM, R_OK))
+ {
+ fnc = _gcry_rndlinux_gather_random;
+ return fnc;
+ }
+#endif
+
+#if USE_RNDEGD
+ if ( _gcry_rndegd_connect_socket (1) != -1 )
+ {
+ fnc = _gcry_rndegd_gather_random;
+ return fnc;
+ }
+#endif
+
+#if USE_RNDUNIX
+ fnc = _gcry_rndunix_gather_random;
+ return fnc;
+#endif
+
+#if USE_RNDW32
+ fnc = _gcry_rndw32_gather_random;
+ return fnc;
+#endif
+
+#if USE_RNDW32CE
+ fnc = _gcry_rndw32ce_gather_random;
+ return fnc;
+#endif
+
+ log_fatal (_("no entropy gathering module detected\n"));
+
+ return NULL; /*NOTREACHED*/
+}
+
+/* Runtime determination of the fast entropy gathering function.
+ (Currently a compile time method is used.) */
+static void (*
+getfnc_fast_random_poll (void))( void (*)(const void*, size_t,
+ enum random_origins),
+ enum random_origins)
+{
+#if USE_RNDW32
+ return _gcry_rndw32_gather_random_fast;
+#endif
+#if USE_RNDW32CE
+ return _gcry_rndw32ce_gather_random_fast;
+#endif
+ return NULL;
+}
+
+
+
+static void
+do_fast_random_poll (void)
+{
+ gcry_assert (pool_is_locked);
+
+ rndstats.fastpolls++;
+
+ if (fast_gather_fnc)
+ fast_gather_fnc (add_randomness, RANDOM_ORIGIN_FASTPOLL);
+
+ /* Continue with the generic functions. */
+#if HAVE_GETHRTIME
+ {
+ hrtime_t tv;
+ tv = gethrtime();
+ add_randomness( &tv, sizeof(tv), RANDOM_ORIGIN_FASTPOLL );
+ }
+#elif HAVE_GETTIMEOFDAY
+ {
+ struct timeval tv;
+ if( gettimeofday( &tv, NULL ) )
+ BUG();
+ add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
+ add_randomness( &tv.tv_usec, sizeof(tv.tv_usec), RANDOM_ORIGIN_FASTPOLL );
+ }
+#elif HAVE_CLOCK_GETTIME
+ { struct timespec tv;
+ if( clock_gettime( CLOCK_REALTIME, &tv ) == -1 )
+ BUG();
+ add_randomness( &tv.tv_sec, sizeof(tv.tv_sec), RANDOM_ORIGIN_FASTPOLL );
+ add_randomness( &tv.tv_nsec, sizeof(tv.tv_nsec), RANDOM_ORIGIN_FASTPOLL );
+ }
+#else /* use times */
+# ifndef HAVE_DOSISH_SYSTEM
+ { struct tms buf;
+ times( &buf );
+ add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
+ }
+# endif
+#endif
+
+#ifdef HAVE_GETRUSAGE
+# ifdef RUSAGE_SELF
+ {
+ struct rusage buf;
+ /* QNX/Neutrino does return ENOSYS - so we just ignore it and add
+ whatever is in buf. In a chroot environment it might not work
+ at all (i.e. because /proc/ is not accessible), so we better
+ ignore all error codes and hope for the best. */
+ getrusage (RUSAGE_SELF, &buf );
+ add_randomness( &buf, sizeof buf, RANDOM_ORIGIN_FASTPOLL );
+ memset( &buf, 0, sizeof buf );
+ }
+# else /*!RUSAGE_SELF*/
+# ifdef __GCC__
+# warning There is no RUSAGE_SELF on this system
+# endif
+# endif /*!RUSAGE_SELF*/
+#endif /*HAVE_GETRUSAGE*/
+
+ /* Time and clock are availabe on all systems - so we better do it
+ just in case one of the above functions didn't work. */
+ {
+ time_t x = time(NULL);
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
+ }
+ {
+ clock_t x = clock();
+ add_randomness( &x, sizeof(x), RANDOM_ORIGIN_FASTPOLL );
+ }
+
+ /* If the system features a fast hardware RNG, read some bytes from
+ there. */
+ _gcry_rndhw_poll_fast (add_randomness, RANDOM_ORIGIN_FASTPOLL);
+}
+
+
+/* The fast random pool function as called at some places in
+ libgcrypt. This is merely a wrapper to make sure that this module
+ is initialized and to lock the pool. Note, that this function is a
+ NOP unless a random function has been used or _gcry_initialize (1)
+ has been used. We use this hack so that the internal use of this
+ function in cipher_open and md_open won't start filling up the
+ random pool, even if no random will be required by the process. */
+void
+_gcry_rngcsprng_fast_poll (void)
+{
+ initialize_basics ();
+
+ lock_pool ();
+ if (rndpool)
+ {
+ /* Yes, we are fully initialized. */
+ do_fast_random_poll ();
+ }
+ unlock_pool ();
+}
+
+
+
+static void
+read_random_source (enum random_origins orgin, size_t length, int level )
+{
+ if ( !slow_gather_fnc )
+ log_fatal ("Slow entropy gathering module not yet initialized\n");
+
+ if ( slow_gather_fnc (add_randomness, orgin, length, level) < 0)
+ log_fatal ("No way to gather entropy for the RNG\n");
+}
+
+
+static int
+gather_faked (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin, size_t length, int level )
+{
+ static int initialized=0;
+ size_t n;
+ char *buffer, *p;
+
+ (void)add;
+ (void)level;
+
+ if ( !initialized )
+ {
+ log_info(_("WARNING: using insecure random number generator!!\n"));
+ initialized=1;
+#ifdef HAVE_RAND
+ srand( time(NULL)*getpid());
+#else
+ srandom( time(NULL)*getpid());
+#endif
+ }
+
+ p = buffer = gcry_xmalloc( length );
+ n = length;
+#ifdef HAVE_RAND
+ while ( n-- )
+ *p++ = ((unsigned)(1 + (int) (256.0*rand()/(RAND_MAX+1.0)))-1);
+#else
+ while ( n-- )
+ *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
+#endif
+ add_randomness ( buffer, length, origin );
+ gcry_free (buffer);
+ return 0; /* okay */
+}
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void
+_gcry_rngcsprng_create_nonce (void *buffer, size_t length)
+{
+ static unsigned char nonce_buffer[20+8];
+ static int nonce_buffer_initialized = 0;
+ static volatile pid_t my_pid; /* The volatile is there to make sure the
+ compiler does not optimize the code away
+ in case the getpid function is badly
+ attributed. */
+ volatile pid_t apid;
+ unsigned char *p;
+ size_t n;
+ int err;
+
+ /* Make sure we are initialized. */
+ initialize ();
+
+#ifdef USE_RANDOM_DAEMON
+ if (allow_daemon
+ && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length))
+ return; /* The daemon succeeded. */
+ allow_daemon = 0; /* Daemon failed - switch off. */
+#endif /*USE_RANDOM_DAEMON*/
+
+ /* Acquire the nonce buffer lock. */
+ err = ath_mutex_lock (&nonce_buffer_lock);
+ if (err)
+ log_fatal ("failed to acquire the nonce buffer lock: %s\n",
+ strerror (err));
+
+ apid = getpid ();
+ /* The first time initialize our buffer. */
+ if (!nonce_buffer_initialized)
+ {
+ time_t atime = time (NULL);
+ pid_t xpid = apid;
+
+ my_pid = apid;
+
+ if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
+ BUG ();
+
+ /* Initialize the first 20 bytes with a reasonable value so that
+ a failure of gcry_randomize won't affect us too much. Don't
+ care about the uninitialized remaining bytes. */
+ p = nonce_buffer;
+ memcpy (p, &xpid, sizeof xpid);
+ p += sizeof xpid;
+ memcpy (p, &atime, sizeof atime);
+
+ /* Initialize the never changing private part of 64 bits. */
+ gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+
+ nonce_buffer_initialized = 1;
+ }
+ else if ( my_pid != apid )
+ {
+ /* We forked. Need to reseed the buffer - doing this for the
+ private part should be sufficient. */
+ gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+ /* Update the pid so that we won't run into here again and
+ again. */
+ my_pid = apid;
+ }
+
+ /* Create the nonce by hashing the entire buffer, returning the hash
+ and updating the first 20 bytes of the buffer with this hash. */
+ for (p = buffer; length > 0; length -= n, p += n)
+ {
+ _gcry_sha1_hash_buffer (nonce_buffer,
+ nonce_buffer, sizeof nonce_buffer);
+ n = length > 20? 20 : length;
+ memcpy (p, nonce_buffer, n);
+ }
+
+
+ /* Release the nonce buffer lock. */
+ err = ath_mutex_unlock (&nonce_buffer_lock);
+ if (err)
+ log_fatal ("failed to release the nonce buffer lock: %s\n",
+ strerror (err));
+
+}
--- /dev/null
+/* random-daemon.c - Access to the external random daemon
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/*
+ The functions here are used by random.c to divert calls to an
+ external random number daemon. The actual daemon we use is
+ gcryptrnd. Such a daemon is useful to keep a persistent pool in
+ memory over invocations of a single application and to allow
+ prioritizing access to the actual entropy sources. The drawback is
+ that we need to use IPC (i.e. unix domain socket) to convey
+ sensitive data.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "random.h"
+#include "ath.h"
+
+\f
+
+/* This is default socket name we use in case the provided socket name
+ is NULL. */
+#define RANDOM_DAEMON_SOCKET "/var/run/libgcrypt/S.gcryptrnd"
+
+/* The lock serializing access to the daemon. */
+static ath_mutex_t daemon_lock = ATH_MUTEX_INITIALIZER;
+
+/* The socket connected to the daemon. */
+static int daemon_socket = -1;
+
+/* Creates a socket connected to the daemon. On success, store the
+ socket fd in *SOCK. Returns error code. */
+static gcry_error_t
+connect_to_socket (const char *socketname, int *sock)
+{
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ gcry_error_t err;
+ int fd;
+ int rc;
+
+ srvr_addr = NULL;
+
+ /* Create a socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ log_error ("can't create socket: %s\n", strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ /* Set up address. */
+ srvr_addr = gcry_malloc (sizeof *srvr_addr);
+ if (! srvr_addr)
+ {
+ log_error ("malloc failed: %s\n", strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ log_error ("socket name `%s' too long\n", socketname);
+ err = gcry_error (GPG_ERR_ENAMETOOLONG);
+ goto out;
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+
+ /* Connect socket. */
+ rc = connect (fd, (struct sockaddr *) srvr_addr, addrlen);
+ if (rc == -1)
+ {
+ log_error ("error connecting socket `%s': %s\n",
+ srvr_addr->sun_path, strerror (errno));
+ err = gcry_error_from_errno (errno);
+ goto out;
+ }
+
+ err = 0;
+
+ out:
+
+ gcry_free (srvr_addr);
+ if (err)
+ {
+ close (fd);
+ fd = -1;
+ }
+ *sock = fd;
+
+ return err;
+}
+
+
+/* Initialize basics of this module. This should be viewed as a
+ constructor to prepare locking. */
+void
+_gcry_daemon_initialize_basics (void)
+{
+ static int initialized;
+ int err;
+
+ if (!initialized)
+ {
+ initialized = 1;
+ err = ath_mutex_init (&daemon_lock);
+ if (err)
+ log_fatal ("failed to create the daemon lock: %s\n", strerror (err) );
+ }
+}
+
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ ssize_t n;
+
+ while (length)
+ {
+ do
+ n = ath_write (fd, buffer, length);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ log_error ("write error: %s\n", strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char*)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+static int
+readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
+{
+ size_t nleft = buflen;
+ int nread;
+ char *p;
+
+ p = buf;
+ while (nleft > 0)
+ {
+ nread = ath_read (fd, buf, nleft);
+ if (nread < 0)
+ {
+ if (nread == EINTR)
+ nread = 0;
+ else
+ return -1;
+ }
+ else if (!nread)
+ break; /* EOF */
+ nleft -= nread;
+ buf = (char*)buf + nread;
+ }
+ if (ret_nread)
+ *ret_nread = buflen - nleft;
+ return 0;
+}
+
+/* This functions requests REQ_NBYTES from the daemon. If NONCE is
+ true, the data should be suited for a nonce. If NONCE is FALSE,
+ data of random level LEVEL will be generated. The retrieved random
+ data will be stored in BUFFER. Returns error code. */
+static gcry_error_t
+call_daemon (const char *socketname,
+ void *buffer, size_t req_nbytes, int nonce,
+ enum gcry_random_level level)
+{
+ static int initialized;
+ unsigned char buf[255];
+ gcry_error_t err = 0;
+ size_t nbytes;
+ size_t nread;
+ int rc;
+
+ if (!req_nbytes)
+ return 0;
+
+ ath_mutex_lock (&daemon_lock);
+
+ /* Open the socket if that has not been done. */
+ if (!initialized)
+ {
+ initialized = 1;
+ err = connect_to_socket (socketname ? socketname : RANDOM_DAEMON_SOCKET,
+ &daemon_socket);
+ if (err)
+ {
+ daemon_socket = -1;
+ log_info ("not using random daemon\n");
+ ath_mutex_unlock (&daemon_lock);
+ return err;
+ }
+ }
+
+ /* Check that we have a valid socket descriptor. */
+ if ( daemon_socket == -1 )
+ {
+ ath_mutex_unlock (&daemon_lock);
+ return gcry_error (GPG_ERR_INTERNAL);
+ }
+
+
+ /* Do the real work. */
+
+ do
+ {
+ /* Process in chunks. */
+ nbytes = req_nbytes > sizeof (buf) ? sizeof (buf) : req_nbytes;
+ req_nbytes -= nbytes;
+
+ /* Construct request. */
+ buf[0] = 3;
+ if (nonce)
+ buf[1] = 10;
+ else if (level == GCRY_VERY_STRONG_RANDOM)
+ buf[1] = 12;
+ else if (level == GCRY_STRONG_RANDOM)
+ buf[1] = 11;
+ buf[2] = nbytes;
+
+ /* Send request. */
+ rc = writen (daemon_socket, buf, 3);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ break;
+ }
+
+ /* Retrieve response. */
+
+ rc = readn (daemon_socket, buf, 2, &nread);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ log_error ("read error: %s\n", gcry_strerror (err));
+ break;
+ }
+ if (nread && buf[0])
+ {
+ log_error ("random daemon returned error code %d\n", buf[0]);
+ err = gcry_error (GPG_ERR_INTERNAL); /* ? */
+ break;
+ }
+ if (nread != 2)
+ {
+ log_error ("response too small\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+
+ /* if (1)*/ /* Do this in verbose mode? */
+ /* log_info ("received response with %d bytes of data\n", buf[1]);*/
+
+ if (buf[1] < nbytes)
+ {
+ log_error ("error: server returned less bytes than requested\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+ else if (buf[1] > nbytes)
+ {
+ log_error ("warning: server returned more bytes than requested\n");
+ err = gcry_error (GPG_ERR_PROTOCOL_VIOLATION); /* ? */
+ break;
+ }
+
+ assert (nbytes <= sizeof (buf));
+
+ rc = readn (daemon_socket, buf, nbytes, &nread);
+ if (rc == -1)
+ {
+ err = gcry_error_from_errno (errno);
+ log_error ("read error: %s\n", gcry_strerror (err));
+ break;
+ }
+
+ if (nread != nbytes)
+ {
+ log_error ("too little random data read\n");
+ err = gcry_error (GPG_ERR_INTERNAL);
+ break;
+ }
+
+ /* Successfuly read another chunk of data. */
+ memcpy (buffer, buf, nbytes);
+ buffer = ((char *) buffer) + nbytes;
+ }
+ while (req_nbytes);
+
+ ath_mutex_unlock (&daemon_lock);
+
+ return err;
+}
+
+/* Internal function to fill BUFFER with LENGTH bytes of random. We
+ support GCRY_STRONG_RANDOM and GCRY_VERY_STRONG_RANDOM here.
+ Return 0 on success. */
+int
+_gcry_daemon_randomize (const char *socketname,
+ void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ gcry_error_t err;
+
+ err = call_daemon (socketname, buffer, length, 0, level);
+
+ return err ? -1 : 0;
+}
+
+
+/* Internal function to fill BUFFER with NBYTES of data usable for a
+ nonce. Returns 0 on success. */
+int
+_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length)
+{
+ gcry_error_t err;
+
+ err = call_daemon (socketname, buffer, length, 1, 0);
+
+ return err ? -1 : 0;
+}
+
+/* END */
--- /dev/null
+/* random-fips.c - FIPS style random number generator
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ The core of this deterministic random number generator is
+ implemented according to the document "NIST-Recommended Random
+ Number Generator Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key
+ Triple DES and AES Algorithms" (2005-01-31). This implementation
+ uses the AES variant.
+
+ There are 3 random context which map to the different levels of
+ random quality:
+
+ Generator Seed and Key Kernel entropy (init/reseed)
+ ------------------------------------------------------------
+ GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits
+ GCRY_STRONG_RANDOM /dev/random 256/128 bits
+ gcry_create_nonce GCRY_STRONG_RANDOM n/a
+
+ All random generators return their data in 128 bit blocks. If the
+ caller requested less bits, the extra bits are not used. The key
+ for each generator is only set once at the first time a generator
+ is used. The seed value is set with the key and again after 1000
+ (SEED_TTL) output blocks; the re-seeding is disabled in test mode.
+
+ The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are
+ keyed and seeded from the /dev/random device. Thus these
+ generators may block until the kernel has collected enough entropy.
+
+ The gcry_create_nonce generator is keyed and seeded from the
+ GCRY_STRONG_RANDOM generator. It may also block if the
+ GCRY_STRONG_RANDOM generator has not yet been used before and thus
+ gets initialized on the first use by gcry_create_nonce. This
+ special treatment is justified by the weaker requirements for a
+ nonce generator and to save precious kernel entropy for use by the
+ real random generators.
+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#endif
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "ath.h"
+
+/* This is the lock we use to serialize access to this RNG. The extra
+ integer variable is only used to check the locking state; that is,
+ it is not meant to be thread-safe but merely as a failsafe feature
+ to assert proper locking. */
+static ath_mutex_t fips_rng_lock = ATH_MUTEX_INITIALIZER;
+static int fips_rng_is_locked;
+
+
+/* The required size for the temporary buffer of the x931_aes_driver
+ function and the buffer itself which will be allocated in secure
+ memory. This needs to be global variable for proper initialization
+ and to allow shutting down the RNG without leaking memory. May
+ only be used while holding the FIPS_RNG_LOCK.
+
+ This variable is also used to avoid duplicate initialization. */
+#define TEMPVALUE_FOR_X931_AES_DRIVER_SIZE 48
+static unsigned char *tempvalue_for_x931_aes_driver;
+
+
+/* After having retrieved this number of blocks from the RNG, we want
+ to do a reseeding. */
+#define SEED_TTL 1000
+
+
+/* The length of the key we use: 16 bytes (128 bit) for AES128. */
+#define X931_AES_KEYLEN 16
+/* A global buffer used to communicate between the x931_generate_key
+ and x931_generate_seed functions and the entropy_collect_cb
+ function. It may only be used by these functions. */
+static unsigned char *entropy_collect_buffer; /* Buffer. */
+static size_t entropy_collect_buffer_len; /* Used length. */
+static size_t entropy_collect_buffer_size; /* Allocated length. */
+
+
+/* This random context type is used to track properties of one random
+ generator. Thee context are usually allocated in secure memory so
+ that the seed value is well protected. There are a couble of guard
+ fields to help detecting applications accidently overwriting parts
+ of the memory. */
+struct rng_context
+{
+ unsigned char guard_0[1];
+
+ /* The handle of the cipher used by the RNG. If this one is not
+ NULL a cipher handle along with a random key has been
+ established. */
+ gcry_cipher_hd_t cipher_hd;
+
+ /* If this flag is true, the SEED_V buffer below carries a valid
+ seed. */
+ int is_seeded:1;
+
+ /* The very first block generated is used to compare the result
+ against the last result. This flag indicates that such a block
+ is available. */
+ int compare_value_valid:1;
+
+ /* A counter used to trigger re-seeding. */
+ unsigned int use_counter;
+
+ unsigned char guard_1[1];
+
+ /* The buffer containing the seed value V. */
+ unsigned char seed_V[16];
+
+ unsigned char guard_2[1];
+
+ /* The last result from the x931_aes function. Only valid if
+ compare_value_valid is set. */
+ unsigned char compare_value[16];
+
+ unsigned char guard_3[1];
+
+ /* The external test may want to suppress the duplicate bock check.
+ This is done if the this flag is set. */
+ unsigned char test_no_dup_check;
+ /* To implement a KAT we need to provide a know DT value. To
+ accomplish this the x931_get_dt function checks whether this
+ field is not NULL and then uses the 16 bytes at this address for
+ the DT value. However the last 4 bytes are replaced by the
+ value of field TEST_DT_COUNTER which will be incremented after
+ each invocation of x931_get_dt. We use a pointer and not a buffer
+ because there is no need to put this value into secure memory. */
+ const unsigned char *test_dt_ptr;
+ u32 test_dt_counter;
+
+ /* We need to keep track of the process which did the initialization
+ so that we can detect a fork. The volatile modifier is required
+ so that the compiler does not optimize it away in case the getpid
+ function is badly attributed. */
+ pid_t key_init_pid;
+ pid_t seed_init_pid;
+};
+typedef struct rng_context *rng_context_t;
+
+
+/* The random context used for the nonce generator. May only be used
+ while holding the FIPS_RNG_LOCK. */
+static rng_context_t nonce_context;
+/* The random context used for the standard random generator. May
+ only be used while holding the FIPS_RNG_LOCK. */
+static rng_context_t std_rng_context;
+/* The random context used for the very strong random generator. May
+ only be used while holding the FIPS_RNG_LOCK. */
+static rng_context_t strong_rng_context;
+
+
+/* --- Local prototypes --- */
+static void x931_reseed (rng_context_t rng_ctx);
+static void get_random (void *buffer, size_t length, rng_context_t rng_ctx);
+
+
+
+\f
+/* --- Functions --- */
+
+/* Basic initialization is required to initialize mutexes and
+ do a few checks on the implementation. */
+static void
+basic_initialization (void)
+{
+ static int initialized;
+ int my_errno;
+
+ if (!initialized)
+ return;
+ initialized = 1;
+
+ my_errno = ath_mutex_init (&fips_rng_lock);
+ if (my_errno)
+ log_fatal ("failed to create the RNG lock: %s\n", strerror (my_errno));
+ fips_rng_is_locked = 0;
+
+ /* Make sure that we are still using the values we have
+ traditionally used for the random levels. */
+ gcry_assert (GCRY_WEAK_RANDOM == 0
+ && GCRY_STRONG_RANDOM == 1
+ && GCRY_VERY_STRONG_RANDOM == 2);
+
+}
+
+
+/* Acquire the fips_rng_lock. */
+static void
+lock_rng (void)
+{
+ int my_errno;
+
+ my_errno = ath_mutex_lock (&fips_rng_lock);
+ if (my_errno)
+ log_fatal ("failed to acquire the RNG lock: %s\n", strerror (my_errno));
+ fips_rng_is_locked = 1;
+}
+
+
+/* Release the fips_rng_lock. */
+static void
+unlock_rng (void)
+{
+ int my_errno;
+
+ fips_rng_is_locked = 0;
+ my_errno = ath_mutex_unlock (&fips_rng_lock);
+ if (my_errno)
+ log_fatal ("failed to release the RNG lock: %s\n", strerror (my_errno));
+}
+
+static void
+setup_guards (rng_context_t rng_ctx)
+{
+ /* Set the guards to some arbitrary values. */
+ rng_ctx->guard_0[0] = 17;
+ rng_ctx->guard_1[0] = 42;
+ rng_ctx->guard_2[0] = 137;
+ rng_ctx->guard_3[0] = 252;
+}
+
+static void
+check_guards (rng_context_t rng_ctx)
+{
+ if ( rng_ctx->guard_0[0] != 17
+ || rng_ctx->guard_1[0] != 42
+ || rng_ctx->guard_2[0] != 137
+ || rng_ctx->guard_3[0] != 252 )
+ log_fatal ("memory corruption detected in RNG context %p\n", rng_ctx);
+}
+
+
+/* Get the DT vector for use with the core PRNG function. Buffer
+ needs to be provided by the caller with a size of at least LENGTH
+ bytes. RNG_CTX needs to be passed to allow for a KAT. The 16 byte
+ timestamp we construct is made up the real time and three counters:
+
+ Buffer: 00112233445566778899AABBCCDDEEFF
+ !--+---!!-+-!!+!!--+---!!--+---!
+ seconds ---------/ | | | |
+ microseconds -----------/ | | |
+ counter2 -------------------/ | |
+ counter1 ------------------------/ |
+ counter0 --------------------------------/
+
+ Counter 2 is just 12 bits wide and used to track fractions of
+ milliseconds whereas counters 1 and 0 are combined to a free
+ running 64 bit counter. */
+static void
+x931_get_dt (unsigned char *buffer, size_t length, rng_context_t rng_ctx)
+{
+ gcry_assert (length == 16); /* This length is required for use with AES. */
+ gcry_assert (fips_rng_is_locked);
+
+ /* If the random context indicates that a test DT should be used,
+ take the DT value from the context. For safety reasons we do
+ this only if the context is not one of the regular contexts. */
+ if (rng_ctx->test_dt_ptr
+ && rng_ctx != nonce_context
+ && rng_ctx != std_rng_context
+ && rng_ctx != strong_rng_context)
+ {
+ memcpy (buffer, rng_ctx->test_dt_ptr, 16);
+ buffer[12] = (rng_ctx->test_dt_counter >> 24);
+ buffer[13] = (rng_ctx->test_dt_counter >> 16);
+ buffer[14] = (rng_ctx->test_dt_counter >> 8);
+ buffer[15] = rng_ctx->test_dt_counter;
+ rng_ctx->test_dt_counter++;
+ return;
+ }
+
+
+#if HAVE_GETTIMEOFDAY
+ {
+ static u32 last_sec, last_usec;
+ static u32 counter1, counter0;
+ static u16 counter2;
+
+ unsigned int usec;
+ struct timeval tv;
+
+ if (!last_sec)
+ {
+ /* This is the very first time we are called: Set the counters
+ to an not so easy predictable value to avoid always
+ starting at 0. Not really needed but it doesn't harm. */
+ counter1 = (u32)getpid ();
+#ifndef HAVE_W32_SYSTEM
+ counter0 = (u32)getppid ();
+#endif
+ }
+
+
+ if (gettimeofday (&tv, NULL))
+ log_fatal ("gettimeofday() failed: %s\n", strerror (errno));
+
+ /* The microseconds part is always less than 1 millon (0x0f4240).
+ Thus we don't care about the MSB and in addition shift it to
+ the left by 4 bits. */
+ usec = tv.tv_usec;
+ usec <<= 4;
+ /* If we got the same time as by the last invocation, bump up
+ counter2 and save the time for the next invocation. */
+ if (tv.tv_sec == last_sec && usec == last_usec)
+ {
+ counter2++;
+ counter2 &= 0x0fff;
+ }
+ else
+ {
+ counter2 = 0;
+ last_sec = tv.tv_sec;
+ last_usec = usec;
+ }
+ /* Fill the buffer with the timestamp. */
+ buffer[0] = ((tv.tv_sec >> 24) & 0xff);
+ buffer[1] = ((tv.tv_sec >> 16) & 0xff);
+ buffer[2] = ((tv.tv_sec >> 8) & 0xff);
+ buffer[3] = (tv.tv_sec & 0xff);
+ buffer[4] = ((usec >> 16) & 0xff);
+ buffer[5] = ((usec >> 8) & 0xff);
+ buffer[6] = ((usec & 0xf0) | ((counter2 >> 8) & 0x0f));
+ buffer[7] = (counter2 & 0xff);
+ /* Add the free running counter. */
+ buffer[8] = ((counter1 >> 24) & 0xff);
+ buffer[9] = ((counter1 >> 16) & 0xff);
+ buffer[10] = ((counter1 >> 8) & 0xff);
+ buffer[11] = ((counter1) & 0xff);
+ buffer[12] = ((counter0 >> 24) & 0xff);
+ buffer[13] = ((counter0 >> 16) & 0xff);
+ buffer[14] = ((counter0 >> 8) & 0xff);
+ buffer[15] = ((counter0) & 0xff);
+ /* Bump up that counter. */
+ if (!++counter0)
+ ++counter1;
+ }
+#else
+ log_fatal ("gettimeofday() not available on this system\n");
+#endif
+
+ /* log_printhex ("x931_get_dt: ", buffer, 16); */
+}
+
+
+/* XOR the buffers A and B which are each of LENGTH bytes and store
+ the result at R. R needs to be provided by the caller with a size
+ of at least LENGTH bytes. */
+static void
+xor_buffer (unsigned char *r,
+ const unsigned char *a, const unsigned char *b, size_t length)
+{
+ for ( ; length; length--, a++, b++, r++)
+ *r = (*a ^ *b);
+}
+
+
+/* Encrypt LENGTH bytes of INPUT to OUTPUT using KEY. LENGTH
+ needs to be 16. */
+static void
+encrypt_aes (gcry_cipher_hd_t key,
+ unsigned char *output, const unsigned char *input, size_t length)
+{
+ gpg_error_t err;
+
+ gcry_assert (length == 16);
+
+ err = gcry_cipher_encrypt (key, output, length, input, length);
+ if (err)
+ log_fatal ("AES encryption in RNG failed: %s\n", gcry_strerror (err));
+}
+
+
+/* The core ANSI X9.31, Appendix A.2.4 function using AES. The caller
+ needs to pass a 16 byte buffer for the result, the 16 byte
+ datetime_DT value and the 16 byte seed value V. The caller also
+ needs to pass an appropriate KEY and make sure to pass a valid
+ seed_V. The caller also needs to provide two 16 bytes buffer for
+ intermediate results, they may be reused by the caller later.
+
+ On return the result is stored at RESULT_R and the SEED_V is
+ updated. May only be used while holding the lock. */
+static void
+x931_aes (unsigned char result_R[16],
+ unsigned char datetime_DT[16], unsigned char seed_V[16],
+ gcry_cipher_hd_t key,
+ unsigned char intermediate_I[16], unsigned char temp_xor[16])
+{
+ /* Let ede*X(Y) represent the AES encryption of Y under the key *X.
+
+ Let V be a 128-bit seed value which is also kept secret, and XOR
+ be the exclusive-or operator. Let DT be a date/time vector which
+ is updated on each iteration. I is a intermediate value.
+
+ I = ede*K(DT) */
+ encrypt_aes (key, intermediate_I, datetime_DT, 16);
+
+ /* R = ede*K(I XOR V) */
+ xor_buffer (temp_xor, intermediate_I, seed_V, 16);
+ encrypt_aes (key, result_R, temp_xor, 16);
+
+ /* V = ede*K(R XOR I). */
+ xor_buffer (temp_xor, result_R, intermediate_I, 16);
+ encrypt_aes (key, seed_V, temp_xor, 16);
+
+ /* Zero out temporary values. */
+ wipememory (intermediate_I, 16);
+ wipememory (temp_xor, 16);
+}
+
+
+/* The high level driver to x931_aes. This one does the required
+ tests and calls the core function until the entire buffer has been
+ filled. OUTPUT is a caller provided buffer of LENGTH bytes to
+ receive the random, RNG_CTX is the context of the RNG. The context
+ must be properly initialized. Returns 0 on success. */
+static int
+x931_aes_driver (unsigned char *output, size_t length, rng_context_t rng_ctx)
+{
+ unsigned char datetime_DT[16];
+ unsigned char *intermediate_I, *temp_buffer, *result_buffer;
+ size_t nbytes;
+
+ gcry_assert (fips_rng_is_locked);
+ gcry_assert (rng_ctx->cipher_hd);
+ gcry_assert (rng_ctx->is_seeded);
+
+ gcry_assert (tempvalue_for_x931_aes_driver);
+ gcry_assert (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE == 48);
+ intermediate_I = tempvalue_for_x931_aes_driver;
+ temp_buffer = tempvalue_for_x931_aes_driver + 16;
+ result_buffer = tempvalue_for_x931_aes_driver + 32;
+
+ while (length)
+ {
+ /* Unless we are running with a test context, we require a new
+ seed after some time. */
+ if (!rng_ctx->test_dt_ptr && rng_ctx->use_counter > SEED_TTL)
+ {
+ x931_reseed (rng_ctx);
+ rng_ctx->use_counter = 0;
+ }
+
+ /* Due to the design of the RNG, we always receive 16 bytes (128
+ bit) of random even if we require less. The extra bytes
+ returned are not used. Intheory we could save them for the
+ next invocation, but that would make the control flow harder
+ to read. */
+ nbytes = length < 16? length : 16;
+
+ x931_get_dt (datetime_DT, 16, rng_ctx);
+ x931_aes (result_buffer,
+ datetime_DT, rng_ctx->seed_V, rng_ctx->cipher_hd,
+ intermediate_I, temp_buffer);
+ rng_ctx->use_counter++;
+
+ if (rng_ctx->test_no_dup_check
+ && rng_ctx->test_dt_ptr
+ && rng_ctx != nonce_context
+ && rng_ctx != std_rng_context
+ && rng_ctx != strong_rng_context)
+ {
+ /* This is a test context which does not want the duplicate
+ block check. */
+ }
+ else
+ {
+ /* Do a basic check on the output to avoid a stuck generator. */
+ if (!rng_ctx->compare_value_valid)
+ {
+ /* First time used, only save the result. */
+ memcpy (rng_ctx->compare_value, result_buffer, 16);
+ rng_ctx->compare_value_valid = 1;
+ continue;
+ }
+ if (!memcmp (rng_ctx->compare_value, result_buffer, 16))
+ {
+ /* Ooops, we received the same 128 bit block - that should
+ in theory never happen. The FIPS requirement says that
+ we need to put ourself into the error state in such
+ case. */
+ fips_signal_error ("duplicate 128 bit block returned by RNG");
+ return -1;
+ }
+ memcpy (rng_ctx->compare_value, result_buffer, 16);
+ }
+
+ /* Append to outbut. */
+ memcpy (output, result_buffer, nbytes);
+ wipememory (result_buffer, 16);
+ output += nbytes;
+ length -= nbytes;
+ }
+
+ return 0;
+}
+
+
+/* Callback for x931_generate_key. Note that this callback uses the
+ global ENTROPY_COLLECT_BUFFER which has been setup by get_entropy.
+ ORIGIN is not used but required due to the design of entropy
+ gathering module. */
+static void
+entropy_collect_cb (const void *buffer, size_t length,
+ enum random_origins origin)
+{
+ const unsigned char *p = buffer;
+
+ (void)origin;
+
+ gcry_assert (fips_rng_is_locked);
+ gcry_assert (entropy_collect_buffer);
+
+ /* Note that we need to protect against gatherers returning more
+ than the requested bytes (e.g. rndw32). */
+ while (length-- && entropy_collect_buffer_len < entropy_collect_buffer_size)
+ {
+ entropy_collect_buffer[entropy_collect_buffer_len++] ^= *p++;
+ }
+}
+
+
+/* Get NBYTES of entropy from the kernel device. The callers needs to
+ free the returned buffer. The function either succeeds or
+ terminates the process in case of a fatal error. */
+static void *
+get_entropy (size_t nbytes)
+{
+ void *result;
+ int rc;
+
+ gcry_assert (!entropy_collect_buffer);
+ entropy_collect_buffer = gcry_xmalloc_secure (nbytes);
+ entropy_collect_buffer_size = nbytes;
+ entropy_collect_buffer_len = 0;
+
+#if USE_RNDLINUX
+ rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0,
+ X931_AES_KEYLEN,
+ GCRY_VERY_STRONG_RANDOM);
+#elif USE_RNDW32
+ do
+ {
+ rc = _gcry_rndw32_gather_random (entropy_collect_cb, 0,
+ X931_AES_KEYLEN,
+ GCRY_VERY_STRONG_RANDOM);
+ }
+ while (rc >= 0 && entropy_collect_buffer_len < entropy_collect_buffer_size);
+#else
+ rc = -1;
+#endif
+
+ if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size)
+ {
+ gcry_free (entropy_collect_buffer);
+ entropy_collect_buffer = NULL;
+ log_fatal ("error getting entropy data\n");
+ }
+ result = entropy_collect_buffer;
+ entropy_collect_buffer = NULL;
+ return result;
+}
+
+
+/* Generate a key for use with x931_aes. The function returns a
+ handle to the cipher context readily prepared for ECB encryption.
+ If FOR_NONCE is true, the key is retrieved by readong random from
+ the standard generator. On error NULL is returned. */
+static gcry_cipher_hd_t
+x931_generate_key (int for_nonce)
+{
+ gcry_cipher_hd_t hd;
+ gpg_error_t err;
+ void *buffer;
+
+ gcry_assert (fips_rng_is_locked);
+
+ /* Allocate a cipher context. */
+ err = gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
+ GCRY_CIPHER_SECURE);
+ if (err)
+ {
+ log_error ("error creating cipher context for RNG: %s\n",
+ gcry_strerror (err));
+ return NULL;
+ }
+
+ /* Get a key from the standard RNG or from the entropy source. */
+ if (for_nonce)
+ {
+ buffer = gcry_xmalloc (X931_AES_KEYLEN);
+ get_random (buffer, X931_AES_KEYLEN, std_rng_context);
+ }
+ else
+ {
+ buffer = get_entropy (X931_AES_KEYLEN);
+ }
+
+ /* Set the key and delete the buffer because the key is now part of
+ the cipher context. */
+ err = gcry_cipher_setkey (hd, buffer, X931_AES_KEYLEN);
+ wipememory (buffer, X931_AES_KEYLEN);
+ gcry_free (buffer);
+ if (err)
+ {
+ log_error ("error creating key for RNG: %s\n", gcry_strerror (err));
+ gcry_cipher_close (hd);
+ return NULL;
+ }
+
+ return hd;
+}
+
+
+/* Generate a key for use with x931_aes. The function copies a seed
+ of LENGTH bytes into SEED_BUFFER. LENGTH needs to by given as 16. */
+static void
+x931_generate_seed (unsigned char *seed_buffer, size_t length)
+{
+ void *buffer;
+
+ gcry_assert (fips_rng_is_locked);
+ gcry_assert (length == 16);
+
+ buffer = get_entropy (X931_AES_KEYLEN);
+
+ memcpy (seed_buffer, buffer, X931_AES_KEYLEN);
+ wipememory (buffer, X931_AES_KEYLEN);
+ gcry_free (buffer);
+}
+
+
+
+/* Reseed a generator. This is also used for the initial seeding. */
+static void
+x931_reseed (rng_context_t rng_ctx)
+{
+ gcry_assert (fips_rng_is_locked);
+
+ if (rng_ctx == nonce_context)
+ {
+ /* The nonce context is special. It will be seeded using the
+ standard random generator. */
+ get_random (rng_ctx->seed_V, 16, std_rng_context);
+ rng_ctx->is_seeded = 1;
+ rng_ctx->seed_init_pid = getpid ();
+ }
+ else
+ {
+ /* The other two generators are seeded from /dev/random. */
+ x931_generate_seed (rng_ctx->seed_V, 16);
+ rng_ctx->is_seeded = 1;
+ rng_ctx->seed_init_pid = getpid ();
+ }
+}
+
+
+/* Core random function. This is used for both nonce and random
+ generator. The actual RNG to be used depends on the random context
+ RNG_CTX passed. Note that this function is called with the RNG not
+ yet locked. */
+static void
+get_random (void *buffer, size_t length, rng_context_t rng_ctx)
+{
+ gcry_assert (buffer);
+ gcry_assert (rng_ctx);
+
+ check_guards (rng_ctx);
+
+ /* Initialize the cipher handle and thus setup the key if needed. */
+ if (!rng_ctx->cipher_hd)
+ {
+ if (rng_ctx == nonce_context)
+ rng_ctx->cipher_hd = x931_generate_key (1);
+ else
+ rng_ctx->cipher_hd = x931_generate_key (0);
+ if (!rng_ctx->cipher_hd)
+ goto bailout;
+ rng_ctx->key_init_pid = getpid ();
+ }
+
+ /* Initialize the seed value if needed. */
+ if (!rng_ctx->is_seeded)
+ x931_reseed (rng_ctx);
+
+ if (rng_ctx->key_init_pid != getpid ()
+ || rng_ctx->seed_init_pid != getpid ())
+ {
+ /* We are in a child of us. Because we have no way yet to do
+ proper re-initialization (including self-checks etc), the
+ only chance we have is to bail out. Obviusly a fork/exec
+ won't harm because the exec overwrites the old image. */
+ fips_signal_error ("fork without proper re-initialization "
+ "detected in RNG");
+ goto bailout;
+ }
+
+ if (x931_aes_driver (buffer, length, rng_ctx))
+ goto bailout;
+
+ check_guards (rng_ctx);
+ return;
+
+ bailout:
+ log_fatal ("severe error getting random\n");
+ /*NOTREACHED*/
+}
+
+
+\f
+/* --- Public Functions --- */
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the basic initialization of the module and does not do
+ anything more. Doing this is not really required but when running
+ in a threaded environment we might get a race condition
+ otherwise. */
+void
+_gcry_rngfips_initialize (int full)
+{
+ basic_initialization ();
+ if (!full)
+ return;
+
+ /* Allocate temporary buffers. If that buffer already exists we
+ know that we are already initialized. */
+ lock_rng ();
+ if (!tempvalue_for_x931_aes_driver)
+ {
+ tempvalue_for_x931_aes_driver
+ = gcry_xmalloc_secure (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE);
+
+ /* Allocate the random contexts. Note that we do not need to use
+ secure memory for the nonce context. */
+ nonce_context = gcry_xcalloc (1, sizeof *nonce_context);
+ setup_guards (nonce_context);
+
+ std_rng_context = gcry_xcalloc_secure (1, sizeof *std_rng_context);
+ setup_guards (std_rng_context);
+
+ strong_rng_context = gcry_xcalloc_secure (1, sizeof *strong_rng_context);
+ setup_guards (strong_rng_context);
+ }
+ else
+ {
+ /* Already initialized. Do some sanity checks. */
+ gcry_assert (!nonce_context->test_dt_ptr);
+ gcry_assert (!std_rng_context->test_dt_ptr);
+ gcry_assert (!strong_rng_context->test_dt_ptr);
+ check_guards (nonce_context);
+ check_guards (std_rng_context);
+ check_guards (strong_rng_context);
+ }
+ unlock_rng ();
+}
+
+
+/* Print some statistics about the RNG. */
+void
+_gcry_rngfips_dump_stats (void)
+{
+ /* Not yet implemented. */
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_rngfips_is_faked (void)
+{
+ return 0; /* Faked random is not allowed. */
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_error_t
+_gcry_rngfips_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ (void)buf;
+ (void)buflen;
+ (void)quality;
+ return 0; /* Not implemented. */
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong
+ enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key
+ generation stuff but may be very slow. */
+void
+_gcry_rngfips_randomize (void *buffer, size_t length,
+ enum gcry_random_level level)
+{
+ _gcry_rngfips_initialize (1); /* Auto-initialize if needed. */
+
+ lock_rng ();
+ if (level == GCRY_VERY_STRONG_RANDOM)
+ get_random (buffer, length, strong_rng_context);
+ else
+ get_random (buffer, length, std_rng_context);
+ unlock_rng ();
+}
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void
+_gcry_rngfips_create_nonce (void *buffer, size_t length)
+{
+ _gcry_rngfips_initialize (1); /* Auto-initialize if needed. */
+
+ lock_rng ();
+ get_random (buffer, length, nonce_context);
+ unlock_rng ();
+}
+
+
+/* Run a Know-Answer-Test using a dedicated test context. Note that
+ we can't use the samples from the NISR RNGVS document because they
+ don't take the requirement to throw away the first block and use
+ that for duplicate check in account. Thus we made up our own test
+ vectors. */
+static gcry_err_code_t
+selftest_kat (selftest_report_func_t report)
+{
+ static struct
+ {
+ const unsigned char key[16];
+ const unsigned char dt[16];
+ const unsigned char v[16];
+ const unsigned char r[3][16];
+ } tv[] =
+ {
+ { { 0xb9, 0xca, 0x7f, 0xd6, 0xa0, 0xf5, 0xd3, 0x42,
+ 0x19, 0x6d, 0x84, 0x91, 0x76, 0x1c, 0x3b, 0xbe },
+ { 0x48, 0xb2, 0x82, 0x98, 0x68, 0xc2, 0x80, 0x00,
+ 0x00, 0x00, 0x28, 0x18, 0x00, 0x00, 0x25, 0x00 },
+ { 0x52, 0x17, 0x8d, 0x29, 0xa2, 0xd5, 0x84, 0x12,
+ 0x9d, 0x89, 0x9a, 0x45, 0x82, 0x02, 0xf7, 0x77 },
+ { { 0x42, 0x9c, 0x08, 0x3d, 0x82, 0xf4, 0x8a, 0x40,
+ 0x66, 0xb5, 0x49, 0x27, 0xab, 0x42, 0xc7, 0xc3 },
+ { 0x0e, 0xb7, 0x61, 0x3c, 0xfe, 0xb0, 0xbe, 0x73,
+ 0xf7, 0x6e, 0x6d, 0x6f, 0x1d, 0xa3, 0x14, 0xfa },
+ { 0xbb, 0x4b, 0xc1, 0x0e, 0xc5, 0xfb, 0xcd, 0x46,
+ 0xbe, 0x28, 0x61, 0xe7, 0x03, 0x2b, 0x37, 0x7d } } },
+ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
+ { { 0xf7, 0x95, 0xbd, 0x4a, 0x52, 0xe2, 0x9e, 0xd7,
+ 0x13, 0xd3, 0x13, 0xfa, 0x20, 0xe9, 0x8d, 0xbc },
+ { 0xc8, 0xd1, 0xe5, 0x11, 0x59, 0x52, 0xf7, 0xfa,
+ 0x37, 0x38, 0xb4, 0xc5, 0xce, 0xb2, 0xb0, 0x9a },
+ { 0x0d, 0x9c, 0xc5, 0x0d, 0x16, 0xe1, 0xbc, 0xed,
+ 0xcf, 0x60, 0x62, 0x09, 0x9d, 0x20, 0x83, 0x7e } } },
+ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x80, 0x00, 0x81, 0x01, 0x82, 0x02, 0x83, 0x03,
+ 0xa0, 0x20, 0xa1, 0x21, 0xa2, 0x22, 0xa3, 0x23 },
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ { { 0x96, 0xed, 0xcc, 0xc3, 0xdd, 0x04, 0x7f, 0x75,
+ 0x63, 0x19, 0x37, 0x6f, 0x15, 0x22, 0x57, 0x56 },
+ { 0x7a, 0x14, 0x76, 0x77, 0x95, 0x17, 0x7e, 0xc8,
+ 0x92, 0xe8, 0xdd, 0x15, 0xcb, 0x1f, 0xbc, 0xb1 },
+ { 0x25, 0x3e, 0x2e, 0xa2, 0x41, 0x1b, 0xdd, 0xf5,
+ 0x21, 0x48, 0x41, 0x71, 0xb3, 0x8d, 0x2f, 0x4c } } }
+ };
+ int tvidx, ridx;
+ rng_context_t test_ctx;
+ gpg_error_t err;
+ const char *errtxt = NULL;
+ unsigned char result[16];
+
+ gcry_assert (tempvalue_for_x931_aes_driver);
+
+ test_ctx = gcry_xcalloc (1, sizeof *test_ctx);
+ setup_guards (test_ctx);
+
+ lock_rng ();
+
+ for (tvidx=0; tvidx < DIM (tv); tvidx++)
+ {
+ /* Setup the key. */
+ err = gcry_cipher_open (&test_ctx->cipher_hd,
+ GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
+ GCRY_CIPHER_SECURE);
+ if (err)
+ {
+ errtxt = "error creating cipher context for RNG";
+ goto leave;
+ }
+
+ err = gcry_cipher_setkey (test_ctx->cipher_hd, tv[tvidx].key, 16);
+ if (err)
+ {
+ errtxt = "error setting key for RNG";
+ goto leave;
+ }
+ test_ctx->key_init_pid = getpid ();
+
+ /* Setup the seed. */
+ memcpy (test_ctx->seed_V, tv[tvidx].v, 16);
+ test_ctx->is_seeded = 1;
+ test_ctx->seed_init_pid = getpid ();
+
+ /* Setup a DT value. */
+ test_ctx->test_dt_ptr = tv[tvidx].dt;
+ test_ctx->test_dt_counter = ( (tv[tvidx].dt[12] << 24)
+ |(tv[tvidx].dt[13] << 16)
+ |(tv[tvidx].dt[14] << 8)
+ |(tv[tvidx].dt[15]) );
+
+ /* Get and compare the first three results. */
+ for (ridx=0; ridx < 3; ridx++)
+ {
+ /* Compute the next value. */
+ if (x931_aes_driver (result, 16, test_ctx))
+ {
+ errtxt = "X9.31 RNG core function failed";
+ goto leave;
+ }
+
+ /* Compare it to the known value. */
+ if (memcmp (result, tv[tvidx].r[ridx], 16))
+ {
+ /* log_printhex ("x931_aes got: ", result, 16); */
+ /* log_printhex ("x931_aes exp: ", tv[tvidx].r[ridx], 16); */
+ errtxt = "RNG output does not match known value";
+ goto leave;
+ }
+ }
+
+ /* This test is actual pretty pointless because we use a local test
+ context. */
+ if (test_ctx->key_init_pid != getpid ()
+ || test_ctx->seed_init_pid != getpid ())
+ {
+ errtxt = "fork detection failed";
+ goto leave;
+ }
+
+ gcry_cipher_close (test_ctx->cipher_hd);
+ test_ctx->cipher_hd = NULL;
+ test_ctx->is_seeded = 0;
+ check_guards (test_ctx);
+ }
+
+ leave:
+ unlock_rng ();
+ gcry_cipher_close (test_ctx->cipher_hd);
+ check_guards (test_ctx);
+ gcry_free (test_ctx);
+ if (report && errtxt)
+ report ("random", 0, "KAT", errtxt);
+ return errtxt? GPG_ERR_SELFTEST_FAILED : 0;
+}
+
+
+/* Run the self-tests. */
+gcry_error_t
+_gcry_rngfips_selftest (selftest_report_func_t report)
+{
+ gcry_err_code_t ec;
+
+#if defined(USE_RNDLINUX) || defined(USE_RNDW32)
+ {
+ char buffer[8];
+
+ /* Do a simple test using the public interface. This will also
+ enforce full initialization of the RNG. We need to be fully
+ initialized due to the global requirement of the
+ tempvalue_for_x931_aes_driver stuff. */
+ gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
+ }
+
+ ec = selftest_kat (report);
+
+#else /*!(USE_RNDLINUX||USE_RNDW32)*/
+ report ("random", 0, "setup", "no entropy gathering module");
+ ec = GPG_ERR_SELFTEST_FAILED;
+#endif
+ return gpg_error (ec);
+}
+
+
+/* Create a new test context for an external RNG test driver. On
+ success the test context is stored at R_CONTEXT; on failure NULL is
+ stored at R_CONTEXT and an error code is returned. */
+gcry_err_code_t
+_gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
+ const void *key, size_t keylen,
+ const void *seed, size_t seedlen,
+ const void *dt, size_t dtlen)
+{
+ gpg_error_t err;
+ rng_context_t test_ctx;
+
+ _gcry_rngfips_initialize (1); /* Auto-initialize if needed. */
+
+ if (!r_context
+ || !key || keylen != 16
+ || !seed || seedlen != 16
+ || !dt || dtlen != 16 )
+ return GPG_ERR_INV_ARG;
+
+ test_ctx = gcry_calloc (1, sizeof *test_ctx + dtlen);
+ if (!test_ctx)
+ return gpg_err_code_from_syserror ();
+ setup_guards (test_ctx);
+
+ /* Setup the key. */
+ err = gcry_cipher_open (&test_ctx->cipher_hd,
+ GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
+ GCRY_CIPHER_SECURE);
+ if (err)
+ goto leave;
+
+ err = gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen);
+ if (err)
+ goto leave;
+
+ test_ctx->key_init_pid = getpid ();
+
+ /* Setup the seed. */
+ memcpy (test_ctx->seed_V, seed, seedlen);
+ test_ctx->is_seeded = 1;
+ test_ctx->seed_init_pid = getpid ();
+
+ /* Setup a DT value. Because our context structure only stores a
+ pointer we copy the DT value to the extra space we allocated in
+ the test_ctx and set the pointer to that address. */
+ memcpy ((unsigned char*)test_ctx + sizeof *test_ctx, dt, dtlen);
+ test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof *test_ctx;
+ test_ctx->test_dt_counter = ( (test_ctx->test_dt_ptr[12] << 24)
+ |(test_ctx->test_dt_ptr[13] << 16)
+ |(test_ctx->test_dt_ptr[14] << 8)
+ |(test_ctx->test_dt_ptr[15]) );
+
+ if ( (flags & 1) )
+ test_ctx->test_no_dup_check = 1;
+
+ check_guards (test_ctx);
+ /* All fine. */
+ err = 0;
+
+ leave:
+ if (err)
+ {
+ gcry_cipher_close (test_ctx->cipher_hd);
+ gcry_free (test_ctx);
+ *r_context = NULL;
+ }
+ else
+ *r_context = test_ctx;
+ return gcry_err_code (err);
+}
+
+
+/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them
+ at BUFFER. Return 0 on success or an error code. */
+gcry_err_code_t
+_gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen)
+{
+ rng_context_t test_ctx = context;
+
+ if (!test_ctx || !buffer || buflen != 16)
+ return GPG_ERR_INV_ARG;
+
+ lock_rng ();
+ get_random (buffer, buflen, test_ctx);
+ unlock_rng ();
+ return 0;
+}
+
+/* Release the test CONTEXT. */
+void
+_gcry_rngfips_deinit_external_test (void *context)
+{
+ rng_context_t test_ctx = context;
+
+ if (test_ctx)
+ {
+ gcry_cipher_close (test_ctx->cipher_hd);
+ gcry_free (test_ctx);
+ }
+}
--- /dev/null
+/* random.c - Random number switch
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This module switches between different implementations of random
+ number generators and provides a few help functions.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "random.h"
+#include "rand-internal.h"
+#include "ath.h"
+
+
+/* If not NULL a progress function called from certain places and the
+ opaque value passed along. Registered by
+ _gcry_register_random_progress (). */
+static void (*progress_cb) (void *,const char*,int,int, int );
+static void *progress_cb_data;
+
+
+
+\f
+/* --- Functions --- */
+
+
+/* Used to register a progress callback. This needs to be called
+ before any threads are created. */
+void
+_gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
+ void *cb_data )
+{
+ progress_cb = cb;
+ progress_cb_data = cb_data;
+}
+
+
+/* This progress function is currently used by the random modules to
+ give hints on how much more entropy is required. */
+void
+_gcry_random_progress (const char *what, int printchar, int current, int total)
+{
+ if (progress_cb)
+ progress_cb (progress_cb_data, what, printchar, current, total);
+}
+
+
+
+/* Initialize this random subsystem. If FULL is false, this function
+ merely calls the basic initialization of the module and does not do
+ anything more. Doing this is not really required but when running
+ in a threaded environment we might get a race condition
+ otherwise. */
+void
+_gcry_random_initialize (int full)
+{
+ if (fips_mode ())
+ _gcry_rngfips_initialize (full);
+ else
+ _gcry_rngcsprng_initialize (full);
+}
+
+
+void
+_gcry_random_dump_stats (void)
+{
+ if (fips_mode ())
+ _gcry_rngfips_dump_stats ();
+ else
+ _gcry_rngcsprng_dump_stats ();
+}
+
+
+/* This function should be called during initialization and before
+ initialization of this module to place the random pools into secure
+ memory. */
+void
+_gcry_secure_random_alloc (void)
+{
+ if (fips_mode ())
+ ; /* Not used; the FIPS RNG is always in secure mode. */
+ else
+ _gcry_rngcsprng_secure_alloc ();
+}
+
+
+/* This may be called before full initialization to degrade the
+ quality of the RNG for the sake of a faster running test suite. */
+void
+_gcry_enable_quick_random_gen (void)
+{
+ if (fips_mode ())
+ ; /* Not used. */
+ else
+ _gcry_rngcsprng_enable_quick_gen ();
+}
+
+
+void
+_gcry_set_random_daemon_socket (const char *socketname)
+{
+ if (fips_mode ())
+ ; /* Not used. */
+ else
+ _gcry_rngcsprng_set_daemon_socket (socketname);
+}
+
+/* With ONOFF set to 1, enable the use of the daemon. With ONOFF set
+ to 0, disable the use of the daemon. With ONOF set to -1, return
+ whether the daemon has been enabled. */
+int
+_gcry_use_random_daemon (int onoff)
+{
+ if (fips_mode ())
+ return 0; /* Never enabled in fips mode. */
+ else
+ return _gcry_rngcsprng_use_daemon (onoff);
+}
+
+
+/* This function returns true if no real RNG is available or the
+ quality of the RNG has been degraded for test purposes. */
+int
+_gcry_random_is_faked (void)
+{
+ if (fips_mode ())
+ return _gcry_rngfips_is_faked ();
+ else
+ return _gcry_rngcsprng_is_faked ();
+}
+
+
+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY
+ should be in the range of 0..100 to indicate the goodness of the
+ entropy added, or -1 for goodness not known. */
+gcry_error_t
+gcry_random_add_bytes (const void *buf, size_t buflen, int quality)
+{
+ if (fips_mode ())
+ return 0; /* No need for this in fips mode. */
+ else
+ return _gcry_rngcsprng_add_bytes (buf, buflen, quality);
+}
+
+
+/* Helper function. */
+static void
+do_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ if (fips_mode ())
+ _gcry_rngfips_randomize (buffer, length, level);
+ else
+ _gcry_rngcsprng_randomize (buffer, length, level);
+}
+
+/* The public function to return random data of the quality LEVEL.
+ Returns a pointer to a newly allocated and randomized buffer of
+ LEVEL and NBYTES length. Caller must free the buffer. */
+void *
+gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+{
+ void *buffer;
+
+ buffer = gcry_xmalloc (nbytes);
+ do_randomize (buffer, nbytes, level);
+ return buffer;
+}
+
+
+/* The public function to return random data of the quality LEVEL;
+ this version of the function returns the random in a buffer allocated
+ in secure memory. Caller must free the buffer. */
+void *
+gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+{
+ void *buffer;
+
+ /* Historical note (1.3.0--1.4.1): The buffer was only allocated
+ in secure memory if the pool in random-csprng.c was also set to
+ use secure memory. */
+ buffer = gcry_xmalloc_secure (nbytes);
+ do_randomize (buffer, nbytes, level);
+ return buffer;
+}
+
+
+/* Public function to fill the buffer with LENGTH bytes of
+ cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is
+ not very strong, GCRY_STRONG_RANDOM is strong enough for most
+ usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
+ may be very slow. */
+void
+gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ do_randomize (buffer, length, level);
+}
+
+
+/* This function may be used to specify the file to be used as a seed
+ file for the PRNG. This function should be called prior to the
+ initialization of the random module. NAME may not be NULL. */
+void
+_gcry_set_random_seed_file (const char *name)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else
+ _gcry_rngcsprng_set_seed_file (name);
+}
+
+
+/* If a seed file has been setup, this function may be used to write
+ back the random numbers entropy pool. */
+void
+_gcry_update_random_seed_file (void)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else
+ _gcry_rngcsprng_update_seed_file ();
+}
+
+
+
+/* The fast random pool function as called at some places in
+ libgcrypt. This is merely a wrapper to make sure that this module
+ is initialized and to lock the pool. Note, that this function is a
+ NOP unless a random function has been used or _gcry_initialize (1)
+ has been used. We use this hack so that the internal use of this
+ function in cipher_open and md_open won't start filling up the
+ random pool, even if no random will be required by the process. */
+void
+_gcry_fast_random_poll (void)
+{
+ if (fips_mode ())
+ ; /* No need for this in fips mode. */
+ else
+ _gcry_rngcsprng_fast_poll ();
+}
+
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void
+gcry_create_nonce (void *buffer, size_t length)
+{
+ if (fips_mode ())
+ _gcry_rngfips_create_nonce (buffer, length);
+ else
+ _gcry_rngcsprng_create_nonce (buffer, length);
+}
+
+
+/* Run the self-tests for the RNG. This is currently only implemented
+ for the FIPS generator. */
+gpg_error_t
+_gcry_random_selftest (selftest_report_func_t report)
+{
+ if (fips_mode ())
+ return _gcry_rngfips_selftest (report);
+ else
+ return 0; /* No selftests yet. */
+}
+
+
+/* Create a new test context for an external RNG test driver. On
+ success the test context is stored at R_CONTEXT; on failure NULL is
+ stored at R_CONTEXT and an error code is returned. */
+gcry_err_code_t
+_gcry_random_init_external_test (void **r_context,
+ unsigned int flags,
+ const void *key, size_t keylen,
+ const void *seed, size_t seedlen,
+ const void *dt, size_t dtlen)
+{
+ (void)flags;
+ if (fips_mode ())
+ return _gcry_rngfips_init_external_test (r_context, flags, key, keylen,
+ seed, seedlen,
+ dt, dtlen);
+ else
+ return GPG_ERR_NOT_SUPPORTED;
+}
+
+/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them
+ at BUFFER. Return 0 on success or an error code. */
+gcry_err_code_t
+_gcry_random_run_external_test (void *context, char *buffer, size_t buflen)
+{
+ if (fips_mode ())
+ return _gcry_rngfips_run_external_test (context, buffer, buflen);
+ else
+ return GPG_ERR_NOT_SUPPORTED;
+}
+
+/* Release the test CONTEXT. */
+void
+_gcry_random_deinit_external_test (void *context)
+{
+ if (fips_mode ())
+ _gcry_rngfips_deinit_external_test (context);
+}
--- /dev/null
+/* random.h - random functions
+ * Copyright (C) 1998, 2002, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_RANDOM_H
+#define G10_RANDOM_H
+
+#include "types.h"
+
+/*-- random.c --*/
+void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
+ void *cb_data );
+
+void _gcry_random_initialize (int full);
+void _gcry_random_dump_stats(void);
+void _gcry_secure_random_alloc(void);
+void _gcry_enable_quick_random_gen (void);
+int _gcry_random_is_faked(void);
+void _gcry_set_random_daemon_socket (const char *socketname);
+int _gcry_use_random_daemon (int onoff);
+void _gcry_set_random_seed_file (const char *name);
+void _gcry_update_random_seed_file (void);
+
+byte *_gcry_get_random_bits( size_t nbits, int level, int secure );
+void _gcry_fast_random_poll( void );
+
+gcry_err_code_t _gcry_random_init_external_test (void **r_context,
+ unsigned int flags,
+ const void *key,
+ size_t keylen,
+ const void *seed,
+ size_t seedlen,
+ const void *dt,
+ size_t dtlen);
+gcry_err_code_t _gcry_random_run_external_test (void *context,
+ char *buffer, size_t buflen);
+void _gcry_random_deinit_external_test (void *context);
+
+
+/*-- rndegd.c --*/
+gpg_error_t _gcry_rndegd_set_socket_name (const char *name);
+
+/*-- random-daemon.c (only used from random.c) --*/
+#ifdef USE_RANDOM_DAEMON
+void _gcry_daemon_initialize_basics (void);
+int _gcry_daemon_randomize (const char *socketname,
+ void *buffer, size_t length,
+ enum gcry_random_level level);
+int _gcry_daemon_create_nonce (const char *socketname,
+ void *buffer, size_t length);
+#endif /*USE_RANDOM_DAEMON*/
+
+#endif /*G10_RANDOM_H*/
--- /dev/null
+/* rndegd.c - interface to the EGD
+ * Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "rand-internal.h"
+
+#ifndef offsetof
+#define offsetof(type, member) ((size_t) &((type *)0)->member)
+#endif
+
+static int egd_socket = -1;
+
+/* Allocated name of the socket if supplied at runtime. */
+static char *user_socket_name;
+
+
+/* Allocate a new filename from FIRST_PART and SECOND_PART and to
+ tilde expansion for first_part. SECOND_PART might be NULL.
+ */
+static char *
+my_make_filename (const char *first_part, const char *second_part)
+{
+ size_t n;
+ char *name, *home, *p;
+
+ n = strlen(first_part)+1;
+ if (second_part)
+ n += strlen (second_part) + 1;
+
+ home = NULL;
+ if( *first_part == '~' && first_part[1] == '/'
+ && (home = getenv("HOME")) && *home )
+ n += strlen(home);
+
+ name = gcry_xmalloc(n);
+ p = (home
+ ? stpcpy (stpcpy (name, home), first_part+1 )
+ : stpcpy (name, first_part) );
+
+ if (second_part)
+ strcpy (stpcpy(p,"/"), second_part);
+
+ return name;
+}
+
+
+static int
+do_write( int fd, void *buf, size_t nbytes )
+{
+ size_t nleft = nbytes;
+ int nwritten;
+
+ while( nleft > 0 )
+ {
+ nwritten = write( fd, buf, nleft);
+ if( nwritten < 0 )
+ {
+ if( errno == EINTR )
+ continue;
+ return -1;
+ }
+ nleft -= nwritten;
+ buf = (char*)buf + nwritten;
+ }
+ return 0;
+}
+
+static int
+do_read( int fd, void *buf, size_t nbytes )
+{
+ int n, nread = 0;
+
+ do
+ {
+ do
+ {
+ n = read(fd, (char*)buf + nread, nbytes );
+ }
+ while( n == -1 && errno == EINTR );
+ if( n == -1)
+ return nread? nread:-1;
+ if( n == 0)
+ return -1;
+ nread += n;
+ nbytes -= n;
+ }
+ while( nread < nbytes );
+ return nread;
+}
+
+
+/* Note that his function is not thread-safe. */
+gpg_error_t
+_gcry_rndegd_set_socket_name (const char *name)
+{
+ char *newname;
+ struct sockaddr_un addr;
+
+ newname = my_make_filename (name, NULL);
+ if (strlen (newname)+1 >= sizeof addr.sun_path)
+ {
+ gcry_free (newname);
+ return gpg_error_from_syserror ();
+ }
+ gcry_free (user_socket_name);
+ user_socket_name = newname;
+ return 0;
+}
+
+
+/* Connect to the EGD and return the file descriptor. Return -1 on
+ error. With NOFAIL set to true, silently fail and return the
+ error, otherwise print an error message and die. */
+int
+_gcry_rndegd_connect_socket (int nofail)
+{
+ int fd;
+ const char *bname = NULL;
+ char *name;
+ struct sockaddr_un addr;
+ int addr_len;
+
+ if (egd_socket != -1)
+ {
+ close (egd_socket);
+ egd_socket = -1;
+ }
+
+#ifdef EGD_SOCKET_NAME
+ bname = EGD_SOCKET_NAME;
+#endif
+ if (user_socket_name)
+ {
+ name = gcry_strdup (user_socket_name);
+ if (!name)
+ {
+ if (!nofail)
+ log_fatal ("error allocating memory in rndegd: %s\n",
+ strerror(errno) );
+ return -1;
+ }
+ }
+ else if ( !bname || !*bname )
+ name = my_make_filename ("~/.gnupg", "entropy");
+ else
+ name = my_make_filename (bname, NULL);
+
+ if (strlen(name)+1 >= sizeof addr.sun_path)
+ log_fatal ("EGD socketname is too long\n");
+
+ memset( &addr, 0, sizeof addr );
+ addr.sun_family = AF_UNIX;
+ strcpy( addr.sun_path, name );
+ addr_len = (offsetof( struct sockaddr_un, sun_path )
+ + strlen( addr.sun_path ));
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1 && !nofail)
+ log_fatal("can't create unix domain socket: %s\n", strerror(errno) );
+ else if (connect (fd, (struct sockaddr*)&addr, addr_len) == -1)
+ {
+ if (!nofail)
+ log_fatal("can't connect to EGD socket `%s': %s\n",
+ name, strerror(errno) );
+ close (fd);
+ fd = -1;
+ }
+ gcry_free(name);
+ if (fd != -1)
+ egd_socket = fd;
+ return fd;
+}
+
+/****************
+ * Note: We always use the highest level.
+ * To boost the performance we may want to add some
+ * additional code for level 1
+ *
+ * Using a level of 0 should never block and better add nothing
+ * to the pool. So this is just a dummy for EGD.
+ */
+int
+_gcry_rndegd_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ int fd = egd_socket;
+ int n;
+ byte buffer[256+2];
+ int nbytes;
+ int do_restart = 0;
+
+ if( !length )
+ return 0;
+ if( !level )
+ return 0;
+
+ restart:
+ if (fd == -1 || do_restart)
+ fd = _gcry_rndegd_connect_socket (0);
+
+ do_restart = 0;
+
+ nbytes = length < 255? length : 255;
+ /* First time we do it with a non blocking request */
+ buffer[0] = 1; /* non blocking */
+ buffer[1] = nbytes;
+ if( do_write( fd, buffer, 2 ) == -1 )
+ log_fatal("can't write to the EGD: %s\n", strerror(errno) );
+ n = do_read( fd, buffer, 1 );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ n = buffer[0];
+ if( n )
+ {
+ n = do_read( fd, buffer, n );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ (*add)( buffer, n, origin );
+ length -= n;
+ }
+
+ if( length )
+ {
+ log_info (
+ _("Please wait, entropy is being gathered. Do some work if it would\n"
+ "keep you from getting bored, because it will improve the quality\n"
+ "of the entropy.\n") );
+ }
+ while( length )
+ {
+ nbytes = length < 255? length : 255;
+
+ buffer[0] = 2; /* blocking */
+ buffer[1] = nbytes;
+ if( do_write( fd, buffer, 2 ) == -1 )
+ log_fatal("can't write to the EGD: %s\n", strerror(errno) );
+ n = do_read( fd, buffer, nbytes );
+ if( n == -1 )
+ {
+ log_error("read error on EGD: %s\n", strerror(errno));
+ do_restart = 1;
+ goto restart;
+ }
+ (*add)( buffer, n, origin );
+ length -= n;
+ }
+ memset(buffer, 0, sizeof(buffer) );
+
+ return 0; /* success */
+}
--- /dev/null
+/* rndhw.c - Access to the external random daemon
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+#undef USE_PADLOCK
+#ifdef ENABLE_PADLOCK_SUPPORT
+# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+# define USE_PADLOCK
+# endif
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+
+/* Keep track on whether the RNG has problems. */
+static volatile int rng_failed;
+
+
+#ifdef USE_PADLOCK
+static size_t
+poll_padlock (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin, int fast)
+{
+ volatile char buffer[64+8] __attribute__ ((aligned (8)));
+ volatile char *p;
+ unsigned int nbytes, status;
+
+ /* Peter Gutmann's cryptlib tests again whether the RNG is enabled
+ but we don't do so. We would have to do this also for our AES
+ implementaion and that is definitely too time consuming. There
+ would be a race condition anyway. Thus we assume that the OS
+ does not change the Padlock initialization while a user process
+ is running. */
+ p = buffer;
+ nbytes = 0;
+ while (nbytes < 64)
+ {
+ asm volatile
+ ("movl %1, %%edi\n\t" /* Set buffer. */
+ "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */
+ ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */
+ : "=a" (status)
+ : "g" (p)
+ : "%edx", "%edi", "cc"
+ );
+ if ((status & (1<<6)) /* RNG still enabled. */
+ && !(status & (1<<13)) /* von Neumann corrector is enabled. */
+ && !(status & (1<<14)) /* String filter is disabled. */
+ && !(status & 0x1c00) /* BIAS voltage at default. */
+ && (!(status & 0x1f) || (status & 0x1f) == 8) /* Sanity check. */
+ )
+ {
+ nbytes += (status & 0x1f);
+ if (fast)
+ break; /* Don't get into the loop with the fast flag set. */
+ p += (status & 0x1f);
+ }
+ else
+ {
+ /* If there was an error we need to break the loop and
+ record that there is something wrong with the padlock
+ RNG. */
+ rng_failed = 1;
+ break;
+ }
+ }
+
+ if (nbytes)
+ {
+ (*add) ((void*)buffer, nbytes, origin);
+ wipememory (buffer, nbytes);
+ }
+ return nbytes;
+}
+#endif /*USE_PADLOCK*/
+
+
+int
+_gcry_rndhw_failed_p (void)
+{
+ return rng_failed;
+}
+
+
+/* Try to read random from a hardware RNG if a fast one is
+ available. */
+void
+_gcry_rndhw_poll_fast (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin)
+{
+ (void)add;
+ (void)origin;
+
+#ifdef USE_PADLOCK
+ if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
+ poll_padlock (add, origin, 1);
+#endif
+}
+
+
+/* Read 64 bytes from a hardware RNG and return the number of bytes
+ actually read. */
+size_t
+_gcry_rndhw_poll_slow (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins origin)
+{
+ size_t nbytes = 0;
+
+ (void)add;
+ (void)origin;
+
+#ifdef USE_PADLOCK
+ if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
+ nbytes += poll_padlock (add, origin, 0);
+#endif
+
+ return nbytes;
+}
--- /dev/null
+/* rndlinux.c - raw random number for OSes with /dev/random
+ * Copyright (C) 1998, 2001, 2002, 2003, 2007,
+ * 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_GETTIMEOFDAY
+# include <sys/times.h>
+#endif
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+static int open_device ( const char *name );
+
+
+static int
+set_cloexec_flag (int fd)
+{
+ int oldflags;
+
+ oldflags= fcntl (fd, F_GETFD, 0);
+ if (oldflags < 0)
+ return oldflags;
+ oldflags |= FD_CLOEXEC;
+ return fcntl (fd, F_SETFD, oldflags);
+}
+
+
+
+/*
+ * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)).
+ */
+static int
+open_device ( const char *name )
+{
+ int fd;
+
+ fd = open ( name, O_RDONLY );
+ if ( fd == -1 )
+ log_fatal ("can't open %s: %s\n", name, strerror(errno) );
+
+ if (set_cloexec_flag (fd))
+ log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
+ fd, strerror (errno));
+
+ /* We used to do the following check, however it turned out that this
+ is not portable since more OSes provide a random device which is
+ sometimes implemented as another device type.
+
+ struct stat sb;
+
+ if( fstat( fd, &sb ) )
+ log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
+ if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
+ log_fatal("invalid random device!\n" );
+ */
+ return fd;
+}
+
+
+int
+_gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static int fd_urandom = -1;
+ static int fd_random = -1;
+ int fd;
+ int n;
+ byte buffer[768];
+ size_t n_hw;
+ size_t want = length;
+ size_t last_so_far = 0;
+ int any_need_entropy = 0;
+ int delay;
+
+ /* First read from a hardware source. However let it account only
+ for up to 50% of the requested bytes. */
+ n_hw = _gcry_rndhw_poll_slow (add, origin);
+ if (n_hw > length/2)
+ n_hw = length/2;
+ if (length > 1)
+ length -= n_hw;
+
+ /* Open the requested device. */
+ if (level >= 2)
+ {
+ if( fd_random == -1 )
+ fd_random = open_device ( NAME_OF_DEV_RANDOM );
+ fd = fd_random;
+ }
+ else
+ {
+ if( fd_urandom == -1 )
+ fd_urandom = open_device ( NAME_OF_DEV_URANDOM );
+ fd = fd_urandom;
+ }
+
+ /* Enter the read loop. */
+ delay = 0; /* Start with 0 seconds so that we do no block on the
+ first iteration and in turn call the progress function
+ before blocking. To give the OS a better chance to
+ return with something we will actually use 100ms. */
+ while (length)
+ {
+ fd_set rfds;
+ struct timeval tv;
+ int rc;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ tv.tv_sec = delay;
+ tv.tv_usec = delay? 0 : 100000;
+ if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
+ {
+ if (!any_need_entropy || last_so_far != (want - length) )
+ {
+ last_so_far = want - length;
+ _gcry_random_progress ("need_entropy", 'X',
+ (int)last_so_far, (int)want);
+ any_need_entropy = 1;
+ }
+ delay = 3; /* Use 3 seconds henceforth. */
+ continue;
+ }
+ else if( rc == -1 )
+ {
+ log_error ("select() error: %s\n", strerror(errno));
+ if (!delay)
+ delay = 1; /* Use 1 second if we encounter an error before
+ we have ever blocked. */
+ continue;
+ }
+
+ do
+ {
+ int nbytes = length < sizeof(buffer)? length : sizeof(buffer);
+ n = read(fd, buffer, nbytes );
+ if( n >= 0 && n > nbytes )
+ {
+ log_error("bogus read from random device (n=%d)\n", n );
+ n = nbytes;
+ }
+ }
+ while( n == -1 && errno == EINTR );
+ if ( n == -1 )
+ log_fatal("read error on random device: %s\n", strerror(errno));
+ (*add)( buffer, n, origin );
+ length -= n;
+ }
+ memset(buffer, 0, sizeof(buffer) );
+
+ if (any_need_entropy)
+ _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
+
+ return 0; /* success */
+}
--- /dev/null
+/****************************************************************************
+ * *
+ * *
+ * Unix Randomness-Gathering Code *
+ * *
+ * Copyright Peter Gutmann, Paul Kendall, and Chris Wedgwood 1996-1999. *
+ * Heavily modified for GnuPG by Werner Koch *
+ * *
+ * *
+ ****************************************************************************/
+
+/* This module is part of the cryptlib continuously seeded pseudorandom
+ number generator. For usage conditions, see lib_rand.c
+
+ [Here is the notice from lib_rand.c:]
+
+ This module and the misc/rnd*.c modules represent the cryptlib
+ continuously seeded pseudorandom number generator (CSPRNG) as described in
+ my 1998 Usenix Security Symposium paper "The generation of random numbers
+ for cryptographic purposes".
+
+ The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
+ 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
+ modules and use in source and binary forms, with or without modification,
+ are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice
+ and this permission notice in its entirety.
+
+ 2. Redistributions in binary form must reproduce the copyright notice in
+ the documentation and/or other materials provided with the distribution.
+
+ 3. A copy of any bugfixes or enhancements made must be provided to the
+ author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
+ baseline version of the code.
+
+ ALTERNATIVELY, the code may be distributed under the terms of the
+ GNU Lesser General Public License, version 2.1 or any later version
+ published by the Free Software Foundation, in which case the
+ provisions of the GNU LGPL are required INSTEAD OF the above
+ restrictions.
+
+ Although not required under the terms of the LGPL, it would still be
+ nice if you could make any changes available to the author to allow
+ a consistent code base to be maintained. */
+/*************************************************************************
+ The above alternative was changed from GPL to LGPL on 2007-08-22 with
+ permission from Peter Gutmann:
+ ==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 03:05:42 +1200
+
+ Hi,
+
+ >As of now libgcrypt is GPL under Windows due to that module and some people
+ >would really like to see it under LGPL too. Can you do such a license change
+ >to LGPL version 2? Note that LGPL give the user the option to relicense it
+ >under GPL, so the change would be pretty easy and backwar compatible.
+
+ Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
+ code as well, but Ian asked for LGPL as an option so as of the next release
+ I'll have LGPL in there. You can consider it to be retroactive, so your
+ current version will be LGPLd as well.
+
+ Peter.
+ ==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 20:50:08 +1200
+
+ >Would you mind to extend this also to the Unix entropy gatherer which is
+ >still used on systems without /dev/random and when EGD is not installed? That
+ >would be the last GPLed piece in Libgcrypt.
+
+ Sure, it covers the entire entropy-gathering subsystem.
+
+ Peter.
+ =========
+*/
+
+/* General includes */
+
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* OS-specific includes */
+
+#ifdef __osf__
+ /* Somewhere in the morass of system-specific cruft which OSF/1 pulls in
+ * via the following includes are various endianness defines, so we
+ * undefine the cryptlib ones, which aren't really needed for this module
+ * anyway */
+#undef BIG_ENDIAN
+#undef LITTLE_ENDIAN
+#endif /* __osf__ */
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+#ifndef __QNX__
+#include <sys/errno.h>
+#include <sys/ipc.h>
+#endif /* __QNX__ */
+#include <sys/time.h> /* SCO and SunOS need this before resource.h */
+#ifndef __QNX__
+#include <sys/resource.h>
+#endif /* __QNX__ */
+#if defined( _AIX ) || defined( __QNX__ )
+#include <sys/select.h>
+#endif /* _AIX */
+#ifndef __QNX__
+#include <sys/shm.h>
+#include <signal.h>
+#include <sys/signal.h>
+#endif /* __QNX__ */
+#include <sys/stat.h>
+#include <sys/types.h> /* Verschiedene komische Typen */
+#if defined( __hpux ) && ( OS_VERSION == 9 )
+#include <vfork.h>
+#endif /* __hpux 9.x, after that it's in unistd.h */
+#include <sys/wait.h>
+/* #include <kitchensink.h> */
+#ifdef __QNX__
+#include <signal.h>
+#include <process.h>
+#endif /* __QNX__ */
+#include <errno.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "rand-internal.h"
+
+#ifndef EAGAIN
+#define EAGAIN EWOULDBLOCK
+#endif
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+
+#define GATHER_BUFSIZE 49152 /* Usually about 25K are filled */
+
+/* The structure containing information on random-data sources. Each
+ * record contains the source and a relative estimate of its usefulness
+ * (weighting) which is used to scale the number of kB of output from the
+ * source (total = data_bytes / usefulness). Usually the weighting is in the
+ * range 1-3 (or 0 for especially useless sources), resulting in a usefulness
+ * rating of 1...3 for each kB of source output (or 0 for the useless
+ * sources).
+ *
+ * If the source is constantly changing (certain types of network statistics
+ * have this characteristic) but the amount of output is small, the weighting
+ * is given as a negative value to indicate that the output should be treated
+ * as if a minimum of 1K of output had been obtained. If the source produces
+ * a lot of output then the scale factor is fractional, resulting in a
+ * usefulness rating of < 1 for each kB of source output.
+ *
+ * In order to provide enough randomness to satisfy the requirements for a
+ * slow poll, we need to accumulate at least 20 points of usefulness (a
+ * typical system should get about 30 points).
+ *
+ * Some potential options are missed out because of special considerations.
+ * pstat -i and pstat -f can produce amazing amounts of output (the record
+ * is 600K on an Oracle server) which floods the buffer and doesn't yield
+ * anything useful (apart from perhaps increasing the entropy of the vmstat
+ * output a bit), so we don't bother with this. pstat in general produces
+ * quite a bit of output, but it doesn't change much over time, so it gets
+ * very low weightings. netstat -s produces constantly-changing output but
+ * also produces quite a bit of it, so it only gets a weighting of 2 rather
+ * than 3. The same holds for netstat -in, which gets 1 rather than 2.
+ *
+ * Some binaries are stored in different locations on different systems so
+ * alternative paths are given for them. The code sorts out which one to
+ * run by itself, once it finds an exectable somewhere it moves on to the
+ * next source. The sources are arranged roughly in their order of
+ * usefulness, occasionally sources which provide a tiny amount of
+ * relatively useless data are placed ahead of ones which provide a large
+ * amount of possibly useful data because another 100 bytes can't hurt, and
+ * it means the buffer won't be swamped by one or two high-output sources.
+ * All the high-output sources are clustered towards the end of the list
+ * for this reason. Some binaries are checked for in a certain order, for
+ * example under Slowaris /usr/ucb/ps understands aux as an arg, but the
+ * others don't. Some systems have conditional defines enabling alternatives
+ * to commands which don't understand the usual options but will provide
+ * enough output (in the form of error messages) to look like they're the
+ * real thing, causing alternative options to be skipped (we can't check the
+ * return either because some commands return peculiar, non-zero status even
+ * when they're working correctly).
+ *
+ * In order to maximise use of the buffer, the code performs a form of run-
+ * length compression on its input where a repeated sequence of bytes is
+ * replaced by the occurrence count mod 256. Some commands output an awful
+ * lot of whitespace, this measure greatly increases the amount of data we
+ * can fit in the buffer.
+ *
+ * When we scale the weighting using the SC() macro, some preprocessors may
+ * give a division by zero warning for the most obvious expression
+ * 'weight ? 1024 / weight : 0' (and gcc 2.7.2.2 dies with a division by zero
+ * trap), so we define a value SC_0 which evaluates to zero when fed to
+ * '1024 / SC_0' */
+
+#define SC( weight ) ( 1024 / weight ) /* Scale factor */
+#define SC_0 16384 /* SC( SC_0 ) evaluates to 0 */
+
+static struct RI {
+ const char *path; /* Path to check for existence of source */
+ const char *arg; /* Args for source */
+ const int usefulness; /* Usefulness of source */
+ FILE *pipe; /* Pipe to source as FILE * */
+ int pipeFD; /* Pipe to source as FD */
+ pid_t pid; /* pid of child for waitpid() */
+ int length; /* Quantity of output produced */
+ const int hasAlternative; /* Whether source has alt.location */
+} dataSources[] = {
+
+ { "/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-s", SC(-3), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-c", SC(-3), NULL, 0, 0, 0, 0},
+ { "/usr/bin/pfstat", NULL, SC(-2), NULL, 0, 0, 0, 0},
+ { "/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-i", SC(-2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-s", SC(2), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-s", SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/bin/nfsstat", NULL, SC(2), NULL, 0, 0, 0, 0},
+ { "/usr/ucb/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-m", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-m", SC(-1), NULL, 0, 0, 0, 0 },
+ { "/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-in", SC(-1), NULL, 0, 0, 0, 1},
+ { "/usr/etc/netstat", "-in", SC(-1), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.1.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP in */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.7.4.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* UDP out */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.4.3.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* IP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.10.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.11.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.6.13.0",
+ SC(-1), NULL, 0, 0, 0, 0 }, /* TCP ? */
+ { "/usr/bin/mpstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/w", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/w", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/df", NULL, SC(1), NULL, 0, 0, 0, 1 },
+ { "/bin/df", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/portstat", NULL, SC(1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/iostat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bsd/uptime", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", "-f", SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/vmstat", NULL, SC(SC_0), NULL, 0, 0, 0, 0 },
+ { "/usr/ucb/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/netstat", "-n", SC(0.5), NULL, 0, 0, 0, 0 },
+#if defined( __sgi ) || defined( __hpux )
+ { "/bin/ps", "-el", SC(0.3), NULL, 0, 0, 0, 1 },
+#endif /* __sgi || __hpux */
+ { "/usr/ucb/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 1 },
+ { "/bin/ps", "aux", SC(0.3), NULL, 0, 0, 0, 0 },
+ { "/bin/ps", "-A", SC(0.3), NULL, 0, 0, 0, 0 }, /*QNX*/
+ { "/usr/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/ipcs", "-a", SC(0.5), NULL, 0, 0, 0, 0 },
+ /* Unreliable source, depends on system usage */
+ { "/etc/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-p", SC(0.5), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-S", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-v", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-x", SC(0.2), NULL, 0, 0, 0, 0 },
+ { "/etc/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/bin/pstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
+ /* pstat is your friend */
+ { "/usr/bin/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 1 },
+#ifdef __sgi
+ { "/usr/bsd/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
+#endif /* __sgi */
+#ifdef __hpux
+ { "/etc/last", "-50", SC(0.3), NULL, 0, 0, 0, 0 },
+#endif /* __hpux */
+ { "/usr/bsd/last", "-n 50", SC(0.3), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.1.0",
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
+ { "/usr/sbin/snmp_request", "localhost public get 1.3.6.1.2.1.5.3.0",
+ SC(0.1), NULL, 0, 0, 0, 0 }, /* ICMP ? */
+ { "/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/etc/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/sbin/arp", "-a", SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/usr/sbin/ripquery", "-nw 1 127.0.0.1",
+ SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/bin/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 1 },
+ { "/usr/ucb/lpstat", "-t", SC(0.1), NULL, 0, 0, 0, 0 },
+ { "/usr/bin/tcpdump", "-c 5 -efvvx", SC(1), NULL, 0, 0, 0, 0 },
+ /* This is very environment-dependant. If network traffic is low, it'll
+ * probably time out before delivering 5 packets, which is OK because
+ * it'll probably be fixed stuff like ARP anyway */
+ { "/usr/sbin/advfsstat", "-b usr_domain",
+ SC(SC_0), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/advfsstat", "-l 2 usr_domain",
+ SC(0.5), NULL, 0, 0, 0, 0},
+ { "/usr/sbin/advfsstat", "-p usr_domain",
+ SC(SC_0), NULL, 0, 0, 0, 0},
+ /* This is a complex and screwball program. Some systems have things
+ * like rX_dmn, x = integer, for RAID systems, but the statistics are
+ * pretty dodgy */
+#ifdef __QNXNTO__
+ { "/bin/pidin", "-F%A%B%c%d%E%I%J%K%m%M%n%N%p%P%S%s%T", SC(0.3),
+ NULL, 0, 0, 0, 0 },
+#endif
+#if 0
+ /* The following aren't enabled since they're somewhat slow and not very
+ * unpredictable, however they give an indication of the sort of sources
+ * you can use (for example the finger might be more useful on a
+ * firewalled internal network) */
+ { "/usr/bin/finger", "@ml.media.mit.edu", SC(0.9), NULL, 0, 0, 0, 0 },
+ { "/usr/local/bin/wget", "-O - http://lavarand.sgi.com/block.html",
+ SC(0.9), NULL, 0, 0, 0, 0 },
+ { "/bin/cat", "/usr/spool/mqueue/syslog", SC(0.9), NULL, 0, 0, 0, 0 },
+#endif /* 0 */
+ { NULL, NULL, 0, NULL, 0, 0, 0, 0 }
+};
+
+static byte *gather_buffer; /* buffer for gathering random noise */
+static int gather_buffer_size; /* size of the memory buffer */
+static uid_t gatherer_uid;
+
+/* The message structure used to communicate with the parent */
+typedef struct {
+ int usefulness; /* usefulness of data */
+ int ndata; /* valid bytes in data */
+ char data[500]; /* gathered data */
+} GATHER_MSG;
+
+#ifndef HAVE_WAITPID
+static pid_t
+waitpid(pid_t pid, int *statptr, int options)
+{
+#ifdef HAVE_WAIT4
+ return wait4(pid, statptr, options, NULL);
+#else
+ /* If wait4 is also not available, try wait3 for SVR3 variants */
+ /* Less ideal because can't actually request a specific pid */
+ /* For that reason, first check to see if pid is for an */
+ /* existing process. */
+ int tmp_pid, dummystat;;
+ if (kill(pid, 0) == -1) {
+ errno = ECHILD;
+ return -1;
+ }
+ if (statptr == NULL)
+ statptr = &dummystat;
+ while (((tmp_pid = wait3(statptr, options, 0)) != pid) &&
+ (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1))
+ ;
+ return tmp_pid;
+#endif
+}
+#endif
+
+/* Under SunOS popen() doesn't record the pid of the child process. When
+ * pclose() is called, instead of calling waitpid() for the correct child, it
+ * calls wait() repeatedly until the right child is reaped. The problem is
+ * that this reaps any other children that happen to have died at that
+ * moment, and when their pclose() comes along, the process hangs forever.
+ * The fix is to use a wrapper for popen()/pclose() which saves the pid in
+ * the dataSources structure (code adapted from GNU-libc's popen() call).
+ *
+ * Aut viam inveniam aut faciam */
+
+static FILE *
+my_popen(struct RI *entry)
+{
+ int pipedes[2];
+ FILE *stream;
+
+ /* Create the pipe */
+ if (pipe(pipedes) < 0)
+ return (NULL);
+
+ /* Fork off the child ("vfork() is like an OS orgasm. All OS's want to
+ * do it, but most just end up faking it" - Chris Wedgwood). If your OS
+ * supports it, you should try to use vfork() here because it's somewhat
+ * more efficient */
+#if defined( sun ) || defined( __ultrix__ ) || defined( __osf__ ) || \
+ defined(__hpux)
+ entry->pid = vfork();
+#else /* */
+ entry->pid = fork();
+#endif /* Unixen which have vfork() */
+ if (entry->pid == (pid_t) - 1) {
+ /* The fork failed */
+ close(pipedes[0]);
+ close(pipedes[1]);
+ return (NULL);
+ }
+
+ if (entry->pid == (pid_t) 0) {
+ struct passwd *passwd;
+
+ /* We are the child. Make the read side of the pipe be stdout */
+ if (dup2(pipedes[STDOUT_FILENO], STDOUT_FILENO) < 0)
+ exit(127);
+
+ /* Now that everything is set up, give up our permissions to make
+ * sure we don't read anything sensitive. If the getpwnam() fails,
+ * we default to -1, which is usually nobody */
+ if (gatherer_uid == (uid_t)-1 && \
+ (passwd = getpwnam("nobody")) != NULL)
+ gatherer_uid = passwd->pw_uid;
+
+ setuid(gatherer_uid);
+
+ /* Close the pipe descriptors */
+ close(pipedes[STDIN_FILENO]);
+ close(pipedes[STDOUT_FILENO]);
+
+ /* Try and exec the program */
+ execl(entry->path, entry->path, entry->arg, NULL);
+
+ /* Die if the exec failed */
+ exit(127);
+ }
+
+ /* We are the parent. Close the irrelevant side of the pipe and open
+ * the relevant side as a new stream. Mark our side of the pipe to
+ * close on exec, so new children won't see it */
+ close(pipedes[STDOUT_FILENO]);
+
+#ifdef FD_CLOEXEC
+ fcntl(pipedes[STDIN_FILENO], F_SETFD, FD_CLOEXEC);
+#endif
+
+ stream = fdopen(pipedes[STDIN_FILENO], "r");
+
+ if (stream == NULL) {
+ int savedErrno = errno;
+
+ /* The stream couldn't be opened or the child structure couldn't be
+ * allocated. Kill the child and close the other side of the pipe */
+ kill(entry->pid, SIGKILL);
+ if (stream == NULL)
+ close(pipedes[STDOUT_FILENO]);
+ else
+ fclose(stream);
+
+ waitpid(entry->pid, NULL, 0);
+
+ entry->pid = 0;
+ errno = savedErrno;
+ return (NULL);
+ }
+
+ return (stream);
+}
+
+static int
+my_pclose(struct RI *entry)
+{
+ int status = 0;
+
+ if (fclose(entry->pipe))
+ return (-1);
+
+ /* We ignore the return value from the process because some
+ programs return funny values which would result in the input
+ being discarded even if they executed successfully. This isn't
+ a problem because the result data size threshold will filter
+ out any programs which exit with a usage message without
+ producing useful output. */
+ if (waitpid(entry->pid, NULL, 0) != entry->pid)
+ status = -1;
+
+ entry->pipe = NULL;
+ entry->pid = 0;
+ return (status);
+}
+
+
+/* Unix slow poll (without special support for Linux)
+ *
+ * If a few of the randomness sources create a large amount of output then
+ * the slowPoll() stops once the buffer has been filled (but before all the
+ * randomness sources have been sucked dry) so that the 'usefulness' factor
+ * remains below the threshold. For this reason the gatherer buffer has to
+ * be fairly sizeable on moderately loaded systems. This is something of a
+ * bug since the usefulness should be influenced by the amount of output as
+ * well as the source type */
+
+
+static int
+slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
+{
+ int moreSources;
+ struct timeval tv;
+ fd_set fds;
+#if defined( __hpux )
+ size_t maxFD = 0;
+#else
+ int maxFD = 0;
+#endif /* OS-specific brokenness */
+ int bufPos, i, usefulness = 0;
+ int last_so_far = 0;
+ int any_need_entropy = 0;
+ int delay;
+ int rc;
+
+ /* Fire up each randomness source */
+ FD_ZERO(&fds);
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ /* Since popen() is a fairly heavy function, we check to see whether
+ * the executable exists before we try to run it */
+ if (access(dataSources[i].path, X_OK)) {
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "%s not present%s\n", dataSources[i].path,
+ dataSources[i].hasAlternative ?
+ ", has alternatives" : "");
+ dataSources[i].pipe = NULL;
+ }
+ else
+ dataSources[i].pipe = my_popen(&dataSources[i]);
+
+ if (dataSources[i].pipe != NULL) {
+ dataSources[i].pipeFD = fileno(dataSources[i].pipe);
+ if (dataSources[i].pipeFD > maxFD)
+ maxFD = dataSources[i].pipeFD;
+
+#ifdef O_NONBLOCK /* Ohhh what a hack (used for Atari) */
+ fcntl(dataSources[i].pipeFD, F_SETFL, O_NONBLOCK);
+#else
+#error O_NONBLOCK is missing
+#endif
+
+ FD_SET(dataSources[i].pipeFD, &fds);
+ dataSources[i].length = 0;
+
+ /* If there are alternatives for this command, don't try and
+ * execute them */
+ while (dataSources[i].hasAlternative) {
+ if( dbgfp && dbgall )
+ fprintf(dbgfp, "Skipping %s\n", dataSources[i + 1].path);
+ i++;
+ }
+ }
+ }
+
+
+ /* Suck all the data we can get from each of the sources */
+ bufPos = 0;
+ moreSources = 1;
+ delay = 0; /* Return immediately (well, after 100ms) the first time. */
+ while (moreSources && bufPos <= gather_buffer_size) {
+ /* Wait for data to become available from any of the sources, with a
+ * timeout of 10 seconds. This adds even more randomness since data
+ * becomes available in a nondeterministic fashion. Kudos to HP's QA
+ * department for managing to ship a select() which breaks its own
+ * prototype */
+ tv.tv_sec = delay;
+ tv.tv_usec = delay? 0 : 100000;
+
+#if defined( __hpux ) && ( OS_VERSION == 9 )
+ rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv);
+#else /* */
+ rc = select(maxFD + 1, &fds, NULL, NULL, &tv);
+#endif /* __hpux */
+ if (rc == -1)
+ break; /* Ooops; select failed. */
+
+ if (!rc)
+ {
+ /* FIXME: Because we run several tools at once it is
+ unlikely that we will see a block in select at all. */
+ if (!any_need_entropy
+ || last_so_far != (gather_buffer_size - bufPos) )
+ {
+ last_so_far = gather_buffer_size - bufPos;
+ _gcry_random_progress ("need_entropy", 'X',
+ last_so_far,
+ gather_buffer_size);
+ any_need_entropy = 1;
+ }
+ delay = 10; /* Use 10 seconds henceforth. */
+ /* Note that the fd_set is setup again at the end of this loop. */
+ }
+
+ /* One of the sources has data available, read it into the buffer */
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) {
+ size_t noBytes;
+
+ if ((noBytes = fread(gather_buffer + bufPos, 1,
+ gather_buffer_size - bufPos,
+ dataSources[i].pipe)) == 0) {
+ if (my_pclose(&dataSources[i]) == 0) {
+ int total = 0;
+
+ /* Try and estimate how much entropy we're getting
+ * from a data source */
+ if (dataSources[i].usefulness) {
+ if (dataSources[i].usefulness < 0)
+ total = (dataSources[i].length + 999)
+ / -dataSources[i].usefulness;
+ else
+ total = dataSources[i].length
+ / dataSources[i].usefulness;
+ }
+ if( dbgfp )
+ fprintf(dbgfp,
+ "%s %s contributed %d bytes, "
+ "usefulness = %d\n", dataSources[i].path,
+ (dataSources[i].arg != NULL) ?
+ dataSources[i].arg : "",
+ dataSources[i].length, total);
+ if( dataSources[i].length )
+ usefulness += total;
+ }
+ dataSources[i].pipe = NULL;
+ }
+ else {
+ int currPos = bufPos;
+ int endPos = bufPos + noBytes;
+
+ /* Run-length compress the input byte sequence */
+ while (currPos < endPos) {
+ int ch = gather_buffer[currPos];
+
+ /* If it's a single byte, just copy it over */
+ if (ch != gather_buffer[currPos + 1]) {
+ gather_buffer[bufPos++] = ch;
+ currPos++;
+ }
+ else {
+ int count = 0;
+
+ /* It's a run of repeated bytes, replace them
+ * with the byte count mod 256 */
+ while ((ch == gather_buffer[currPos])
+ && currPos < endPos) {
+ count++;
+ currPos++;
+ }
+ gather_buffer[bufPos++] = count;
+ noBytes -= count - 1;
+ }
+ }
+
+ /* Remember the number of (compressed) bytes of input we
+ * obtained */
+ dataSources[i].length += noBytes;
+ }
+ }
+ }
+
+ /* Check if there is more input available on any of the sources */
+ moreSources = 0;
+ FD_ZERO(&fds);
+ for (i = 0; dataSources[i].path != NULL; i++) {
+ if (dataSources[i].pipe != NULL) {
+ FD_SET(dataSources[i].pipeFD, &fds);
+ moreSources = 1;
+ }
+ }
+ }
+
+ if (any_need_entropy)
+ _gcry_random_progress ("need_entropy", 'X',
+ gather_buffer_size,
+ gather_buffer_size);
+
+ if( dbgfp ) {
+ fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness);
+ fflush(dbgfp);
+ }
+ *nbytes = bufPos;
+ return usefulness;
+}
+
+/****************
+ * Start the gatherer process which writes messages of
+ * type GATHERER_MSG to pipedes
+ */
+static void
+start_gatherer( int pipefd )
+{
+ FILE *dbgfp = NULL;
+ int dbgall;
+
+ {
+ const char *s = getenv("GNUPG_RNDUNIX_DBG");
+ if( s ) {
+ dbgfp = (*s=='-' && !s[1])? stdout : fopen(s, "a");
+ if( !dbgfp )
+ log_info("can't open debug file `%s': %s\n",
+ s, strerror(errno) );
+ else
+ fprintf(dbgfp,"\nSTART RNDUNIX DEBUG pid=%d\n", (int)getpid());
+ }
+ dbgall = !!getenv("GNUPG_RNDUNIX_DBGALL");
+ }
+ /* close all files but the ones we need */
+ { int nmax, n1, n2, i;
+#ifdef _SC_OPEN_MAX
+ if( (nmax=sysconf( _SC_OPEN_MAX )) < 0 ) {
+#ifdef _POSIX_OPEN_MAX
+ nmax = _POSIX_OPEN_MAX;
+#else
+ nmax = 20; /* assume a reasonable value */
+#endif
+ }
+#else /*!_SC_OPEN_MAX*/
+ nmax = 20; /* assume a reasonable value */
+#endif /*!_SC_OPEN_MAX*/
+ n1 = fileno( stderr );
+ n2 = dbgfp? fileno( dbgfp ) : -1;
+ for(i=0; i < nmax; i++ ) {
+ if( i != n1 && i != n2 && i != pipefd )
+ close(i);
+ }
+ errno = 0;
+ }
+
+
+ /* Set up the buffer. Not ethat we use a plain standard malloc here. */
+ gather_buffer_size = GATHER_BUFSIZE;
+ gather_buffer = malloc( gather_buffer_size );
+ if( !gather_buffer ) {
+ log_error("out of core while allocating the gatherer buffer\n");
+ exit(2);
+ }
+
+ /* Reset the SIGC(H)LD handler to the system default. This is necessary
+ * because if the program which cryptlib is a part of installs its own
+ * SIGC(H)LD handler, it will end up reaping the cryptlib children before
+ * cryptlib can. As a result, my_pclose() will call waitpid() on a
+ * process which has already been reaped by the installed handler and
+ * return an error, so the read data won't be added to the randomness
+ * pool. There are two types of SIGC(H)LD naming, the SysV SIGCLD and
+ * the BSD/Posix SIGCHLD, so we need to handle either possibility */
+#ifdef SIGCLD
+ signal(SIGCLD, SIG_DFL);
+#else
+ signal(SIGCHLD, SIG_DFL);
+#endif
+
+ fclose(stderr); /* Arrghh!! It's Stuart code!! */
+
+ for(;;) {
+ GATHER_MSG msg;
+ size_t nbytes;
+ const char *p;
+
+ msg.usefulness = slow_poll( dbgfp, dbgall, &nbytes );
+ p = gather_buffer;
+ while( nbytes ) {
+ msg.ndata = nbytes > sizeof(msg.data)? sizeof(msg.data) : nbytes;
+ memcpy( msg.data, p, msg.ndata );
+ nbytes -= msg.ndata;
+ p += msg.ndata;
+
+ while( write( pipefd, &msg, sizeof(msg) ) != sizeof(msg) ) {
+ if( errno == EINTR )
+ continue;
+ if( errno == EAGAIN ) {
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 50000;
+ select(0, NULL, NULL, NULL, &tv);
+ continue;
+ }
+ if( errno == EPIPE ) /* parent has exited, so give up */
+ exit(0);
+
+ /* we can't do very much here because stderr is closed */
+ if( dbgfp )
+ fprintf(dbgfp, "gatherer can't write to pipe: %s\n",
+ strerror(errno) );
+ /* we start a new poll to give the system some time */
+ nbytes = 0;
+ break;
+ }
+ }
+ }
+ /* we are killed when the parent dies */
+}
+
+
+static int
+read_a_msg( int fd, GATHER_MSG *msg )
+{
+ char *buffer = (char*)msg;
+ size_t length = sizeof( *msg );
+ int n;
+
+ do {
+ do {
+ n = read(fd, buffer, length );
+ } while( n == -1 && errno == EINTR );
+ if( n == -1 )
+ return -1;
+ buffer += n;
+ length -= n;
+ } while( length );
+ return 0;
+}
+
+
+/****************
+ * Using a level of 0 should never block and better add nothing
+ * to the pool. So this is just a dummy for this gatherer.
+ */
+int
+_gcry_rndunix_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static pid_t gatherer_pid = 0;
+ static int pipedes[2];
+ GATHER_MSG msg;
+ size_t n;
+
+ if( !level )
+ return 0;
+
+ if( !gatherer_pid ) {
+ /* Make sure we are not setuid. */
+ if ( getuid() != geteuid() )
+ BUG();
+ /* time to start the gatherer process */
+ if( pipe( pipedes ) ) {
+ log_error("pipe() failed: %s\n", strerror(errno));
+ return -1;
+ }
+ gatherer_pid = fork();
+ if( gatherer_pid == -1 ) {
+ log_error("can't for gatherer process: %s\n", strerror(errno));
+ return -1;
+ }
+ if( !gatherer_pid ) {
+ start_gatherer( pipedes[1] );
+ /* oops, can't happen */
+ return -1;
+ }
+ }
+
+ /* now read from the gatherer */
+ while( length ) {
+ int goodness;
+ ulong subtract;
+
+ if( read_a_msg( pipedes[0], &msg ) ) {
+ log_error("reading from gatherer pipe failed: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+
+ if( level > 1 ) {
+ if( msg.usefulness > 30 )
+ goodness = 100;
+ else if ( msg.usefulness )
+ goodness = msg.usefulness * 100 / 30;
+ else
+ goodness = 0;
+ }
+ else if( level ) {
+ if( msg.usefulness > 15 )
+ goodness = 100;
+ else if ( msg.usefulness )
+ goodness = msg.usefulness * 100 / 15;
+ else
+ goodness = 0;
+ }
+ else
+ goodness = 100; /* goodness of level 0 is always 100 % */
+
+ n = msg.ndata;
+ if( n > length )
+ n = length;
+ (*add)( msg.data, n, origin );
+
+ /* this is the trick how we cope with the goodness */
+ subtract = (ulong)n * goodness / 100;
+ /* subtract at least 1 byte to avoid infinite loops */
+ length -= subtract ? subtract : 1;
+ }
+
+ return 0;
+}
--- /dev/null
+/* rndw32.c - W32 entropy gatherer
+ * Copyright (C) 1999, 2000, 2002, 2003, 2007,
+ * 2010 Free Software Foundation, Inc.
+ * Copyright Peter Gutmann, Matt Thomlinson and Blake Coverett 1996-2006
+ *
+ * This file is part of Libgcrypt.
+ *
+ *************************************************************************
+ * The code here is based on code from Cryptlib 3.0 beta by Peter Gutmann.
+ * Source file misc/rndwin32.c "Win32 Randomness-Gathering Code" with this
+ * copyright notice:
+ *
+ * This module is part of the cryptlib continuously seeded pseudorandom
+ * number generator. For usage conditions, see lib_rand.c
+ *
+ * [Here is the notice from lib_rand.c, which is now called dev_sys.c]
+ *
+ * This module and the misc/rnd*.c modules represent the cryptlib
+ * continuously seeded pseudorandom number generator (CSPRNG) as described in
+ * my 1998 Usenix Security Symposium paper "The generation of random numbers
+ * for cryptographic purposes".
+ *
+ * The CSPRNG code is copyright Peter Gutmann (and various others) 1996,
+ * 1997, 1998, 1999, all rights reserved. Redistribution of the CSPRNG
+ * modules and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice
+ * and this permission notice in its entirety.
+ *
+ * 2. Redistributions in binary form must reproduce the copyright notice in
+ * the documentation and/or other materials provided with the distribution.
+ *
+ * 3. A copy of any bugfixes or enhancements made must be provided to the
+ * author, <pgut001@cs.auckland.ac.nz> to allow them to be added to the
+ * baseline version of the code.
+ *
+ * ALTERNATIVELY, the code may be distributed under the terms of the
+ * GNU Lesser General Public License, version 2.1 or any later version
+ * published by the Free Software Foundation, in which case the
+ * provisions of the GNU LGPL are required INSTEAD OF the above
+ * restrictions.
+ *
+ * Although not required under the terms of the LGPL, it would still
+ * be nice if you could make any changes available to the author to
+ * allow a consistent code base to be maintained.
+ *************************************************************************
+ * The above alternative was changed from GPL to LGPL on 2007-08-22 with
+ * permission from Peter Gutmann:
+ *==========
+ From: pgut001 <pgut001@cs.auckland.ac.nz>
+ Subject: Re: LGPL for the windows entropy gatherer
+ To: wk@gnupg.org
+ Date: Wed, 22 Aug 2007 03:05:42 +1200
+
+ Hi,
+
+ >As of now libgcrypt is GPL under Windows due to that module and some people
+ >would really like to see it under LGPL too. Can you do such a license change
+ >to LGPL version 2? Note that LGPL give the user the option to relicense it
+ >under GPL, so the change would be pretty easy and backwar compatible.
+
+ Sure. I assumed that since GPG was GPLd, you'd prefer the GPL for the entropy
+ code as well, but Ian asked for LGPL as an option so as of the next release
+ I'll have LGPL in there. You can consider it to be retroactive, so your
+ current version will be LGPLd as well.
+
+ Peter.
+ *==========
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#ifdef __GNUC__
+#include <stdint.h>
+#endif
+
+#include <windows.h>
+
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+
+/* Definitions which are missing from the current GNU Windows32Api. */
+#ifndef IOCTL_DISK_PERFORMANCE
+#define IOCTL_DISK_PERFORMANCE 0x00070020
+#endif
+
+/* This used to be (6*8+5*4+8*2), but Peter Gutmann figured a larger
+ value in a newer release. So we use a far larger value. */
+#define SIZEOF_DISK_PERFORMANCE_STRUCT 256
+
+/* We don't include wincrypt.h so define it here. */
+#define HCRYPTPROV HANDLE
+
+
+/* When we query the performance counters, we allocate an initial buffer and
+ * then reallocate it as required until RegQueryValueEx() stops returning
+ * ERROR_MORE_DATA. The following values define the initial buffer size and
+ * step size by which the buffer is increased
+ */
+#define PERFORMANCE_BUFFER_SIZE 65536 /* Start at 64K */
+#define PERFORMANCE_BUFFER_STEP 16384 /* Step by 16K */
+
+
+/* The number of bytes to read from the system RNG on each slow poll. */
+#define SYSTEMRNG_BYTES 64
+
+/* Intel Chipset CSP type and name */
+#define PROV_INTEL_SEC 22
+#define INTEL_DEF_PROV "Intel Hardware Cryptographic Service Provider"
+
+
+
+
+/* Type definitions for function pointers to call NetAPI32 functions. */
+typedef DWORD (WINAPI *NETSTATISTICSGET)(LPWSTR szServer, LPWSTR szService,
+ DWORD dwLevel, DWORD dwOptions,
+ LPBYTE *lpBuffer);
+typedef DWORD (WINAPI *NETAPIBUFFERSIZE)(LPVOID lpBuffer, LPDWORD cbBuffer);
+typedef DWORD (WINAPI *NETAPIBUFFERFREE)(LPVOID lpBuffer);
+
+/* Type definitions for function pointers to call native NT functions. */
+typedef DWORD (WINAPI *NTQUERYSYSTEMINFORMATION)(DWORD systemInformationClass,
+ PVOID systemInformation,
+ ULONG systemInformationLength,
+ PULONG returnLength);
+typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS)
+ (HANDLE processHandle, DWORD processInformationClass,
+ PVOID processInformation, ULONG processInformationLength,
+ PULONG returnLength);
+typedef DWORD (WINAPI *NTPOWERINFORMATION)
+ (DWORD powerInformationClass, PVOID inputBuffer,
+ ULONG inputBufferLength, PVOID outputBuffer, ULONG outputBufferLength );
+
+/* Type definitions for function pointers to call CryptoAPI functions. */
+typedef BOOL (WINAPI *CRYPTACQUIRECONTEXT)(HCRYPTPROV *phProv,
+ LPCTSTR pszContainer,
+ LPCTSTR pszProvider,
+ DWORD dwProvType,
+ DWORD dwFlags);
+typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,
+ BYTE *pbBuffer);
+typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);
+
+/* Somewhat alternative functionality available as a direct call, for
+ Windows XP and newer. This is the CryptoAPI RNG, which isn't anywhere
+ near as good as the HW RNG, but we use it if it's present on the basis
+ that at least it can't make things any worse. This direct access version
+ is only available under Windows XP, we don't go out of our way to access
+ the more general CryptoAPI one since the main purpose of using it is to
+ take advantage of any possible future hardware RNGs that may be added,
+ for example via TCPA devices. */
+typedef BOOL (WINAPI *RTLGENRANDOM)(PVOID RandomBuffer,
+ ULONG RandomBufferLength);
+
+
+
+/* MBM data structures, originally by Alexander van Kaam, converted to C by
+ Anders@Majland.org, finally updated by Chris Zahrt <techn0@iastate.edu> */
+#define BusType char
+#define SMBType char
+#define SensorType char
+
+typedef struct
+{
+ SensorType iType; /* Type of sensor. */
+ int Count; /* Number of sensor for that type. */
+} SharedIndex;
+
+typedef struct
+{
+ SensorType ssType; /* Type of sensor */
+ unsigned char ssName[12]; /* Name of sensor */
+ char sspadding1[3]; /* Padding of 3 bytes */
+ double ssCurrent; /* Current value */
+ double ssLow; /* Lowest readout */
+ double ssHigh; /* Highest readout */
+ long ssCount; /* Total number of readout */
+ char sspadding2[4]; /* Padding of 4 bytes */
+ long double ssTotal; /* Total amout of all readouts */
+ char sspadding3[6]; /* Padding of 6 bytes */
+ double ssAlarm1; /* Temp & fan: high alarm; voltage: % off */
+ double ssAlarm2; /* Temp: low alarm */
+} SharedSensor;
+
+typedef struct
+{
+ short siSMB_Base; /* SMBus base address */
+ BusType siSMB_Type; /* SMBus/Isa bus used to access chip */
+ SMBType siSMB_Code; /* SMBus sub type, Intel, AMD or ALi */
+ char siSMB_Addr; /* Address of sensor chip on SMBus */
+ unsigned char siSMB_Name[41]; /* Nice name for SMBus */
+ short siISA_Base; /* ISA base address of sensor chip on ISA */
+ int siChipType; /* Chip nr, connects with Chipinfo.ini */
+ char siVoltageSubType; /* Subvoltage option selected */
+} SharedInfo;
+
+typedef struct
+{
+ double sdVersion; /* Version number (example: 51090) */
+ SharedIndex sdIndex[10]; /* Sensor index */
+ SharedSensor sdSensor[100]; /* Sensor info */
+ SharedInfo sdInfo; /* Misc.info */
+ unsigned char sdStart[41]; /* Start time */
+
+ /* We don't use the next two fields both because they're not random
+ and because it provides a nice safety margin in case of data size
+ mis- estimates (we always under-estimate the buffer size). */
+#if 0
+ unsigned char sdCurrent[41]; /* Current time */
+ unsigned char sdPath[256]; /* MBM path */
+#endif /*0*/
+} SharedData;
+
+
+
+/* One time intialized handles and function pointers. We use dynamic
+ loading of the DLLs to do without them in case libgcrypt does not
+ need any random. */
+static HANDLE hNetAPI32;
+static NETSTATISTICSGET pNetStatisticsGet;
+static NETAPIBUFFERSIZE pNetApiBufferSize;
+static NETAPIBUFFERFREE pNetApiBufferFree;
+
+static HANDLE hNTAPI;
+static NTQUERYSYSTEMINFORMATION pNtQuerySystemInformation;
+static NTQUERYINFORMATIONPROCESS pNtQueryInformationProcess;
+static NTPOWERINFORMATION pNtPowerInformation;
+
+static HANDLE hAdvAPI32;
+static CRYPTACQUIRECONTEXT pCryptAcquireContext;
+static CRYPTGENRANDOM pCryptGenRandom;
+static CRYPTRELEASECONTEXT pCryptReleaseContext;
+static RTLGENRANDOM pRtlGenRandom;
+
+
+/* Other module global variables. */
+static int system_rng_available; /* Whether a system RNG is available. */
+static HCRYPTPROV hRNGProv; /* Handle to Intel RNG CSP. */
+
+static int debug_me; /* Debug flag. */
+
+static int system_is_w2000; /* True if running on W2000. */
+
+
+
+\f
+/* Try and connect to the system RNG if there's one present. */
+static void
+init_system_rng (void)
+{
+ system_rng_available = 0;
+ hRNGProv = NULL;
+
+ hAdvAPI32 = GetModuleHandle ("AdvAPI32.dll");
+ if (!hAdvAPI32)
+ return;
+
+ pCryptAcquireContext = (CRYPTACQUIRECONTEXT)
+ GetProcAddress (hAdvAPI32, "CryptAcquireContextA");
+ pCryptGenRandom = (CRYPTGENRANDOM)
+ GetProcAddress (hAdvAPI32, "CryptGenRandom");
+ pCryptReleaseContext = (CRYPTRELEASECONTEXT)
+ GetProcAddress (hAdvAPI32, "CryptReleaseContext");
+
+ /* Get a pointer to the native randomness function if it's available.
+ This isn't exported by name, so we have to get it by ordinal. */
+ pRtlGenRandom = (RTLGENRANDOM)
+ GetProcAddress (hAdvAPI32, "SystemFunction036");
+
+ /* Try and connect to the PIII RNG CSP. The AMD 768 southbridge (from
+ the 760 MP chipset) also has a hardware RNG, but there doesn't appear
+ to be any driver support for this as there is for the Intel RNG so we
+ can't do much with it. OTOH the Intel RNG is also effectively dead
+ as well, mostly due to virtually nonexistent support/marketing by
+ Intel, it's included here mostly for form's sake. */
+ if ( (!pCryptAcquireContext || !pCryptGenRandom || !pCryptReleaseContext
+ || !pCryptAcquireContext (&hRNGProv, NULL, INTEL_DEF_PROV,
+ PROV_INTEL_SEC, 0) )
+ && !pRtlGenRandom)
+ {
+ hAdvAPI32 = NULL;
+ }
+ else
+ system_rng_available = 1;
+}
+
+
+/* Read data from the system RNG if availavle. */
+static void
+read_system_rng (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ BYTE buffer[ SYSTEMRNG_BYTES + 8 ];
+ int quality = 0;
+
+ if (!system_rng_available)
+ return;
+
+ /* Read SYSTEMRNG_BYTES bytes from the system RNG. We don't rely on
+ this for all our randomness requirements (particularly the
+ software RNG) in case it's broken in some way. */
+ if (hRNGProv)
+ {
+ if (pCryptGenRandom (hRNGProv, SYSTEMRNG_BYTES, buffer))
+ quality = 80;
+ }
+ else if (pRtlGenRandom)
+ {
+ if ( pRtlGenRandom (buffer, SYSTEMRNG_BYTES))
+ quality = 50;
+ }
+ if (quality > 0)
+ {
+ if (debug_me)
+ log_debug ("rndw32#read_system_rng: got %d bytes of quality %d\n",
+ SYSTEMRNG_BYTES, quality);
+ (*add) (buffer, SYSTEMRNG_BYTES, requester);
+ wipememory (buffer, SYSTEMRNG_BYTES);
+ }
+}
+
+
+/* Read data from MBM. This communicates via shared memory, so all we
+ need to do is map a file and read the data out. */
+static void
+read_mbm_data (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ HANDLE hMBMData;
+ SharedData *mbmDataPtr;
+
+ hMBMData = OpenFileMapping (FILE_MAP_READ, FALSE, "$M$B$M$5$S$D$" );
+ if (hMBMData)
+ {
+ mbmDataPtr = (SharedData*)MapViewOfFile (hMBMData, FILE_MAP_READ,0,0,0);
+ if (mbmDataPtr)
+ {
+ if (debug_me)
+ log_debug ("rndw32#read_mbm_data: got %d bytes\n",
+ (int)sizeof (SharedData));
+ (*add) (mbmDataPtr, sizeof (SharedData), requester);
+ UnmapViewOfFile (mbmDataPtr);
+ }
+ CloseHandle (hMBMData);
+ }
+}
+
+
+/* Fallback method using the registry to poll the statistics. */
+static void
+registry_poll (void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester)
+{
+ static int cbPerfData = PERFORMANCE_BUFFER_SIZE;
+ int iterations;
+ DWORD dwSize, status;
+ PERF_DATA_BLOCK *pPerfData;
+
+ /* Get information from the system performance counters. This can take a
+ few seconds to do. In some environments the call to RegQueryValueEx()
+ can produce an access violation at some random time in the future, in
+ some cases adding a short delay after the following code block makes
+ the problem go away. This problem is extremely difficult to
+ reproduce, I haven't been able to get it to occur despite running it
+ on a number of machines. MS knowledge base article Q178887 covers
+ this type of problem, it's typically caused by an external driver or
+ other program that adds its own values under the
+ HKEY_PERFORMANCE_DATA key. The NT kernel, via Advapi32.dll, calls the
+ required external module to map in the data inside an SEH try/except
+ block, so problems in the module's collect function don't pop up until
+ after it has finished, so the fault appears to occur in Advapi32.dll.
+ There may be problems in the NT kernel as well though, a low-level
+ memory checker indicated that ExpandEnvironmentStrings() in
+ Kernel32.dll, called an interminable number of calls down inside
+ RegQueryValueEx(), was overwriting memory (it wrote twice the
+ allocated size of a buffer to a buffer allocated by the NT kernel).
+ OTOH this could be coming from the external module calling back into
+ the kernel, which eventually causes the problem described above.
+
+ Possibly as an extension of the problem that the krnlWaitSemaphore()
+ call above works around, running two instances of cryptlib (e.g. two
+ applications that use it) under NT4 can result in one of them hanging
+ in the RegQueryValueEx() call. This happens only under NT4 and is
+ hard to reproduce in any consistent manner.
+
+ One workaround that helps a bit is to read the registry as a remote
+ (rather than local) registry, it's possible that the use of a network
+ RPC call isolates the calling app from the problem in that whatever
+ service handles the RPC is taking the hit and not affecting the
+ calling app. Since this would require another round of extensive
+ testing to verify and the NT native API call is working fine, we'll
+ stick with the native API call for now.
+
+ Some versions of NT4 had a problem where the amount of data returned
+ was mis-reported and would never settle down, because of this the code
+ below includes a safety-catch that bails out after 10 attempts have
+ been made, this results in no data being returned but at does ensure
+ that the thread will terminate.
+
+ In addition to these problems the code in RegQueryValueEx() that
+ estimates the amount of memory required to return the performance
+ counter information isn't very accurate (it's much worse than the
+ "slightly-inaccurate" level that the MS docs warn about, it's usually
+ wildly off) since it always returns a worst-case estimate which is
+ usually nowhere near the actual amount required. For example it may
+ report that 128K of memory is required, but only return 64K of data.
+
+ Even worse than the registry-based performance counters is the
+ performance data helper (PDH) shim that tries to make the counters
+ look like the old Win16 API (which is also used by Win95). Under NT
+ this can consume tens of MB of memory and huge amounts of CPU time
+ while it gathers its data, and even running once can still consume
+ about 1/2MB of memory */
+ if (getenv ("GNUPG_RNDW32_NOPERF"))
+ {
+ static int shown;
+
+ if (!shown)
+ {
+ shown = 1;
+ log_info ("note: get performance data has been disabled\n");
+ }
+ }
+ else
+ {
+ pPerfData = gcry_xmalloc (cbPerfData);
+ for (iterations=0; iterations < 10; iterations++)
+ {
+ dwSize = cbPerfData;
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer_nt: get perf data\n" );
+
+ status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
+ NULL, (LPBYTE) pPerfData, &dwSize);
+ if (status == ERROR_SUCCESS)
+ {
+ if (!memcmp (pPerfData->Signature, L"PERF", 8))
+ (*add) ( pPerfData, dwSize, requester );
+ else
+ log_debug ("rndw32: no PERF signature\n");
+ break;
+ }
+ else if (status == ERROR_MORE_DATA)
+ {
+ cbPerfData += PERFORMANCE_BUFFER_STEP;
+ pPerfData = gcry_xrealloc (pPerfData, cbPerfData);
+ }
+ else
+ {
+ static int been_here;
+
+ /* Silence the error message. In particular under Wine (as
+ of 2008) we would get swamped with such diagnotiscs. One
+ such diagnotiscs should be enough. */
+ if (been_here != status)
+ {
+ been_here = status;
+ log_debug ("rndw32: get performance data problem: ec=%ld\n",
+ status);
+ }
+ break;
+ }
+ }
+ gcry_free (pPerfData);
+ }
+
+ /* Although this isn't documented in the Win32 API docs, it's necessary
+ to explicitly close the HKEY_PERFORMANCE_DATA key after use (it's
+ implicitly opened on the first call to RegQueryValueEx()). If this
+ isn't done then any system components which provide performance data
+ can't be removed or changed while the handle remains active. */
+ RegCloseKey (HKEY_PERFORMANCE_DATA);
+}
+
+
+static void
+slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
+ enum random_origins requester )
+{
+ static int is_initialized = 0;
+ static int is_workstation = 1;
+ HANDLE hDevice;
+ DWORD dwType, dwSize, dwResult;
+ ULONG ulSize;
+ int drive_no, status;
+ int no_results = 0;
+ void *buffer;
+
+ if ( !is_initialized )
+ {
+ HKEY hKey;
+
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: init toolkit\n" );
+ /* Find out whether this is an NT server or workstation if necessary */
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
+ "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
+ 0, KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ BYTE szValue[32 + 8];
+ dwSize = 32;
+
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: check product options\n" );
+
+ status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
+ szValue, &dwSize);
+ if (status == ERROR_SUCCESS && stricmp (szValue, "WinNT"))
+ {
+ /* Note: There are (at least) three cases for ProductType:
+ WinNT = NT Workstation, ServerNT = NT Server, LanmanNT =
+ NT Server acting as a Domain Controller. */
+ is_workstation = 0;
+ if ( debug_me )
+ log_debug ("rndw32: this is a NT server\n");
+ }
+ RegCloseKey (hKey);
+ }
+
+ /* The following are fixed for the lifetime of the process so we
+ only add them once */
+ /* readPnPData (); - we have not implemented that. */
+
+ /* Initialize the NetAPI32 function pointers if necessary */
+ hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
+ if (hNetAPI32)
+ {
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: netapi32 loaded\n" );
+ pNetStatisticsGet = (NETSTATISTICSGET)
+ GetProcAddress (hNetAPI32, "NetStatisticsGet");
+ pNetApiBufferSize = (NETAPIBUFFERSIZE)
+ GetProcAddress (hNetAPI32, "NetApiBufferSize");
+ pNetApiBufferFree = (NETAPIBUFFERFREE)
+ GetProcAddress (hNetAPI32, "NetApiBufferFree");
+
+ if (!pNetStatisticsGet || !pNetApiBufferSize || !pNetApiBufferFree)
+ {
+ FreeLibrary (hNetAPI32);
+ hNetAPI32 = NULL;
+ log_debug ("rndw32: No NETAPI found\n" );
+ }
+ }
+
+ /* Initialize the NT kernel native API function pointers if necessary */
+ hNTAPI = GetModuleHandle ("NTDll.dll");
+ if (hNTAPI)
+ {
+ /* Get a pointer to the NT native information query functions */
+ pNtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)
+ GetProcAddress (hNTAPI, "NtQuerySystemInformation");
+ pNtQueryInformationProcess = (NTQUERYINFORMATIONPROCESS)
+ GetProcAddress (hNTAPI, "NtQueryInformationProcess");
+ pNtPowerInformation = (NTPOWERINFORMATION)
+ GetProcAddress(hNTAPI, "NtPowerInformation");
+
+ if (!pNtQuerySystemInformation || !pNtQueryInformationProcess)
+ hNTAPI = NULL;
+ }
+
+
+ is_initialized = 1;
+ }
+
+ read_system_rng ( add, requester );
+ read_mbm_data ( add, requester );
+
+ /* Get network statistics. Note: Both NT Workstation and NT Server by
+ default will be running both the workstation and server services. The
+ heuristic below is probably useful though on the assumption that the
+ majority of the network traffic will be via the appropriate service.
+ In any case the network statistics return almost no randomness. */
+ {
+ LPBYTE lpBuffer;
+
+ if (hNetAPI32
+ && !pNetStatisticsGet (NULL,
+ is_workstation ? L"LanmanWorkstation" :
+ L"LanmanServer", 0, 0, &lpBuffer))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: get netstats\n" );
+ pNetApiBufferSize (lpBuffer, &dwSize);
+ (*add) ( lpBuffer, dwSize, requester );
+ pNetApiBufferFree (lpBuffer);
+ }
+ }
+
+ /* Get disk I/O statistics for all the hard drives. 100 is an
+ arbitrary failsafe limit. */
+ for (drive_no = 0; drive_no < 100 ; drive_no++)
+ {
+ char diskPerformance[SIZEOF_DISK_PERFORMANCE_STRUCT + 8];
+ char szDevice[50];
+
+ /* Check whether we can access this device. */
+ snprintf (szDevice, sizeof szDevice, "\\\\.\\PhysicalDrive%d",
+ drive_no);
+ hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, 0, NULL);
+ if (hDevice == INVALID_HANDLE_VALUE)
+ break; /* No more drives. */
+
+ /* Note: This only works if you have turned on the disk performance
+ counters with 'diskperf -y'. These counters are off by default. */
+ dwSize = sizeof diskPerformance;
+ if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
+ diskPerformance, SIZEOF_DISK_PERFORMANCE_STRUCT,
+ &dwSize, NULL))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#slow_gatherer: iostat drive %d\n",
+ drive_no);
+ (*add) (diskPerformance, dwSize, requester);
+ }
+ else
+ {
+ log_info ("NOTE: you should run 'diskperf -y' "
+ "to enable the disk statistics\n");
+ }
+ CloseHandle (hDevice);
+ }
+
+ /* In theory we should be using the Win32 performance query API to obtain
+ unpredictable data from the system, however this is so unreliable (see
+ the multiple sets of comments in registryPoll()) that it's too risky
+ to rely on it except as a fallback in emergencies. Instead, we rely
+ mostly on the NT native API function NtQuerySystemInformation(), which
+ has the dual advantages that it doesn't have as many (known) problems
+ as the Win32 equivalent and that it doesn't access the data indirectly
+ via pseudo-registry keys, which means that it's much faster. Note
+ that the Win32 equivalent actually works almost all of the time, the
+ problem is that on one or two systems it can fail in strange ways that
+ are never the same and can't be reproduced on any other system, which
+ is why we use the native API here. Microsoft officially documented
+ this function in early 2003, so it'll be fairly safe to use. */
+ if ( !hNTAPI )
+ {
+ registry_poll (add, requester);
+ return;
+ }
+
+
+ /* Scan the first 64 possible information types (we don't bother with
+ increasing the buffer size as we do with the Win32 version of the
+ performance data read, we may miss a few classes but it's no big deal).
+ This scan typically yields around 20 pieces of data, there's nothing
+ in the range 65...128 so chances are there won't be anything above
+ there either. */
+ buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE);
+ for (dwType = 0; dwType < 64; dwType++)
+ {
+ switch (dwType)
+ {
+ /* ID 17 = SystemObjectInformation hangs on some win2k systems. */
+ case 17:
+ if (system_is_w2000)
+ continue;
+ break;
+
+ /* Some information types are write-only (the IDs are shared with
+ a set-information call), we skip these. */
+ case 26: case 27: case 38: case 46: case 47: case 48: case 52:
+ continue;
+
+ /* ID 53 = SystemSessionProcessInformation reads input from the
+ output buffer, which has to contain a session ID and pointer
+ to the actual buffer in which to store the session information.
+ Because this isn't a standard query, we skip this. */
+ case 53:
+ continue;
+ }
+
+ /* Query the info for this ID. Some results (for example for
+ ID = 6, SystemCallCounts) are only available in checked builds
+ of the kernel. A smaller subcless of results require that
+ certain system config flags be set, for example
+ SystemObjectInformation requires that the
+ FLG_MAINTAIN_OBJECT_TYPELIST be set in NtGlobalFlags. To avoid
+ having to special-case all of these, we try reading each one and
+ only use those for which we get a success status. */
+ dwResult = pNtQuerySystemInformation (dwType, buffer,
+ PERFORMANCE_BUFFER_SIZE - 2048,
+ &ulSize);
+ if (dwResult != ERROR_SUCCESS)
+ continue;
+
+ /* Some calls (e.g. ID = 23, SystemProcessorStatistics, and ID = 24,
+ SystemDpcInformation) incorrectly return a length of zero, so we
+ manually adjust the length to the correct value. */
+ if ( !ulSize )
+ {
+ if (dwType == 23)
+ ulSize = 6 * sizeof (ULONG);
+ else if (dwType == 24)
+ ulSize = 5 * sizeof (ULONG);
+ }
+
+ /* If we got some data back, add it to the entropy pool. */
+ if (ulSize > 0 && ulSize <= PERFORMANCE_BUFFER_SIZE - 2048)
+ {
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: %lu bytes from sysinfo %ld\n",
+ ulSize, dwType);
+ (*add) (buffer, ulSize, requester);
+ no_results++;
+ }
+ }
+
+ /* Now we would do the same for the process information. This
+ call would rather ugly in that it requires an exact length
+ match for the data returned, failing with a
+ STATUS_INFO_LENGTH_MISMATCH error code (0xC0000004) if the
+ length isn't an exact match. It requires a compiler to handle
+ complex nested structs, alignment issues, and so on, and
+ without the headers in which the entries are declared it's
+ almost impossible to do. Thus we don't. */
+
+
+ /* Finally, do the same for the system power status information. There
+ are only a limited number of useful information types available so we
+ restrict ourselves to the useful types. In addition since this
+ function doesn't return length information, we have to hardcode in
+ length data. */
+ if (pNtPowerInformation)
+ {
+ static const struct { int type; int size; } powerInfo[] = {
+ { 0, 128 }, /* SystemPowerPolicyAc */
+ { 1, 128 }, /* SystemPowerPolicyDc */
+ { 4, 64 }, /* SystemPowerCapabilities */
+ { 5, 48 }, /* SystemBatteryState */
+ { 11, 48 }, /* ProcessorInformation */
+ { 12, 24 }, /* SystemPowerInformation */
+ { -1, -1 }
+ };
+ int i;
+
+ /* The 100 is a failsafe limit. */
+ for (i = 0; powerInfo[i].type != -1 && i < 100; i++ )
+ {
+ /* Query the info for this ID */
+ dwResult = pNtPowerInformation (powerInfo[i].type, NULL, 0, buffer,
+ PERFORMANCE_BUFFER_SIZE - 2048);
+ if (dwResult != ERROR_SUCCESS)
+ continue;
+ if (debug_me)
+ log_debug ("rndw32#slow_gatherer: %u bytes from powerinfo %d\n",
+ powerInfo[i].size, i);
+ (*add) (buffer, powerInfo[i].size, requester);
+ no_results++;
+ }
+ gcry_assert (i < 100);
+ }
+ gcry_free (buffer);
+
+ /* We couldn't get enough results from the kernel, fall back to the
+ somewhat troublesome registry poll. */
+ if (no_results < 15)
+ registry_poll (add, requester);
+}
+
+
+int
+_gcry_rndw32_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ static int is_initialized;
+
+ if (!level)
+ return 0;
+
+ /* We don't differentiate between level 1 and 2 here because there
+ is no internal entropy pool as a scary resource. It may all work
+ slower, but because our entropy source will never block but
+ deliver some not easy to measure entropy, we assume level 2. */
+
+ if (!is_initialized)
+ {
+ OSVERSIONINFO osvi = { sizeof( osvi ) };
+
+ GetVersionEx( &osvi );
+ if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT)
+ log_fatal ("can only run on a Windows NT platform\n" );
+ system_is_w2000 = (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0);
+ init_system_rng ();
+ is_initialized = 1;
+ }
+
+ if (debug_me)
+ log_debug ("rndw32#gather_random: ori=%d len=%u lvl=%d\n",
+ origin, (unsigned int)length, level );
+
+ slow_gatherer (add, origin);
+
+ return 0;
+}
+
+
+
+void
+_gcry_rndw32_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin)
+{
+ static int addedFixedItems = 0;
+
+ if ( debug_me )
+ log_debug ("rndw32#gather_random_fast: ori=%d\n", origin );
+
+ /* Get various basic pieces of system information: Handle of active
+ window, handle of window with mouse capture, handle of clipboard
+ owner handle of start of clpboard viewer list, pseudohandle of
+ current process, current process ID, pseudohandle of current
+ thread, current thread ID, handle of desktop window, handle of
+ window with keyboard focus, whether system queue has any events,
+ cursor position for last message, 1 ms time for last message,
+ handle of window with clipboard open, handle of process heap,
+ handle of procs window station, types of events in input queue,
+ and milliseconds since Windows was started. */
+
+ {
+ byte buffer[20*sizeof(ulong)], *bufptr;
+
+ bufptr = buffer;
+#define ADD(f) do { ulong along = (ulong)(f); \
+ memcpy (bufptr, &along, sizeof (along) ); \
+ bufptr += sizeof (along); \
+ } while (0)
+
+ ADD ( GetActiveWindow ());
+ ADD ( GetCapture ());
+ ADD ( GetClipboardOwner ());
+ ADD ( GetClipboardViewer ());
+ ADD ( GetCurrentProcess ());
+ ADD ( GetCurrentProcessId ());
+ ADD ( GetCurrentThread ());
+ ADD ( GetCurrentThreadId ());
+ ADD ( GetDesktopWindow ());
+ ADD ( GetFocus ());
+ ADD ( GetInputState ());
+ ADD ( GetMessagePos ());
+ ADD ( GetMessageTime ());
+ ADD ( GetOpenClipboardWindow ());
+ ADD ( GetProcessHeap ());
+ ADD ( GetProcessWindowStation ());
+ ADD ( GetQueueStatus (QS_ALLEVENTS));
+ ADD ( GetTickCount ());
+
+ gcry_assert ( bufptr-buffer < sizeof (buffer) );
+ (*add) ( buffer, bufptr-buffer, origin );
+#undef ADD
+ }
+
+ /* Get multiword system information: Current caret position, current
+ mouse cursor position. */
+ {
+ POINT point;
+
+ GetCaretPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ GetCursorPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ }
+
+ /* Get percent of memory in use, bytes of physical memory, bytes of
+ free physical memory, bytes in paging file, free bytes in paging
+ file, user bytes of address space, and free user bytes. */
+ {
+ MEMORYSTATUS memoryStatus;
+
+ memoryStatus.dwLength = sizeof (MEMORYSTATUS);
+ GlobalMemoryStatus (&memoryStatus);
+ (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
+ }
+
+ /* Get thread and process creation time, exit time, time in kernel
+ mode, and time in user mode in 100ns intervals. */
+ {
+ HANDLE handle;
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+ DWORD minimumWorkingSetSize, maximumWorkingSetSize;
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ handle = GetCurrentProcess ();
+ GetProcessTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ /* Get the minimum and maximum working set size for the current
+ process. */
+ GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
+ &maximumWorkingSetSize);
+ (*add) ( &minimumWorkingSetSize,
+ sizeof (minimumWorkingSetSize), origin );
+ (*add) ( &maximumWorkingSetSize,
+ sizeof (maximumWorkingSetSize), origin );
+ }
+
+
+ /* The following are fixed for the lifetime of the process so we only
+ * add them once */
+ if (!addedFixedItems)
+ {
+ STARTUPINFO startupInfo;
+
+ /* Get name of desktop, console window title, new window
+ position and size, window flags, and handles for stdin,
+ stdout, and stderr. */
+ startupInfo.cb = sizeof (STARTUPINFO);
+ GetStartupInfo (&startupInfo);
+ (*add) ( &startupInfo, sizeof (STARTUPINFO), origin );
+ addedFixedItems = 1;
+ }
+
+ /* The performance of QPC varies depending on the architecture it's
+ running on and on the OS, the MS documentation is vague about the
+ details because it varies so much. Under Win9x/ME it reads the
+ 1.193180 MHz PIC timer. Under NT/Win2K/XP it may or may not read the
+ 64-bit TSC depending on the HAL and assorted other circumstances,
+ generally on machines with a uniprocessor HAL
+ KeQueryPerformanceCounter() uses a 3.579545MHz timer and on machines
+ with a multiprocessor or APIC HAL it uses the TSC (the exact time
+ source is controlled by the HalpUse8254 flag in the kernel). That
+ choice of time sources is somewhat peculiar because on a
+ multiprocessor machine it's theoretically possible to get completely
+ different TSC readings depending on which CPU you're currently
+ running on, while for uniprocessor machines it's not a problem.
+ However, the kernel appears to synchronise the TSCs across CPUs at
+ boot time (it resets the TSC as part of its system init), so this
+ shouldn't really be a problem. Under WinCE it's completely platform-
+ dependant, if there's no hardware performance counter available, it
+ uses the 1ms system timer.
+
+ Another feature of the TSC (although it doesn't really affect us here)
+ is that mobile CPUs will turn off the TSC when they idle, Pentiums
+ will change the rate of the counter when they clock-throttle (to
+ match the current CPU speed), and hyperthreading Pentiums will turn
+ it off when both threads are idle (this more or less makes sense,
+ since the CPU will be in the halted state and not executing any
+ instructions to count).
+
+ To make things unambiguous, we detect a CPU new enough to call RDTSC
+ directly by checking for CPUID capabilities, and fall back to QPC if
+ this isn't present. */
+#ifdef __GNUC__
+/* FIXME: We would need to implement the CPU feature tests first. */
+/* if (cpu_has_feature_rdtsc) */
+/* { */
+/* uint32_t lo, hi; */
+ /* We cannot use "=A", since this would use %rax on x86_64. */
+/* __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); */
+ /* Ignore high 32 bits, hwich are >1s res. */
+/* (*add) (&lo, 4, origin ); */
+/* } */
+/* else */
+#endif /*!__GNUC__*/
+ {
+ LARGE_INTEGER performanceCount;
+
+ if (QueryPerformanceCounter (&performanceCount))
+ {
+ if ( debug_me )
+ log_debug ("rndw32#gather_random_fast: perf data\n");
+ (*add) (&performanceCount, sizeof (performanceCount), origin);
+ }
+ else
+ {
+ /* Millisecond accuracy at best... */
+ DWORD aword = GetTickCount ();
+ (*add) (&aword, sizeof (aword), origin );
+ }
+ }
+
+
+}
--- /dev/null
+/* rndw32ce.c - W32CE entropy gatherer
+ * Copyright (C) 2010 Free Software Foundation, Inc.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <windows.h>
+#include <wincrypt.h>
+
+#include "types.h"
+#include "g10lib.h"
+#include "rand-internal.h"
+
+
+/* The Microsoft docs say that it is suggested to see the buffer with
+ some extra random. We do this, despite that it is a questionable
+ suggestion as the OS as better means of collecting entropy than an
+ application. */
+static size_t filler_used;
+static size_t filler_length;
+static unsigned char *filler_buffer;
+
+static void
+filler (const void *data, size_t datalen, enum random_origins dummy)
+{
+ (void)dummy;
+ if (filler_used + datalen > filler_length)
+ datalen = filler_length - filler_used;
+ memcpy (filler_buffer + filler_used, data, datalen);
+ filler_used += datalen;
+}
+
+
+static void
+fillup_buffer (unsigned char *buffer, size_t length)
+{
+ filler_used = 0;
+ filler_length = length;
+ filler_buffer = buffer;
+
+ while (filler_used < length)
+ _gcry_rndw32ce_gather_random_fast (filler, 0);
+}
+
+
+int
+_gcry_rndw32ce_gather_random (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin,
+ size_t length, int level )
+{
+ HCRYPTPROV prov;
+ unsigned char buffer [256];
+ DWORD buflen;
+
+ if (!level)
+ return 0;
+
+ /* Note that LENGTH is not really important because the caller
+ checks the returned lengths and calls this function until it
+ feels that enough entropy has been gathered. */
+
+ buflen = sizeof buffer;
+ if (length+8 < buflen)
+ buflen = length+8; /* Return a bit more than requested. */
+
+ if (!CryptAcquireContext (&prov, NULL, NULL, PROV_RSA_FULL,
+ (CRYPT_VERIFYCONTEXT|CRYPT_SILENT)) )
+ log_debug ("CryptAcquireContext failed: rc=%d\n", (int)GetLastError ());
+ else
+ {
+ fillup_buffer (buffer, buflen);
+ if (!CryptGenRandom (prov, buflen, buffer))
+ log_debug ("CryptGenRandom(%d) failed: rc=%d\n",
+ (int)buflen, (int)GetLastError ());
+ else
+ (*add) (buffer, buflen, origin);
+ CryptReleaseContext (prov, 0);
+ wipememory (buffer, sizeof buffer);
+ }
+
+ return 0;
+}
+
+
+
+void
+_gcry_rndw32ce_gather_random_fast (void (*add)(const void*, size_t,
+ enum random_origins),
+ enum random_origins origin)
+{
+
+ /* Add word sized values. */
+ {
+# define ADD(t,f) do { \
+ t along = (f); \
+ memcpy (bufptr, &along, sizeof (along)); \
+ bufptr += sizeof (along); \
+ } while (0)
+ unsigned char buffer[20*sizeof(ulong)], *bufptr;
+
+ bufptr = buffer;
+ ADD (HWND, GetActiveWindow ());
+ ADD (HWND, GetCapture ());
+ ADD (HWND, GetClipboardOwner ());
+ ADD (HANDLE, GetCurrentProcess ());
+ ADD (DWORD, GetCurrentProcessId ());
+ ADD (HANDLE, GetCurrentThread ());
+ ADD (DWORD, GetCurrentThreadId ());
+ ADD (HWND, GetDesktopWindow ());
+ ADD (HWND, GetFocus ());
+ ADD (DWORD, GetMessagePos ());
+ ADD (HWND, GetOpenClipboardWindow ());
+ ADD (HWND, GetProcessHeap ());
+ ADD (DWORD, GetQueueStatus (QS_ALLEVENTS));
+ ADD (DWORD, GetTickCount ());
+
+ gcry_assert ( bufptr-buffer < sizeof (buffer) );
+ (*add) ( buffer, bufptr-buffer, origin );
+# undef ADD
+ }
+
+ /* Get multiword system information: Current caret position, current
+ mouse cursor position. */
+ {
+ POINT point;
+
+ GetCaretPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ GetCursorPos (&point);
+ (*add) ( &point, sizeof (point), origin );
+ }
+
+ /* Get percent of memory in use, bytes of physical memory, bytes of
+ free physical memory, bytes in paging file, free bytes in paging
+ file, user bytes of address space, and free user bytes. */
+ {
+ MEMORYSTATUS memoryStatus;
+
+ memoryStatus.dwLength = sizeof (MEMORYSTATUS);
+ GlobalMemoryStatus (&memoryStatus);
+ (*add) ( &memoryStatus, sizeof (memoryStatus), origin );
+ }
+
+
+ /* Get thread and process creation time, exit time, time in kernel
+ mode, and time in user mode in 100ns intervals. */
+ {
+ HANDLE handle;
+ FILETIME creationTime, exitTime, kernelTime, userTime;
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ handle = GetCurrentThread ();
+ GetThreadTimes (handle, &creationTime, &exitTime,
+ &kernelTime, &userTime);
+ (*add) ( &creationTime, sizeof (creationTime), origin );
+ (*add) ( &exitTime, sizeof (exitTime), origin );
+ (*add) ( &kernelTime, sizeof (kernelTime), origin );
+ (*add) ( &userTime, sizeof (userTime), origin );
+
+ }
+
+
+ /* In case the OEM provides a high precision timer get this. If
+ none is available the default implementation returns the
+ GetTickCount. */
+ {
+ LARGE_INTEGER performanceCount;
+
+ if (QueryPerformanceCounter (&performanceCount))
+ (*add) (&performanceCount, sizeof (performanceCount), origin);
+ }
+
+}
--- /dev/null
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (pk_operation): New.
+ (pk_encoding_ctx): Add new fields: op, nbits, flags, verify_cmp,
+ and verify_arg.
+
+2011-05-19 Daiki Ueno <ueno@unixuser.org>
+
+ * Makefile.am (gcryptrnd_LDADD): Supply $(GPG_ERROR_LIBS) for
+ gpg_strerror.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h: Remove PUBKEY_FLAG_UNPAD.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * cipher.h (PUBKEY_FLAG_UNPAD): New.
+ (enum pk_encoding): New.
+ (struct pk_encoding_ctx): New.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * stdmem.c (_gcry_private_malloc_secure, _gcry_private_malloc):
+ Set ERRNO on failure.
+ * secmem.c (mb_get_new): Set ERRNO on failure.
+ (_gcry_secmem_malloc_internal): Ditto.
+
+2011-04-01 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_realloc): Divert to gcry_malloc or gcry_free.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_kdf_algos): New.
+ (gcry_kdf_derive): New.
+ * visibility.c (gcry_kdf_derive): New.
+ * visibility.h, libgcrypt.vers, libgcrypt.def: Add gcry_kdf_derive.
+
+2011-02-23 Werner Koch <wk@g10code.com>
+
+ * libgcrypt-config.in: Add option --host.
+ * libgcrypt.m4: Use AC_PROG_TOOL to find the config script. Print
+ a warning is the config scripts does not match the configure host.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_check_version): Do not take the patchlevel in
+ account; it is not well defined.
+
+2011-02-17 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (gcry_cipher_register, gcry_cipher_unregister)
+ (gcry_pk_register, gcry_pk_unregister, gcry_md_register)
+ (gcry_md_unregister): Mark as deprecated by the API; in a future
+ version the module register feature will be removed.
+
+ * gcrypt.h.in: Attribute all _ac_ functions and types as
+ deprecated by the API.
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix AES-NI detection. Use AND
+ instead of SUB for bit testing.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_DISABLE_HWF): New.
+ * global.c (_gcry_vcontrol): Support new control code.
+ (print_config): Factor list of hwfeatures out to ...
+ (hwflist): new.
+ (disabled_hw_features): New.
+ (global_init): Pass new variable to _gcry_detect_hw_features.
+ * hwfeatures.c (_gcry_detect_hw_features): Add arg
+ DISABLED_FEATURES and disable detected features.
+
+2011-02-11 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): Rename to HWF_INTEL_AESNI.
+ * hwfeatures.c (detect_ia32_gnuc): Fix setting of this flag.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * libgcrypt.vers (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * libgcrypt.def (gcry_pk_get_curve, gcry_pk_get_param): Add.
+ * visibility.c (gcry_pk_get_curve, gcry_pk_get_param): New.
+ * cipher-proto.h (pk_extra_spec): Add fields GET_CURVE and
+ GET_CURVE_PARM.
+
+2011-01-31 Werner Koch <wk@g10code.com>
+
+ * sexp.c (vsexp_sscan): Allow opaque MPIs in "%m".
+
+2010-08-27 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (HWF_INTEL_AES): New.
+ * global.c (print_config): Print new flag.
+ * hwfeatures.c (detect_ia32_gnuc): Detect this flag.
+
+2010-08-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute.
+
+2010-07-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to
+ help building with MSVC.
+
+2010-06-24 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in [W32]: Include time.h and not sys/time.h.
+
+2010-04-19 Marcus Brinkmann <marcus@g10code.de>
+
+ * misc.c (write2stderr): Dummy variable to silence gcc warning.
+
+2010-04-16 Marcus Brinkmann <marcus@g10code.de>
+
+ * sexp.c: (sexp_sscan): Make it variable length, and rename the
+ old version to ...
+ (vsexp_sscan): ... this new function. Also swap last two arguments.
+ (gcry_sexp_create): Remove dummy va_list.
+ (gcry_sexp_build): Use vsexp_sscan instead of sexp_sscan.
+ (_gcry_sexp_vbuild): Likewise.
+ (gcry_sexp_build_array): Remove dummy va_list.
+ (gcry_sexp_sscan): Likewise.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Add autoconf template to set generated file to
+ read-only in an Emacs buffer.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (arch_gpg_error_cflags, arch_gpg_error_libs): New.
+ (dumpsexp_CFLAGS): New.
+ (dumpsexp_LDADD): Add arch_gpg_error_libs.
+ (hmac256_CFLAGS, hmac256_LDADD): Add the arch variables.
+ (libgcrypt_la_DEPENDENCIES): Add libcompat.
+ * secmem.c (lock_pool): Mark unused args.
+ * global.c (do_malloc, gcry_realloc, gcry_free, gcry_calloc)
+ (gcry_calloc_secure, gcry_xcalloc, gcry_xcalloc_secure): Use
+ gpg_err_set_errno.
+ (_gcry_vcontrol): Call _gcry_compat_identification.
+ * hmac256.c [__MINGW32CE__]: Include gpg-error.h.
+ (_gcry_hmac256_file): Use gpg_err_set_errno.
+ (gpg_err_set_errno) [!GPG_ERR_INLINE]: Add macro.
+ * g10lib.h: Include libcompat.h.
+
+2010-01-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_PK_ECDH): New.
+
+2009-12-08 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_CIPHER_MODE_AESWRAP): New.
+
+2009-12-08 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (LTRCCOMPILE): Refactor with ...
+ (RCCOMPILE): ... this new macro. Add $(libgcrypt_la_CPPFLAGS).
+ (SUFFIXES): Add .lo.
+ (.rc.o): Change to ...
+ (.rc.lo): ... this implicit rule.
+ (gcrypt_res_ldflag): Removed.
+ (gcrypt_res): Use libtool object file name here.
+ (libgcrypt_la_LDFLAGS): Remove gcrypt_res_ldflag usage.
+ (libgcrypt_la_LIBADD): Add gcrypt_res.
+
+2009-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Repalce "=r" by "+r" so that
+ HAS-CPUDID is always initialized. Thanks to Ben Hutchings for
+ pointing out this problem.
+
+2009-08-05 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/msg.h.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if
+ /proc/.../fips_enabled has insufficient permissions.
+
+ * dumpsexp.c (main): Fix handling multiple files.
+ (parse_and_print): Implement hex and octal escaping.
+
+ * sexp.c (unquote_string): Remove superfluous clearing of ESC.
+ * dumpsexp.c (parse_and_print): Add missing break.
+ (main): Fix return value.
+ Reported by Fabian Keil.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * ath.h [HAVE_SYS_SELECT_H]: Include <sys/select.h> for fd_set.
+ [!HAVE_SYS_SELECT_H]: Include <sys/time.h>. Move inclusion of
+ config.h to the top. The actual configure check was already
+ there.
+
+ * sexp.c: Remove memory.h.
+ * mpi.h: Remove memory.h. Add string.h.
+
+2009-02-02 Werner Koch <wk@g10code.com>
+
+ * ath.h: Include sys/time.h. Fixes bug#993.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Remove superfluous const
+ from static string. Reported by Albert Chin.
+ * hmac256.c (selftest): Ditto and change to unsigned char.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize): Fix for big endian hosts.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_free): Save and restore ERRNO if set.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * sexp.c (get_internal_buffer): New.
+ (sexp_sscan): Add format character S.
+ * cipher-proto.h (pk_ext_generate_t): Add field EXTRAINFO changed
+ all implementors.
+
+ * cipher-proto.h (pk_ext_generate_t): Simplify.
+ (pk_get_param): New.
+ (pk_extra_spec_t): Add field GET_PARAM.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): Remove.
+ (_gcry_pubkey_extraspec_elg): New.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * cipher.h (CIPHER_INFO_NO_WEAK_KEY): New.
+
+ * cipher-proto.h (cipher_set_extra_info_t): New.
+ (cipher_extra_spec): Add field SET_EXTRA_INFO.
+
+2008-10-30 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (GCC_ATTR_FORMAT_ARG): New.
+ (_gcry_gettext): Use it.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * global.c (inactive_fips_mode): Move to fips.c.
+ (gcry_set_allocation_handler): Factor code out to ...
+ * fips.c (_gcry_inactivate_fips_mode): New.
+ (_gcry_is_fips_mode_inactive): New.
+
+2008-09-29 Werner Koch <wk@g10code.com>
+
+ * gcrypt-module.h (GCRY_MODULE_ID_USER, GCRY_MODULE_ID_USER_LAST):
+ New.
+ * module.c (MODULE_ID_USER, MODULE_ID_USER_LAST): Define using new
+ macros.
+
+2008-09-20 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (finalize) [WORDS_BIGENDIAN]: Fix sigbus problem.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * cipher-proto.h (pk_ext_generate_t): Add args QBITS, NAME, DOMAIN.
+
+ * fips.c (fips_new_state): Allow Error => Error transition.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_fips_mode_active): New.
+
+ * secmem.c (_gcry_secmem_init): Factor most code out to ..
+ (secmem_init): .. new.
+ (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE.
+ (STANDARD_POOL_SIZE): New.
+ (_gcry_secmem_malloc_internal): Don't abort if the pool is not
+ initialized but try to out intialize it first and only then print
+ an error message and return NULL. If the pool is not locked while
+ in FIPS mode, return NULL.
+
+ * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to
+ "/etc/gcrypt/fips_enabled".
+ (enforced_fips_mode): New.
+ (_gcry_initialize_fips_mode): Set that flag.
+ (_gcry_enforced_fips_mode): New.
+ * global.c (inactive_fips_mode): New.
+ (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P.
+ (gcry_set_allocation_handler): Take care of the enforced fips mdoe
+ flag.
+ (get_no_secure_memory): New.
+ (do_malloc, gcry_is_secure): Use it.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Use y/n for fips mode.
+
+ * fips.c (fips_new_state): Allow transition to Error and
+ Fatal-error from Init.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * fips.c [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm)
+ (_gcry_fips_signal_error, fips_new_state)
+ (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog.
+ (check_binary_integrity) [HAVE_SYSLOG]: Log failure.
+ * global.h [HAVE_SYSLOG]: Include syslog.h.
+ (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning.
+
+ * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED
+ to run power-up tests. Add unpublished control commands 58-60.
+
+ * global.c (_gcry_global_is_operational): New.
+ * g10lib.h (fips_is_operational): Change to call this function.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED.
+ (run_cipher_selftests, run_digest_selftests, run_hmac_selftests)
+ (run_pubkey_selftests): Ditto.
+ * cipher-proto.h (selftest_func_t): Add arg EXTENDED
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * fips.c: Include string.h.
+ (loxtoi_1, loxtoi_2, loxdigit_p): New.
+ (check_binary_integrity): Change the format of the expected file.
+
+ * fips.c (_gcry_fips_run_selftests): Run random tests before the
+ pubkey tests.
+
+2008-09-05 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCYRCTL_SELFTEST): New.
+ * global.c (_gcry_vcontrol): Implement.
+ * fips.c (_gcry_fips_run_selftests): Do state transitions only if
+ in fips mode. Return an error code.
+
+2008-09-01 Werner Koch <wk@g10code.com>
+
+ * stdmem.c: Re-indented.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test
+ for FIPS mode.
+
+ * cipher-proto.h (pk_compute_keygrip_t): New.
+ (pk_extra_spec): Add field comp_keygrip.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (_gcry_detect_hw_features): Disable hardware
+ detection in FIPS mode.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_vcontrol): Allow running selftests from error
+ state.
+ (gcry_set_outofcore_handler): Only print a warning if used in FIPS
+ mode.
+ (gcry_xmalloc, gcry_xrealloc, gcry_xmalloc_secure, gcry_xstrdup):
+ Ignore an outofcore handler in FIPS mode.
+
+ * fips.c (_gcry_fips_test_error_or_operational): New.
+ (fips_new_state): Allow transition from error into selftest.
+ Disallow error to init.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * fips.c (fips_new_state): Print state transitions only at
+ verbosity level of 2.
+ (reporter): Likewise.
+
+ * cipher-proto.h (pk_ext_generate_t): New.
+ (pk_extra_spec): Add member ext_generate.
+ * cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+
+2008-08-22 Werner Koch <wk@g10code.com>
+
+ * hmac256.c (_gcry_hmac256_file): New.
+ (main): New option --binary.
+ * fips.c (check_binary_integrity): New.
+ (_gcry_fips_run_selftests): Run it.
+
+ * global.c (_gcry_vcontrol) <GCRYCTL_UPDATE_RANDOM_SEED_FILE>:
+ Check for fips operational state.
+ (_gcry_vcontrol) <GCRYCTL_FAST_POLL>: Ditt.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_log_printhex): New.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * g10lib.h (gcry_assert): New. use this at almost all places
+ where we used a plain assert.
+ * misc.c (_gcry_assert_failed): New.
+ (_gcry_bug): Also use func variant for ISO-C99.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * visibility.c, visibility.h (gcry_mpi_lshift): New.
+ * libgcrypt.vers, libgcrypt.def, gcrypt.h.in: Ditto.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_cipher_setkey): Replace macro by function.
+ (gcry_cipher_setiv): Ditto.
+ (gcry_cipher_setctr): Ditto.
+ * visibility.c (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * visibility.h (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.vers (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+ * libgcrypt.def (gcry_cipher_setkey, gcry_cipher_setiv)
+ (gcry_cipher_setctr): New.
+
+ * hmac256.h, hmac256.c: New.
+ * Makefile.am (hmac256_SOURCES): New.
+ * Makefile.am (bin_PROGRAMS): Add hmac256.
+
+ * gcrypt.h.in (struct gcry_thread_cbs): Change type of OPTION to
+ unsigned int. Although this is a type change it does not make a
+ difference.
+ * ath.c (ath_install): Take the version of the option field in
+ account.
+
+ * visibility.c (gcry_pk_encrypt, gcry_pk_decrypt, gcry_pk_sign)
+ (gcry_pk_verify, gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits, gcry_pk_get_keygrip)
+ (gcry_md_open, gcry_md_copy, gcry_md_enable)
+ (gcry_md_write, md_final, gcry_md_ctl, gcry_md_setkey)
+ (gcry_md_hash_buffer, gcry_md_get_algo, gcry_md_info)
+ (gcry_md_is_enabled)
+ (gcry_cipher_open, gcry_cipher_encrypt)
+ (gcry_cipher_decrypt, gcry_cipher_ctl)
+ (gcry_cipher_algo_info): Check whether the library is operational.
+
+ * cipher-proto.h: New.
+ * cipher.h: Include cipher-proto.h.
+ * visibility.h: Remove duplicate macro definitions. Remove
+ gcry_cipher_register, gcry_md_register, gcry_pk_register macros.
+ * visibility.c: Include cipher-proto.h.
+ (gcry_cipher_register): Pass dummy extra args to the internal
+ register function.
+ (gcry_md_register, gcry_pk_register): Ditto.
+ * g10lib.h (struct gcry_module): Add field EXTRASPEC.
+ * module.c (_gcry_module_add): Add arg EXTRASPEC. Changed all
+ callers to pass NULL.
+
+ * fips.c: New.
+ * gcrypt.h.in (GCRYCTL_FIPS_MODE_P): New.
+ * global.c (global_init): Call fips initialization.
+ (_gcry_vcontrol): Add GCRYCTL_FIPS_MODE_P code.
+ (print_config): Add config item fips-mode.
+ (gcry_set_allocation_handler): Do not allow the use of custom
+ allocation handlers.
+ (gcry_set_outofcore_handler): Ditto.
+ (_gcry_get_debug_flag): Do not return any debug flags in fips mode.
+ * misc.c (_gcry_logv): Signal fips error on BUG or FATAL.
+ (_gcry_fatal_error): Ditto.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Include librandom.la.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * missing-string.c (vasprintf): Remove. It is not used. Reported
+ by Simon Josefsson.
+
+2008-03-11 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_em_t, gcry_ac_scheme_t): Remove trailing
+ comma for full C-89 compatibility.
+
+2008-01-21 Marcus Brinkmann <marcus@g10code.de>
+
+ * hwfeatures.c (detect_ia32_gnuc): Fix inline asm.
+
+2007-12-11 Werner Koch <wk@g10code.com>
+
+ * visibility.c (gcry_md_hash_buffer): Don't use return vor a void
+ function. Hey, why does gcc not complain about this?
+ (gcry_ac_io_init_va): Ditto.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Depend on ENABLE_PADLOCK_SUPPORT.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * misc.c (_gcry_logv): Use abort for error levels fatal and bug as
+ this is more approriate for a library. Terminate the secmem
+ before doing so.
+ (_gcry_fatal_error): Terminate secmem before abort.
+ * secmem.c (_gcry_secmem_malloc_internal): Use log_bug instead of
+ exit.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * hwfeatures.c (detect_ia32_gnuc): Detect Padlock engine.
+
+2007-11-13 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (_GCRY_GCC_ATTR_MALLOC): Fixed gcc version check.
+ Reported by Gabriele Monti.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control): Factor most code out to ..
+ (_gcry_vcontrol): .. new.
+ * sexp.c (_gcry_sexp_vbuild): New.
+ * mpi.h (_gcry_mpi_set, _gcry_mpi_set_ui, _gcry_mpi_invm): Remove
+ prototypes as they are already in gcrypt.h.
+
+2007-10-30 Werner Koch <wk@g10code.com>
+
+ * sexp.c (gcry_sexp_nth_string): Replace by _gcry_sexp_nth_string.
+
+ * visibility.h, visibility.c: New.
+ * g10lib.h: Include visibility.h instead of gcrypt.h.
+ * globals.c (_gcry_malloc): Rename to ..
+ (do_malloc): .. this.
+
+ * hwfeatures.c: New.
+ * global.c (global_init): Detect features.
+ (print_config): Print them.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * dumpsexp.c: New.
+ * Makefile.am (bin_PROGRAMS): Install it.
+
+ * getrandom.c (print_version): Use new standard license line.
+ * gcryptrnd.c (print_version): Ditto.
+
+2007-06-06 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network
+ related code out so that the prototypes can be adjusted for W32.
+ (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New.
+
+2007-05-09 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.m4: Print found version on success.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in (gcry_ac_io_t): Add name for anonymous union, and mark
+ all members as internal (actually: deprecated).
+
+2007-05-04 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (.rc.lo): New to replace gmake specific suffix rule.
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_sexp_nth_string): New.
+ * Makefile.am (EXTRA_DIST): Add libgcrypt.def.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * global.c (print_config): Print ciphers, digests and pubkeys.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.h, gcrypt.h.in: Add Camellia.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRYCTL_PRINT_CONFIG): New.
+ (GCRYCTL_SET_RNDEGD_SOCKET): New.
+ * global.c (gcry_control): Add GCRYCTL_PRINT_CONFIG and
+ GCRYCTL_SET_RNDEGD_SOCKET.
+ (print_config): New.
+ * misc.c (_gcry_log_info_with_dummy_fp): New.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_sexp_nth_string): New.
+
+ * sexp.c (gcry_sexp_nth_data): Factored code out to ...
+ (sexp_nth_data): ... new.
+ (gcry_sexp_nth_string): New.
+ (gcry_sexp_nth_mpi): Reimplemented in terms of sexp_ntd_data.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * secmem.c (init_pool): Use sysconf() if available to determine
+ page size.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * mpi.h (mpi_mod): New.
+ (mpi_new, mpi_snew): New.
+
+ * gcrypt.h.in: Add GCRY_PK_ECDSA.
+
+2007-03-16 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Fixed typo
+ introduced by me on 2006-10-23.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (gcry_ac_id_to_name, gcry_ac_name_to_id): Mark as
+ deprecated.
+
+ * libgcrypt.def (gcry_fast_random_poll): Removed - it is a macro.
+ (gcry_cipher_register, gcry_cipher_unregister): New.
+ (gcry_md_register, gcry_md_unregister): New.
+ (gcry_pk_register, gcry_pk_unregister): New.
+ (gcry_ac_data_from_sexp, gcry_ac_data_to_sexp): New.
+ (gcry_ac_io_init, gcry_ac_io_init_va): New.
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme): New.
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): New.
+
+ * missing-string.c: Include stdio.h for the vsprintf prototype.
+
+ * ath.h (struct ath_ops) [_WIN32]: Use int instead of socklen_t.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * libgcrypt.def (gcry_create_nonce, gcry_fast_random_poll)
+ (gcry_md_debug): New.
+
+ * libgcrypt-config.in: Remove duplicates from --cflags and --libs.
+ Print a error for option --thread.
+
+ * gcrypt.h.in (gcry_sexp_sprint): Change BUFFER from char* to void*.
+ (gcry_md_ctl): Change BUFFER from unsigned char* to void*.
+ (gcry_md_debug): New.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Change buffer args to
+ void*.
+ (gcry_randomize): Change BUFFER to void.
+ (gcry_create_nonce): Ditto.
+
+ * libgcrypt.vers (gcry_md_debug): New.
+
+ * sexp.c (gcry_sexp_sprint): Ditto.
+ (normalize): Make P unsigned.
+ (gcry_sexp_nth_data): Cast return value to char*.
+ (sexp_sscan): Fix sign/unsigned conflicts.
+ (whitespacep): Change P to char*.
+ (unquote_string): Change STRING to char*.
+ (convert_to_hex): Change DEST to char*.
+ (convert_to_string): Change DEST and P to char*.
+ (convert_to_token): Chnage DEST to char*.
+ (gcry_sexp_canon_len): Change DISPHINT to unsigned char*.
+
+ * gcrypt-module.h (gcry_pk_spec): Made ALIASES a const.
+ (gcry_md_write_t): Changed BUF to a const void*.
+
+2007-02-12 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in: Include stdlib.h for the sake fo the trheading
+ macros. Suggested by Andreas Metzler.
+
+ * secmem.c (ptr_into_pool_p): New.
+ (_gcry_private_is_secure): Implement in terms of new function.
+ (BLOCK_VALID): Removed. Replaced all users by new function.
+
+2007-01-31 Werner Koch <wk@g10code.com>
+
+ * secmem.c (_gcry_private_is_secure): Fixed severe implementation
+ flaw. Might be the reason for some of the more obscure bugs.
+ (MB_WIPE_OUT): Use wipememory2.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h.in (GCRY_THREAD_OPTION_PTHREAD_IMPL): Add some cast for
+ use by C-doubleplus. In general I don't like this but due to
+ public demand I give up ;-)
+
+2006-10-19 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_control) <GCRYCTL_INIT_SECMEM>: Return an error
+ if the memory could not be locked.
+ * secmem.c (not_locked): New.
+ (_gcry_secmem_get_flags): Return that flag.
+ * secmem.h (GCRY_SECMEM_FLAG_NOT_LOCKED): New.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * module.c (_gcry_module_id_new): Don't assign modules in the range
+ the range of 1024..4096.
+ * gcrypt.h (GCRY_MD_USER, GCRY_MD_USER_LAST): New
+ (GCRY_PK_USER, GCRY_PK_USER_LAST): New.
+ (GCRY_CIPHER_USER, GCRY_CIPHER_USER_LAST): New.
+
+2006-10-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace socklen_t with gcry_socklen_t.
+
+2006-10-11 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h.in: Replace version by @VERSION@.
+
+2006-10-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * gcrypt.h: Add fallback type for socklen_t. Move to ...
+ * gcrypt.h.in: ... this file.
+ * Makefile.am (EXTRA_DIST): Add gcrypt.h.in.
+
+2006-09-04 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed some trailing comma in enums.
+
+2006-08-29 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xrealloc): Pass secure flag to outofcore handler.
+
+ * gcrypt.h (GCRY_CIPHER_SEED): New.
+
+2006-08-21 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRYCTL_FAKED_RANDOM_P): New.
+
+2006-07-29 Marcus Brinkmann <marcus@g10code.de>
+
+ * secmem.c (init_pool): Close FD after establishing the mapping.
+
+2006-07-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c (ath_mutex_destroy): Microoptimize destruction of unused
+ statitically initialized mutexes. Suggested by Victor Stinner
+ <victor.stinner@inl.fr>.
+
+ * gcrypt.h (GCRY_THREAD_OPTION_PTHREAD_IMPL,
+ (GCRY_THREAD_OPTION_PTH_IMPL): Add missing initializers to
+ suppress gcc warning.
+ Submitted by Victor Stinner <victor.stinner@inl.fr>.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * ath.c: Avoid warning about double defined type byte and other
+ hacks to let it build for W32 (backported from LIBGCRYPT-1-2-BRANCH).
+ * ath.h, gcrypt.h, tests/benchmark.c, src/types.h: Likewise.
+
+ * gcrypt.h: Revert last change, and instead:
+ [_WIN32 || __WIN32__]: Do not include <sys/socket.h>, but
+ <winsock2.h> and <ws2tcpip.h>.
+ Suggested by Simon Josefsson <jas@extundo.com>.
+
+ * Makefile.am (install-data-local, uninstall-local, %.lo,
+ (install-def-file, uninstall-def-file): New targets.
+ (LTRCCOMPILE, gcrypt_res, gcrypt_res_ldflag, no_undefined,
+ (export_symbols, gcrypt_deps): New variables.
+ * versioninfo.rc.in: New file.
+ * libgcrypt.def: New file from ../w32-dll/libgcrypt.def.
+
+ * gcrypt.h [!HAVE_SYS_SOCKET_H]: Do not include sys/socket.h, but
+ the appropriate windows socket header.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * global.c (gcry_xcalloc, gcry_xcalloc_secure): Made safe against
+ integer overflow.
+
+ * sexp.c (make_space): Return an error on out of core.
+ (sexp_sscan): Remove all xmalloc style calls and return proper
+ error codes on allocation failures.
+ (gcry_sexp_find_token): Ditto.
+ (gcry_sexp_nth):
+
+ * sexp.c (gcry_sexp_find_token): Re-indented and removed a cruft
+ "while(level);" which fortunately had no effect.
+
+2006-04-28 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_MD_SHA224): Change value from 306 to 11 to match
+ the use in OpenPGP. There has been no release yet, so we can
+ safely do it.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New commands:
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET, GCRYCTL_USE_RANDOM_DAEMON.
+ * global.c (gcry_control): Handle new commands, calling
+ _gcry_set_random_daemon_socket() and _gcry_use_random_daemon().
+
+2006-04-18 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h (GCRY_PK_USAGE_CERT, GCRY_PK_USAGE_AUTH)
+ (GCRY_PK_USAGE_UNKN): New.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_ac_eme_pkcs_v1_5): Removed members: key, handle;
+ added member: key_size.
+
+ * secmem.c (MB_FLAG_ACTIVE): Write braces around MB_FLAG_ACTIVE
+ definition.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * getrandom.c: New.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * gcryptrnd.c: New.
+
+2006-03-10 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Add GCRY_MD_SHA224.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Update comments for functions: gcry_cipher_algo_name,
+ gcry_pk_algo_name.
+
+2005-10-31 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Added documentation.
+
+2005-10-16 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Use gcry_error_t instead of
+ gcry_err_code_t; use goto instead of if constructs.
+
+ * stdmem.c: Inserted description of the layered memory management
+ in Libgcrypt.
+
+ * g10lib.h: Removed G10_I18N_H related check; it seems to be a
+ GnuPG relict (Libgcrypt does not define this symbol anywhere).
+ (FLAG_MODULE_DISABLED): Don't forget parantheses around shifted
+ value.
+
+ Removed GCC_ATTR_PURE macro definitions, since gcrypt.h does
+ already contain such a macro named _GCRY_GCC_ATTR_PURE, which we
+ can use here as well.
+
+ Likewise for GCC_ATTR_MALLOC and _GCRY_GCC_ATTR_MALLOC.
+
+ * stdmem.h: Use _GCRY_GCC_ATTR_MALLOC instead of GCC_ATTR_MALLOC.
+ * secmem.h: Likewise.
+
+2005-10-09 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_control): Call global_init() after passing thread
+ cbs to ath. global_init() MUST to be called AFTER passing the cbs
+ to ath and BEFORE calling library functions, which make use of
+ ath. This change combines cbs installing with ath initialization
+ and thus removes the need to call other library initialization
+ functions inbetween like e.g. gcry_check_version().
+
+2005-10-01 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c: Assign copyright to FSF.
+ * ath.h: Likewise.
+
+2005-06-25 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): Removed variables.
+ * libgcrypt.pc.in: Removed file - we do not want to support a
+ second, foreign configuration system.
+
+2005-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_xstrdup): Removed superfluous strcpy call.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (pkgconfigdir, pkgconfig_DATA): New; support for
+ pkgconfig provided by Albert Chin.
+ * libgcrypt.pc.in (Cflags): New file.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (_gcry_ac_init): Declare.
+ * global.c (global_init): Call _gcry_ac_init; don't forget to set
+ err.
+
+2005-04-14 Werner Koch <wk@g10code.com>
+
+ * sexp.c (whitespacep): New.
+ (sexp_sscan): Replaced isdigit and isspace by whitespacep and
+ digitp.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_algos): Added: GCRY_MD_WHIRLPOOL.
+ * cipher.h (_gcry_digest_spec_whirlpool): Declare.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_io_init, gry_ac_io_init_va.
+
+ * gcrypt.h (gcry_ac_data_read_cb_t, gcry_ac_data_write_cb_t,
+ gcry_ac_io_mode_t, gcry_ac_io_type_t, gcry_ac_io_t): New types.
+ (gcry_ac_io_init_va): Declare function.
+ (gcry_ac_data_encode, gcry_ac_data_decode,
+ gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme,
+ gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme): Use
+ gcry_ac_io_type_t objects instead of memory strings directly.
+
+2005-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * libgcrypt.vers: Added: gcry_ac_data_to_sexp() and
+ gcry_ac_data_from_sexp().
+
+2005-02-22 Werner Koch <wk@g10code.com>
+
+ * global.c (_gcry_malloc): Make sure ERRNO is set if we return
+ NULL. Remove unneeded initialization of M to allow the compiler
+ to catch errors.
+ (gcry_realloc): Make sure ERRNO is set if we return NULL>
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare new functions: gcry_ac_data_encrypt_scheme,
+ gcry_ac_data_decrypt_scheme, gcry_ac_data_sign_scheme,
+ gcry_ac_data_verify_scheme, gcry_ac_data_encode,
+ gcry_ac_data_decode, gcry_ac_data_to_sexp, gcry_ac_data_from_sexp.
+ New types: gcry_ac_emsa_pkcs_v1_5_t, gcry_ac_ssa_pkcs_v1_5_t,
+ gcry_md_algo_t.
+ New enumeration lists: gcry_ac_scheme_t, gcry_ac_em_t.
+ * libgcrypt.vers: Added new ac functions.
+ * g10lib.h: Declare function: _gcry_pk_get_elements.
+ * mpi.h (mpi_get_ui): New macro.
+ Declare function: _gcry_mpi_get_ui.
+
+2004-11-09 Werner Koch <wk@g10code.com>
+
+ * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko
+ Stamer.
+
+2004-09-21 Werner Koch <wk@g10code.de>
+
+ * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann
+ Vandoorselaere.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Do not include <assert.h>.
+ * sexp.c: Likewise.
+ * module.c: Likewise.
+ * misc.c: Likewise.
+
+2004-08-18 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (_gcry_secmem_init): Try to lock pool into core not
+ only when running with root privileges.
+
+2004-08-16 Werner Koch <wk@g10code.de>
+
+ * secmem.h (_gcry_secmem_set_flags,_gcry_secmem_get_flags):
+ Removed __pure__.
+ (GCRY_SECMEM_FLAG_NO_WARNING): Put macro value into parens.
+
+ * secmem.c (_gcry_secmem_init): Defer printing of the warning.
+
+2004-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Include <sys/time.h>, thanks to Simon Josefsson.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRYCTL_FAST_POLL.
+ (gcry_fast_random_poll): New.
+ * global.c (gcry_control) <INITIALIZATION_FINISHED>: Do only basic
+ random subsystem init.
+ (gcry_control) <FAST_POLL>: New.
+
+2004-04-22 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt.m4: Quote first argument to AC_DEFUN.
+
+2004-04-15 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_malloc_internal): Removed old extra info
+ error output.
+ (_gcry_secmem_term): Use wipememory2 here.
+
+ * misc.c (_gcry_burn_stack): Use wipememory to avoid optimizations.
+
+ * string.c: Removed. Was never used.
+ * global.c (gcry_strdup): Replaced by the version from string.c
+ (gcry_xstrdup): Rewritten.
+ * gcrypt.h: Removed duplicate prototype for gcry_strdup.
+
+2004-03-29 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_realloc): Fixed double unlock; bug
+ manifested itself due to the more rigorous checking in the changed
+ ath.h
+
+ * libgcrypt-config.in (Options): Ignore the obsolete --threads
+ option for now.
+
+2004-03-17 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): Quote'em. Use
+ $gpg_error_cflags and $gpg_error_libs. Fix construction of
+ $includes.
+
+2004-03-14 Marcus Brinkmann <marcus@g10code.de>
+
+ * libgcrypt-config.in (includedir, libdir): New variables. For
+ --cflags, don't test $cflags. Also check against /include for the
+ GNU/Hurd. Don't overwrite but extend $cflags_final. Likewise for
+ --libs.
+
+2004-03-10 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (ltlib_libgcrypt_pthread, ltlib_libgcrypt_pth): Removed.
+ (lib_LTLIBRARIES): Remove those variables from here.
+ (libgcrypt_pthread_la_SOURCES, libgcrypt_pthread_la_LDFLAGS,
+ (libgcrypt_pthread_la_DEPENDENCIES, libgcrypt_pthread_la_LIBADD,
+ (libgcrypt_pth_la_SOURCES, libgcrypt_pth_la_LDFLAGS,
+ (libgcrypt_pth_la_DEPENDENCIES, libgcrypt_pth_la_LIBADD,
+ (noinst_LTLIBRARIES): Removed.
+ (libgcrypt_real_la_SOURCES): Merge with ...
+ (libgcrypt_la_SOURCES): ... likewise.
+ (libgcrypt_real_la_DEPENDENCIES): Merge with ...
+ (libgcrypt_la_DEPENDENCIES): ... this.
+ (libgcrypt_real_la_LIBADD): Merge with ...
+ (libgcrypt_la_LIBADD): ... this.
+ * libgcrypt-config.in (libs_pthread, libs_pth, cflags_pth)
+ (cflags_pthread, thread_module, thread_modules): Removed.
+ (Options): Remove --thread option from help output. If the option
+ is specified, output an error and exit.
+ For --cflags and --libs option, remove pth and pthread from output.
+ * gcrypt.h: Include <sys/types.h> and <sys/socket.h>.
+ (enum gcry_ctl_cmds): Add GCRYCTL_SET_THREAD_CBS.
+ (gcry_thread_cbs): New struct.
+ * global.c (gcry_control): Implement GCRYCTL_SET_THREAD_CBS.
+ (global_init): Don't call ath_init here.
+ * ath.h: Rewritten.
+ * ath.c: Rewritten.
+
+2004-03-06 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: s/--soname-number/--api-version/
+ * libgcrypt.m4: Changed test for API version.
+
+2004-03-05 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Optionally check the SONAME number.
+
+ * libgcrypt-config.in: Add option --soname-number
+
+2004-03-01 Marcus Brinkmann <marcus@g10code.de>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add ath.c.
+ * ath.c (ath_init): Add missing function.
+
+ * Makefile.am (ath_pth_src): Removed.
+ (ath_pthread_src): Removed.
+ (libgcrypt_la_SOURCES): Remove ath-compat, $(ath_pth_src) and
+ $(ath_pthread_src).
+ * ath-compat.c, ath-pth-compat.c, ath-pthread-compat.c: Files
+ removed.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_PRIME_CHECK_AT_GOT_PRIME)
+ (GCRY_PRIME_CHECK_AT_FINISH),
+ (GCRY_PRIME_CHECK_AT_MAYBE_PRIME): New.
+
+2004-02-18 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Ignore setting of --prefix.
+
+2004-02-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_128, alsthough not yet
+ supported.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added GCRY_CIPHER_RFC2268_40.
+
+2004-02-03 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_init): Do not print the "not locked into
+ core warning" if the NO_WARNING flag has been set.
+
+ * sexp.c (sexp_sscan): Allocate result in secure memory if BUFFER
+ is in secure memory. Switch to secure memory for the a secure %b
+ format item. Extra paranoid wipe on error.
+ (gcry_sexp_release): Added paranoid wiping for securely allocated
+ S-expressions.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * ath.h: Include <config.h>.
+
+2004-01-12 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h: Adjusted declarations of: gcry_ac_data_set,
+ gcry_ac_data_get_name, gcry_ac_data_get_index,
+ gcry_ac_key_pair_generate, gcry_ac_key_test,
+ gcry_ac_key_get_nbits, gcry_ac_key_get_grip.
+
+ * gcrypt.h (GCRY_AC_FLAG_DATA_NO_BLINDING): Removed symbol.
+ (GCRY_AC_FLAG_DEALLOC, GCRY_AC_FLAG_COPY)
+ (GCRY_AC_FLAG_NO_BLINDING): New symbols.
+
+ * global.c (gcry_strdup): Removed function.
+ * string.c: New file.
+ * Makefile.am (libgcrypt_real_la_SOURCES): Added: string.c.
+ * string.c (gcry_strdup): New function.
+ * gcrypt.h (gcry_strdup): Declare.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h (wipememory, wipememory2): New; taken from gnupg.
+
+2003-11-14 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): Don't copy the string after a malloc
+ error.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Implemented "%b" format specifier.
+
+2003-11-11 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt.m4: Do not set prefix when calling libgcrypt-config.
+ Thanks to Nikos Mavroyanopoulos.
+
+2003-11-08 Moritz Schulte <mo@g10code.com>
+
+ * cipher.h (small_prime_numbers): Removed declaration.
+ (PUBKEY_FLAG_NO_BLINDING): Put braces around shift.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * cipher.h (_gcry_sha1_has_buffer): New.
+
+ * gcrypt.h (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers (_gcry_generate_elg_prime): Removed this symbol;
+ gnutls does not need it anymore.
+
+ * secmem.c (mb_get_new): s/pool/block/ due to global pool.
+
+ * misc.c (gcry_set_log_handler): s/logf/f/ to avoid shadowing
+ warning against a builtin.
+
+ * ath-pth-compat.c: cast pth_connect to get rid of the const
+ prototype.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * ath.h (ATH_MUTEX_INITIALIZER): Removed spurious semicolon.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Include libs/cflags of libgpg-error.
+
+ * sexp.c (sexp_sscan): Cleaned up, deallocate scanned sexp on
+ error.
+
+ * module.c (MODULE_ID_MIN): New symbol, use it.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_pk_testkey): Doc fix.
+
+2003-09-29 Moritz Schulte <mo@g10code.com>
+
+ * libgcrypt-config.in: Fix --algorithms option.
+
+2003-10-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_err_code): Use GPG_ERR_INLINE instead of
+ __inline__.
+
+ * secmem.c (lock_pool): Don't print the warning for certain
+ systems, handle ENOMEM.
+
+2003-10-21 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Fixed format sepcifier for a
+ size_t. Reported by Stephane Corthesy.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * global.c (_gcry_malloc): Handle the no_secure_memory option.
+
+ * gcrypt.h (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-07 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Check that parenthesis are matching.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * g10lib.h: Declare: _gcry_malloc.
+ (GCRY_ALLOC_FLAG_SECURE): New symbol.
+
+ * global.c (_gcry_malloc): New function...
+ (gcry_malloc): ... use it.
+ (gcry_malloc_secure): Likewise.
+
+ * ath.c: Change License to LGPL.
+ * ath-pthread-compat.c: Likewise.
+ * ath-pthread.c: Likewise.
+ * ath-pth-compat.c: Likewise.
+ * ath-pth.c: Likewise.
+ * ath.h: Likewise.
+ * ath-compat.c: Likewise.
+
+ * secmem.c (_gcry_secmem_realloc): Do not forget to release secmem
+ lock. Thanks to low halo for triggering this bug.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (_GCRY_ERR_SOURCE_DEFAULT): Removed cruft.
+ (gcry_prime_check_func_t): Renamed arg for clarity.
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (GCRY_PRIME_FLAG_SPECIAL_FACTOR): New symbol.
+
+2003-09-01 Moritz Schulte <mo@g10code.com>
+
+ * gcrypt.h (gcry_random_level_t): New type.
+ (gcry_prime_check_func_t): Likewise.
+ (GCRY_PRIME_FLAG_SECRET): New symbol.
+ (gcry_prime_generate, gcry_prime_check): Declare functions.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_pth_la_LDFLAGS): Removed PTH_CFLAGS cruft.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * global.c (gcry_control): Remove call to ath_deinit.
+
+ * Makefile.am (libgcrypt_real_la_DEPENDENCIES): Fixed.
+ (libgcrypt_real_la_LIBADD): Fixed.
+ Removed unecessary variables.
+
+ * libgcrypt-config.in: Adjusted script for new thread handling.
+
+ * Makefile.am: New version, based on GPGMEs Makefile.am.
+
+ * ath.c, ath-compat.c, ath.h, ath-pth.c, ath-pth-compat.c,
+ ath-pthread.c, ath-pthread-compat.c: New files, merged from GPGME.
+ * ath.c, ath.h, ath-pthread.c, ath-pth.c: Removed files.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_realloc): Remove FIXME about `clearing out
+ realloced memory', since _gcry_secmem_realloc takes care of
+ overwriting old memory.
+
+2003-08-07 Werner Koch <wk@gnupg.org>
+
+ * module.c (_gcry_module_release): Don't act if module is NULL.
+
+2003-07-30 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_ac_id): Added: GCRY_AC_ELG_E.
+ Reverted change: use gcry_md_flags enumeration list instead of
+ defines.
+
+2003-07-29 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add GCRYCTL_SET_RANDOM_SEED_FILE and
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE.
+ * gcrypt.h: Ditto. Renamed index to idx, so avoid warning
+ related to the old index function.
+
+2003-07-28 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (gcry_err_code_from_errno, gcry_err_code_to_errno)
+ (gcry_err_make_from_errno, gcry_error_from_errno): New functions.
+
+ * gcrypt.h: Declared: gcry_err_code_from_errno,
+ gcry_err_code_to_errno, gcry_err_make_from_errno,
+ gcry_error_from_errno.
+
+ * Makefile.am (include_HEADERS): Added: gcrypt-module.h.
+
+ * gcrypt.h: Include <gcrypt-module.h>.
+
+ * gcrypt-module.h: New file.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_scan, gcry_mpi_print): API change.
+ (gcry_mpi_dump): New.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declared: gcry_ac_key_data_get.
+ (gcry_pk_spec): Renamed member `sexp_names' into `aliases'.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_md_oid_spec_t): New type.
+ (gcry_md_spec): New member: oids.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_oid_spec_t): New type.
+ (gcry_cipher_spec): New member: oids;
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_mpi_set_opaque): Add a warning comment.
+
+2003-07-15 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (compress_pool): Remove function, since unused blocks
+ are automatically concatenad.
+
+ * gcrypt.h: Bumped version number up to 1.1.42-cvs.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_spec): New member: aliases.
+
+ * Makefile.am (noinst_PROGRAMS, testapi_SOURCES, testapai_LDADD,
+ benchmark_SOURCES, benchmark_LDADD): Removed.
+
+ * benchmark.c, testapi.c: Removed files.
+
+ * mpi.h: Removed disabled typedef.
+ * g10lib.h: Likewise.
+
+ * benchmark.c, g10lib.h, gcrypt.h, global.c, module.c, sexp.c:
+ Used gcry_err* wrappers for libgpg-error symbols.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Likewise.
+
+ * gcrypt.h: New type: gcry_error_t, gcry_err_code_t and
+ gcry_err_source_t.
+ (gcry_err_make, gcry_error, gcry_err_code, gcry_err_source): New
+ functions.
+
+ * global.c (gcry_strerror): New function.
+ (gcry_strsource): New function.
+
+ * gcrypt.h: New symbol: GCRY_CIPHER_TWOFISH128.
+
+2003-07-09 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_md_flags): Removed, used define instead,
+ since that is more common than an enumeration list when it comes
+ to flags that can be bitwise ORed.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * global.c: Use new types for handlers.
+
+ * gcrypt.h: Declare: gcry_ac_data_copy.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_build_array): Use dummy argument pointer.
+ Thanks to Simon Josefsson <jas@extunde.com>.
+
+ * gcrypt.h: Declare: gcry_cipher_list, gcry_pk_list, gcry_md_list.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Declare: gcry_cipher_register, gcry_cipher_unregister,
+ gcry_md_register, gcry_md_unregister, gcry_pk_register,
+ gcry_pk_unregister.
+ (gcry_cipher_spec): Removed member: algorithm.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+ Adjusted declarations: gcry_cipher_register, gcry_pk_register,
+ gcry_md_register.
+
+ * module.c: Replaced all occurences of `id' with `mod_id', since
+ `id' is a keyword in obj-c.
+
+ * gcrypt.h (gcry_cipher_spec): Renamed member `id' to `algorithm'.
+ (gcry_pk_spec): Likewise.
+ (gcry_md_spec): Likewise.
+
+ * cipher.h: Removed types: gcry_pubkey_generate_t,
+ gcry_pubkey_check_secret_key_t, gcry_pubkey_encrypt_t,
+ gcry_pubkey_decrypt_t, gcry_pubkey_sign_t, gcry_pubkey_verify_t,
+ gcry_pubkey_get_nbits_t, gcry_pk_spec_t, gcry_digest_init_t,
+ gcry_digest_write_t, gcry_digest_final_t, gcry_digest_read_t,
+ gcry_digest_spec_t, gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t, gcry_cipher_spec_t.
+
+ * gcrypt.h: New types: gcry_pk_generate_t,
+ gcry_pk_check_secret_key_t, gcry_pk_encrypt_t, gcry_pk_decrypt_t,
+ gcry_pk_sign_t, gcry_pk_verify_t, gcry_pk_get_nbits_t,
+ gcry_pk_spec_t, gcry_md_init_t, gcry_md_write_t, gcry_md_final_t,
+ gcry_md_read_t, gcry_md_spec_t, gcry_cipher_setkey_t,
+ gcry_cipher_encrypt_t, gcry_cipher_decrypt_t,
+ gcry_cipher_stencrypt_t, gcry_cipher_stdecrypt_t,
+ gcry_cipher_spec_t, gcry_module_t.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_list): New function.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_lookup): Fixed typo.
+
+ * gcrypt.h: Added all definitions and declarations necessary for
+ the new ac interface.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Added declarations: _gcry_pk_module_lookup,
+ _gcry_pk_module_release.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c (cipher_bench): Adjusted for new API of get_blklen
+ and get_keylen.
+
+ * gcrypt.h (gcry_cipher_get_algo_blklen)
+ (gcry_cipher_get_algo_keylen): Replaced macro by funcion.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Renamed types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec into: gcry_digest_spec_t, gcry_cipher_spec_t and
+ gcry_pubkey_spec_t.
+ (gcry_pubkey_spec): Defined member `id' as unsigned.
+ (gcry_digest_spec): Likewise.
+ (gcry_cipher_spec): Likewise.
+
+ * module.c (_gcry_module_id_new): New function.
+ (_gcry_module_add): Generate a new ID via _gcry_module_id_new in
+ case `id' is zero.
+
+ * g10lib.h, module.c: Replace old type GcryModule with newer one:
+ gcry_module_t.
+
+ * module.c (_gcry_module_add): Added argument `id', use it.
+
+ * g10lib.h: Added declaration: _gcry_module_lookup_id.
+ (_gcry_module_add): Added argument `id'.
+
+ * module.c (_gcry_module_lookup_id): New function.
+
+ * g10lib.h (struct gcry_module): New member: id.
+
+ * gcrypt.h: New type: gcry_handler_progress_t,
+ gcry_handler_alloc_t, gcry_haandler_secure_check_t,
+ gcry_handler_realloc_t, gcry_handler_free_t,
+ gcry_handler_no_mem_t, gcry_handler_error_t, gcry_handler_log_t.
+ Use new types.
+
+ * cipher.h: Include <gcrypt.h>.
+ New types: gcry_pk_generate_t, gcry_pk_check_secret_key_t,
+ gcry_pk_encrypt_t, gcry_pk_decrypt_t, gcry_pk_sign_t,
+ gcry_pk_verify_t, gcry_pk_get_nbits_t, gcry_md_init_t,
+ gcry_md_write_t, gcry_md_final_t, gcry_md_read_t,
+ gcry_cipher_setkey_t, gcry_cipher_encrypt_t,
+ gcry_cipher_decrypt_t, gcry_cipher_stencrypt_t,
+ gcry_cipher_stdecrypt_t.
+ Use new types.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * mpi.h: Likewise.
+ * sexp.c: Likewise.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * testapi.c (test_genkey): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * global.c (gcry_control): Fixed typo.
+
+ * misc.c (_gcry_fatal_error): Use gpg_strerror instead of
+ gcry_strerror.
+
+ * types.h (STRLIST): Removed type since it is not used.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * global.c (global_init): Call: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * g10lib.h: Declare: _gcry_cipher_init, _gcry_md_init,
+ _gcry_pk_init.
+
+ * global.c (gcry_strerror): Remove compatibility code.
+
+ * Makefile.am: Remove support libgpg-error special handling.
+ (AM_CPPFLAGS): Add @GPG_ERROR_CFLAGS@
+
+ * gcrypt.h: Likewise.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_enabled): New.
+ (gcry_md_is_secure): Replaced macro by function and reverted to old
+ API.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR): Define _GCRY_ERR_SOURCE_DEFAULT instead of
+ GPG_ERR_SOURCE_DEFAULT, so that libgpg-error still works despite
+ the use of the old gcrypt error codes.
+ (gcry_md_copy): Swapped arguments.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Support for libgpg-error.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (gcry_sexp_create): Expect sane error values from
+ gcry_sexp_canon_len instead of the `historical' values.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * ath.c, ath.c, ath-pth.c, ath-pthread.c, benchmark.c, cipher.h,
+ g10lib.h, gcrypt.h, global.c, misc.c, missing-string.c, module.c,
+ mpi.h, secmem.c, secmem.h, sexp.c, stdmem.c, stdmem.h, testapi.c,
+ types.h: Edited all preprocessor instructions to remove whitespace
+ before the '#'. This is not required by C89, but there are some
+ compilers out there that don't like it. Replaced any occurence of
+ the now deprecated type names with the new ones.
+
+ * gcrypt.h: Re-organized checking for gcc features; New macro:
+ _GCRY_GCC_ATTR_DEPRECATED.
+ Include copy of libgpg-error's gpg-error.h in order to make it
+ easy to build libgcrypt without needing libgpg-error.h.
+
+ (GCRY_MPI, GcryMPI, GCRY_SEXP, GcrySexp, GCRY_CIPHER_HD,
+ GcryCipherHd, GCRY_MD_HD, GcryMDHd): Declared deprecated.
+ (gcry_mpi_t, gcry_sexp_t, gcry_cipher_hd_t, gcry_md_hd_t): New
+ types.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (sexp_sscan): New argument: arg_list, adjusted all
+ callers.
+ (ARG_NEXT): New macro.
+ (sexp_sscan): Use ARG_NEXT for receiving format string arguments.
+ (gcry_sexp_build_array): New function.
+
+2003-06-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Added some comments describing the gcry_sexp_*
+ functions.
+ Include <gpg-error.h> instead of <gpg/error.h>.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * sexp.c (OLDPARSECODE): Removed macro...
+ (gcry_sexp_canon_len): ... and do not use it.
+
+ * gcrypt.h (gcry_errno): Removed declaration.
+
+ * g10lib.h (string_to_pubkey_algo, pubkey_algo_to_string,
+ pubkey_nbits): Removed declarations for non-existing functions.
+
+2003-05-31 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (is_RSA, is_ELGAMAL): Removed macros.
+
+ * g10lib.h (set_lasterr): Removed macro.
+ (_gcry_set_lasterr): Removed declaration.
+
+ * gcrypt.h: Changed declarations for: gcry_pk_algo_info,
+ gcry_md_open, gcry_md_copy, gcry_md_algo_info, gcry_md_info,
+ gcry_md_get_algo, gcry_random_add_bytes.
+
+ (gcry_md_is_secure): Adjust macro for new API.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Changed declarations for: gcry_cipher_open,
+ gcry_cipher_info, gcry_cipher_algo_info.
+ (gcry_cipher_get_algo_keylen): Adjuster for new
+ gcry_cipher_algo_info interface.
+ (gcry_cipher_get_algo_blklen): Likewise.
+
+ * global.c (gcry_errno): Removed function.
+ (gcry_strerror): Do not use gcry_errno.
+ (_gcry_set_lasterr): Removed function.
+ (last_ec): Removed variable.
+
+2003-05-27 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (enum gcry_cipher_algos): Make Serpent IDs do not
+ conflict with OpenPGP. Reported by Timo Schulz.
+
+ * global.c (gcry_control): Fixed name of enum list.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_cipher_spec): Adjust return type of `setkey' for
+ libgpg-error.
+ (gcry_pubkey_spec): Adjust return type of `generate',
+ `check_secret_key', `encrypt', `decrypt', `sign' and `verify' for
+ libgpg-error.
+
+ * sexp.c (gcry_sexp_canon_len): Adjusted for libgpg-error.
+ (gcry_sexp_create): Likewise.
+ (gcry_sexp_new): Likewise.
+ (sexp_sscan): Likewise.
+ (gcry_sexp_build): Likewise.
+ (gcry_sexp_sscan): Likewise.
+
+ * module.c (_gcry_module_add): Likewise.
+
+ * global.c (last_ec): Change type to gpg_error_t.
+ (gcry_control): Adjust for libgpg-error.
+ (gcry_errno): Likewise.
+ (gcry_strerror): Likewise.
+ (_gcry_set_lasterr): Likewise.
+ (gcry_xmalloc): Likewise.
+ (gcry_xrealloc): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * types.h: Merged code from GnuPG regarding U64_C.
+
+ * missing-string.c (strsep): Removed function.
+
+ * g10lib.h: Removed declarations: strsep, strlwr.
+
+ * secmem.c (secmem_lock): New variable.
+ (SECMEM_LOCK, SECMEM_UNLOCK): New macros.
+ (_gcry_secmem_set_flags): Use SECMEM_LOCK and SECMEM_UNLOCK.
+ (_gcry_secmem_get_flags): Likewise.
+ (_gcry_secmem_init): Likewie.
+ (_gcry_secmem_malloc): Likewise.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_malloc): Renamed to ...
+ (_gcry_secmem_malloc_internal): ... this.
+ (_gcry_secmem_malloc): New function, use SECMEM_LOCK,
+ SECMEM_UNLOCK, call _gcry_secmem_malloc_internal.
+ (_gcry_secmem_free): Renamed to ...
+ (_gcry_secmem_free_internal): ... this.
+ (_gcry_secmem_free): New function, use SECMEM_LOCK, SECMEM_UNLOCK,
+ call _gcry_secmem_free_internal.
+ (_gcry_secmem_realloc): Use SECMEM_LOCK, SECMEM_UNLOCK, call
+ _gcry_secmem_malloc_internal and _gcry_secmem_free_internal.
+ (_gcry_private_is_secure): Use SECMEM_LOCK, SECMEM_UNLOCK.
+ (_gcry_secmem_dump_stats): Likewise.
+ (_gcry_secmem_malloc_internal): Removed unused variable:
+ compressed.
+ Include "ath.h".
+
+2003-05-21 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192,
+ GCRY_CIPHER_SERPENT256): New symbols.
+
+2003-05-19 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h: Reversed changes from 2003-03-03 since they would have
+ been an unnecessary ABI break.
+
+2003-05-13 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (stats_update): New function.
+ (BLOCK_HEAD_SIZE): New symbol.
+ (MB_FLAG_ACTIVE): New symbol.
+ (ADDR_TO_BLOCK, BLOCK_VALID): New macros.
+ (mb_get_next): New function.
+ (mb_get_prev): New function.
+ (mb_merge): New function.
+ (mb_get_new): New function.
+ (unused_blocks): Removed variable.
+ (init_pool): Initialize new memory pool.
+ (_gcry_secmem_malloc): Use new heap management code.
+ (_gcry_secmem_free): Likewise.
+ (_gcry_secmem_realloc): Likewise.
+ Renamed type MEMBLOCK to memblock_t.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): New member: sexp_names.
+
+2003-04-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (gcry_pubkey_spec): Removed members: npkey, nskey,
+ nenc, nsig.
+ (gcry_pubkey_spec): Added members: elements_pkey, elements_skey,
+ elements_enc, elements_sig, elements_grip.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * g10lib.h (GcryModule): New typedef.
+
+ * gcrypt.h (gcry_cipher_register, gcry_cipher_unregister,
+ gcry_digest_register, gcry_digest_unregister,
+ gcry_pubkey_register, gcry_pubkey_unregister): Function
+ declarations removed - for now.
+
+ * gcrypt.h (GcryModule): Declaration removed.
+ * gcrypt.h (GcryPubkeySpec, GcryDigestSpec, GcryCipherSpec):
+ Types Moved...
+ * cipher.h: ... here.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h: Declare digest_spec_sha512 and digest_spec_384.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * module.c (_gcry_module_use): New function.
+ * g10lib.h (_gcry_module_use): Declare function.
+
+ * libgcrypt-config.in: Support for --algorithms switch, which
+ prints the algorithms included in the built libgcrypt.
+
+ * global.c (gcry_set_progress_handler): Register progress
+ functions depending on the enabled algorithms.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Added module.c
+
+ * module.c: New file.
+ (_gcry_module_add): New function.
+ (_gcry_module_drop): New function.
+ (_gcry_module_lookup): New function.
+ (_gcry_module_release): New function.
+
+ * g10lib.h (GcryModule): New types.
+ (FLAG_MODULE_DISABLED): New symbol.
+ Added declarations for _gcry_module_add, _gcry_module_release and
+ _gcry_module_lookup.
+
+ * gcrypt.h: New types: GcryPubkeySpec, GcryDigestSpec,
+ GcryCipherSpec.
+ Added declarations for: gcry_cipher_register,
+ gcry_cipher_unregister, gcry_digest_register,
+ gcry_digest_unregister, gcry_pubkey_register and
+ gcry_pubkey_unregister.
+
+ * cipher.h: Removed symbols: CIPHER_ALGO_NONE, CIPHER_ALGO_IDEA,
+ CIPHER_ALGO_3DES, CIPHER_ALGO_CAST5, CIPHER_ALGO_BLOWFISH,
+ CIPHER_ALGO_SAFER_SK128, CIPHER_ALGO_DES_SK, CIPHER_ALGO_TWOFISH,
+ CIPHER_ALGO_TWOFISH_OLD, CIPHER_ALGO_DUMMY, PUBKEY_USAGE_SIG,
+ PUBKEY_USAGE_ENC, DIGEST_ALGO_MD5, DIGEST_ALGO_SHA1,
+ DIGEST_ALGO_RMD160, DIGEST_ALGO_TIGER, PUBKEY_ALGO_RSA,
+ PUBKEY_ALGO_RSA_E, PUBKEY_ALGO_RSA_S, PUBKEY_ALGO_DSA,
+ PUBKEY_ALGO_ELGAMAL, PUBKEY_ALGO_ELGAMAL_E.
+
+2003-04-02 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (md_bench): Fix error message.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (cipher_bench): Added CTR mode.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (enum gcry_control_cmds): Add GCRY_SET_CTR.
+ (enum gcry_cipher_modes): Add GCRY_CIPHER_MODE_CTR.
+ (gcry_cipher_setctr): New macro to set counter.
+
+2003-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.h (PUBKEY_FLAG_NO_BLINDING): New symbol.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h: Add GCRYCTL_SET_CBC_MAC and GCRY_CIPHER_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * g10lib.h: Adjusted primegen.c prototypes.
+
+2003-03-12 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Initialize NM. Thanks to Ian Peters for
+ valgrinding this.
+
+2003-03-06 Moritz Schulte <mo@g10code.com>
+
+ * secmem.h (GCRY_SECMEM_FLAG_NO_WARNING,
+ GCRY_SECMEM_FLAG_SUSPEND_WARNING): New symbols.
+
+ * global.c (gcry_control): Use
+ GCRY_SECMEM_FLAG_{NO,SUSPEND}_WARNING, instead of hard-coded
+ values.
+ * secmem.c (_gcry_secmem_set_flags): Likewise.
+ * secmem.c (_gcry_secmem_get_flags): Likewise.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * misc.c: Removed old FIXME, since there is already a function to
+ set the value of `verbosity_level'.
+
+ * gcrypt.h: Removed enumeration list: gcry_ctl_cmds.
+ New enumeration lists: gcry_global_control_cmds,
+ gcry_control_cmds, gcry_info_cmds, gcry_algo_info_cmds.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * gcrypt.h (gcry_cipher_reset): New macro for resetting a handle.
+
+2003-02-28 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.c (DEFAULT_PAGESIZE): New symbol.
+ (init_pool): Use DEFAULT_PAGESIZE.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * secmem.h: Fix typo in declaration of _gcry_secmem_term.
+
+ * sexp.c: Move macro definitions of `digitp', `octdigit', `alphap'
+ and `hexdigit' ...
+ * g10lib.h: ... here.
+
+ * misc.c (_gcry_burn_stack): New function (former name:
+ burn_stack).
+
+ * g10lib.h (burn_stack): Declare _gcry_burn_stack().
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_set_progress_handler): Register a random progress
+ handler.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_ENABLE_QUICK_RANDOM): New.
+ * global.c (gcry_control): Make use of it.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_random_add_bytes): Add QUALITY argument.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * gcrypt.h (gcry_random_add_bytes): New.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_md_algos): Add GCRY_MD_CRC32,
+ GCRY_MD_CRC32_RFC1510, GCRY_MD_CRC24_RFC2440.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (gcry_md_write): Changed type of 2nd argument to void*.
+ (gcry_md_hash_buffer): Changed type of both buffers to void*.
+ (gcry_md_setkey): Changed type of 2nd argument to void*.
+ (gcry_md_get_asnoid): New.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_length): Fixed. This was seriously broken.
+
+2003-01-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYERR_INV_FLAG), global.c (gcry_strerror): New.
+
+2003-01-02 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.vers: Temporary export _gcry_generate_elg_prime for
+ use by GNUTLS.
+
+2002-12-21 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Make use of gcc's pure and malloc attributes
+ (gcry_md_putc): Use a helper variable to avoid multiple
+ evaluation of H.
+ * g10lib.h, stdmem.h, secmem.h: Use gcc attributes pure and malloc.
+
+ * stdmem.c (use_m_guard): Don't default to yes.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * global.c (global_init): The meat was never run due to a faulty
+ check. Thanks to Nikos for pointing this out.
+
+ * global.c (gcry_control): Return 1 and not -1 for the
+ initialization tests.
+
+ * libgcrypt.vers: New.
+ * Makefile.am: Use this instead of the build symbol file.
+
+ * global.c (gcry_control) <initialization>: Call the random module
+ initializer to make sure that the pool lock flag has been
+ initialized.
+
+2002-12-09 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_calloc,gcry_calloc_secure): Check for overflow.
+ Noted by Florian Weimer.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * gcrypt.h (gcry_ctl_cmds): New GCRYCTL_SET_CBC_CTS control flag.
+ (gcry_cipher_flags): New GCRY_CIPHER_CBC_CTS gcry_cipher_open() flag.
+ (gcry_cipher_cts): New macro for toggling CTS.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRY_MD_MD4): New. We use a non OpenPGP value here.
+
+2002-09-20 Werner Koch <wk@gnupg.org>
+
+ * ath.c: Include sys.time.h if sys/select.h does not exist.
+ (ath_select, ath_waitpid): Shortcut for Windows.
+ * ath.h: Include some Windows headers. By Timo.
+
+2002-09-18 Werner Koch <wk@gnupg.org>
+
+ * ath.h: Prefix ath_deinit.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * benchmark.c: New.
+ (mpi_bench, do_powm): Add a a simple test for RSA.
+
+ * global.c (global_init): New. Use it instead of the setting
+ any_init_done. Initialize the ATH system.
+ (gcry_check_version): Hook global_init in. This is the suggested
+ way to initialize the library.
+ (_gcry_no_internal_locking): Removed. We simply call a ath_deinit
+ and leave it to ATH to disbale the locking.
+
+ * ath.c, ath.h, ath-pth.c, ath-pthread.c: New. Taken from GPGME.
+ * mutex.h: Removed.
+ * Makefile.am (ath_components): New.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * secmem.c (_gcry_secmem_dump_stats): Replaced fprintf by log_*.
+
+2002-08-23 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Removed unneeded strlwr.
+
+ * libgcrypt.m4: Made much more simple.
+ * libgcrypt-config.in: Made --prefix work for --libs.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Add GCRY_CIPGER_DES. Included string.h for size_t.
+ Suggested by Simon Josefsson.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * cipher.h: Added prototypes for progress functions.
+ * global.c: Include cipher.h for those prototypes.
+
+ * stdmem.c (_gcry_private_realloc): Replaced void* by char * for
+ pointer arithmetic reasons. Noted by Stephan Austermuehle.
+
+2002-06-24 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: Include ctype.h.
+
+ * gcrypt.h (gcry_mpi_invm, gcry_mpi_div, gcry_mpi_mod)
+ (gcry_mpi_swap): New.
+
+2002-06-18 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Added a bunch of brief function descriptions.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): Don't initialize a va_list. Noted by
+ Jeff Johnson.
+
+ * global.c (gcry_set_progress_handler): New.
+
+ * gcrypt.h: Replaced the typedef for byte.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * missing-string.c: New.
+
+ * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
+ GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
+ ones using an underscore.
+
+ * global.c (gcry_strerror): Add strings fro the new error codes.
+ * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
+ old error codes.
+ (gcry_sexp_create,gcry_sexp_new): New.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and
+ initialize it so that we can detect an unitialized mutex and don't
+ read from stdin.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-05-07 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_control): Add commands
+ GCRYCTL_ANY_INITIALIZATION_P and GCRYCTL_INITIALIZATION_FINISHED_P
+ so that other libraries are able to check for required
+ initializations.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h (GCRYCTL_DISABLE_INTERNAL_LOCKING): New.
+ * global.c (gcry_control): Implement it.
+ (_gcry_no_internal_locking): New.
+ * mutex.h: Prefixed all fucntions with _gcry_. Bypass all
+ functions when desired.
+
+ * gcrypt.h (GCRYCTL_DISABLE_SECMEM): New.
+ * global.c (gcry_control,gcry_malloc_secure,gcry_is_secure):
+ Implement it here.
+ * secmem.c (_gcry_private_is_secure): Return false if the pool is
+ not initialized.
+
+ * gcrypt.h (GCRYCTL_INITIALIZATION_FINISHED): New.
+
+ * gcrypt.h (gcry_cipher_algos): Replaced RINDAEL by AES and change
+ the macros to expand from rijdael to aes.
+
+ * stdmem.c (_gcry_private_malloc): Return NULL for 0 byte allocation.
+ (_gcry_private_malloc_secure): Ditto.
+
+ * g10lib.h: Copied the JNLIB_GCC macros from ../jnlib/mischelp.h
+ and removed the inclusion of that file.
+
+2002-04-15 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strdup): New.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * mutex.h: New file with a portable thread mutex implementation
+ written by Marcus Brinkmann. Taken from GPGME.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_sscan): Don't initialize the dummy
+ variable. Suggested by Jordi Mallach.
+
+2002-01-31 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (suitable_encoding,convert_to_hex,convert_to_string)
+ (convert_to_token): New.
+ (gcry_sexp_sprint): Better formatting of advanced encoding, does
+ now insert LFs and escapes all unprintable characters.
+ (unquote_string): New.
+ (sexp_sscan): Implemented the missing conversion of quoted strings.
+
+2002-01-26 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt-config.in: Add copyright notice.
+
+2002-01-11 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed last change.
+
+2002-01-01 Timo Schulz <ts@winpt.org>
+
+ * stdmem.c (_gcry_private_realloc): If pointer is NULL now realloc
+ behaves like malloc.
+
+2001-12-20 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Describe the error codes and
+ return an error if this is not a S-Exp; i.e. it does not start
+ with an open parenthesis.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): Fixed the test on NULL buffer.
+
+ * Makefile.am (DISTCLEANFILES): Include libgcrypt.sym
+
+ * sexp.c: Removed the commented test code because we now have a
+ test in ../tests/
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (gcry_sexp_canon_len): New.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Fixed AES128 macro, add enum for OFB mode.
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * misc.c (_gcry_log_printf): New.
+ * sexp.c (dump_string,gcry_sexp_dump): Use logging functions
+ instead of stderr.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New constant GCRYCTL_IS_ALGO_ENABLED.
+
+2001-10-02 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Removed a couple of trailing commas.
+
+2001-08-28 Werner Koch <wk@gnupg.org>
+
+ * sexp.c (sexp_sscan): Add an argument to enable the
+ arg_ptr. Changed all callers. Suggested by Tom Holroyd.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * global.c (gcry_strerror): Updated list of error codes.
+
+2001-07-23 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: Replaced the last ulong. Noted by Rami Lehti.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h, mpi.h: Made some mpi functions public.
+
+ * wrapper.c: Removed.
+ * global.c: Renamed all g10_ prefixed functions which had wrappers
+ to gcry_xxx. So we now use the exported memory functions inernally.
+
+ Renamed all g10_ prefixed functions to _gcry_ prefixed ones.
+
+ * g10lib.h (_GCRYPT_IN_LIBGCRYPT): Replace defintion by a test on it.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * libgcrypt.m4: Check GCRYPT_VERSION macro and not LIBGCRYPT_VERSION.
+
+ * mpi.h: Removed mpi_fromstr prototype.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (libgcrypt_la_SOURCES): Add mpi.h
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ * types.h: Moved from ../include to here.
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Moved to ../mpi.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-11 Werner Koch <wk@gnupg.org>
+
+ * mpi.h: Changed the way mpi_limb_t is defined.
+
+2000-10-10 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am: Take version-info from configure.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * gcrypt.h: New cipher mode, new algo Arcfour and new error code
+ GCRYERR_INV_CIPHER_MODE.
+ * global.c (gcry_strerror): New errorcode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New.
+
+ * secmem.c (secmem_realloc): check for failed secmem_malloc. By
+ Matt Kraai.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Removed the datalen fields from list tags.
+ (gcry_sexp_car_data,gcry_sexp_cdr_data,gcry_sexp_car_mpi,
+ gcry_sexp_cdr_mpi): Removed.
+ (gcry_sexp_nth,gcry_sexp_nth_data,gcry_sexp_nth_mpi): New.
+
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c (sexp_sscan): Fixed reallocation to secure memory.
+ (new_empty_list): Removed
+ (gcry_sexp_length): New.
+ (gcry_sexp_enum): Removed.
+ (normalize): New. Reworked the whole thing to use NULL for an empty list.
+ (make_space): New instead of the macro.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c: Major rewrite.
+ (gcry_sexp_sscan): Reordered arguments. Moved functionality to ..
+ (sexp_sscan): .. this.
+ (gcry_sexp_build): New.
+ (gcry_sexp_new_name_mpi, gcry_sexp_new_name_data, gcry_sexp_new_data,
+ gcry_sexp_new_mpi): Removed.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * gcrypt.h (gcry_md_start_debug, gcry_md_stop_debug): New.
+ (gcry_ctl_cmds): New control values
+
+ * sexp.c (gcry_sexp_sscan): Add hex format parsing.
+
+ * secmem.c (lock_pool): Check for ENOSYS return my mlock() on old SCOs.
+ (pool_is_mmapped): Made volatile.
+ (lock_pool): No more warning for QNX. By Sam Roberts.
+ (lock_pool,secmem_init): Additional check for dropped privs.
+
+2000-03-21 09:18:48 Werner Koch (wk@habibti.gnupg.de)
+
+ * gcrypt.h (gcry_md_setkey): New.
+ (GCRY_MD_FLAG_HMAC): New.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * Makefile.am: Add g10lib.h
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_sscan): Allow NULL for erroff.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (gcry_sexp_alist): New.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * secmem.c: Moved from ../util to here.
+ * secmem.h: New.
+ * stdmem.c: New. Based on the old ../util/memory.c.
+ * stdmem.h: New.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gcrypt.m4: New.
+ * gcrypt-config: New.
+
+ * mpi.h (mpi_get_nbit_info): Removed
+ (mpi_set_nbit_info): Removed.
+ (struct gcry_mpi): Removed the nbits field.
+
+ * misc.c (g10_log_verbosity): New.
+
+ * global.c (g10_xstrdup): New.
+
+ * mpiapi.c: Removed.
+
+ * mpi.h: Moved from ../include to here. Removed some obsolete
+ prototypes and the iobuf.h header.
+ * cipher.h: Moved from ../include to here. Removed the mpi.h header.
+ * g10lib.h: Moved from ../include to here.
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * sexp.c (dump_string): New. Taken from gnupg/util/miscutil.c.
+ (do_dump_list): s/print_string/dump_string/.
+
+ * testapi.c: New.
+
+ * mpiapi.c (gcry_mpi_randomize): Use new random API.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * gloabl.c (gcry_control): Add cases for dumping random
+ and secmem stats.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * pkapi.c: Removed.
+
+ * symapi.c: Removed.
+
+ * g10lib.h: Moved to ../include.
+
+ * mdapi.c: Removed.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * sexp.c: New.
+
+Tue Dec 8 13:15:16 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * gcrypt.h: New
+ * mpiapi.c: New
+
+
+ Copyright (C) 1998,1999,2000,2001,2002,2003
+ 2004,2005,2008,2009,2011 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+# Makefile.am - for gcrypt/src
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+# 2006, 2007 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+## Process this file with automake to produce Makefile.in
+
+EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+ gcrypt.h.in libgcrypt.def
+
+bin_SCRIPTS = libgcrypt-config
+m4datadir = $(datadir)/aclocal
+m4data_DATA = libgcrypt.m4
+include_HEADERS = gcrypt.h gcrypt-module.h
+
+lib_LTLIBRARIES = libgcrypt.la
+bin_PROGRAMS = dumpsexp hmac256
+if USE_RANDOM_DAEMON
+sbin_PROGRAMS = gcryptrnd
+bin_PROGRAMS += getrandom
+endif USE_RANDOM_DAEMON
+
+# Depending on the architecture some targets require libgpg-error.
+if HAVE_W32CE_SYSTEM
+arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
+arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+else
+arch_gpg_error_cflags =
+arch_gpg_error_libs =
+endif
+
+
+if HAVE_LD_VERSION_SCRIPT
+ libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
+else
+ libgcrypt_version_script_cmd =
+endif
+
+libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
+libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
+ cipher.h cipher-proto.h \
+ misc.c global.c sexp.c hwfeatures.c \
+ stdmem.c stdmem.h secmem.c secmem.h \
+ mpi.h missing-string.c module.c fips.c \
+ hmac256.c hmac256.h \
+ ath.h ath.c
+
+if HAVE_W32_SYSTEM
+
+RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
+LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+
+SUFFIXES = .rc .lo
+
+.rc.lo:
+ $(LTRCCOMPILE) -i "$<" -o "$@"
+
+gcrypt_res = versioninfo.lo
+no_undefined = -no-undefined
+export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+
+install-def-file:
+ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
+
+uninstall-def-file:
+ -rm $(DESTDIR)$(libdir)/libgcrypt.def
+
+gcrypt_deps = $(gcrypt_res) libgcrypt.def
+
+else !HAVE_W32_SYSTEM
+
+gcrypt_res =
+gcrypt_res_ldflag =
+no_undefined =
+export_symbols =
+install-def-file:
+uninstall-def-file:
+
+gcrypt_deps =
+
+endif !HAVE_W32_SYSTEM
+
+
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
+ $(libgcrypt_version_script_cmd) -version-info \
+ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
+libgcrypt_la_DEPENDENCIES = \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la \
+ $(srcdir)/libgcrypt.vers $(gcrypt_deps)
+libgcrypt_la_LIBADD = $(gcrypt_res) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la $(GPG_ERROR_LIBS)
+
+
+dumpsexp_SOURCES = dumpsexp.c
+dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
+
+hmac256_SOURCES = hmac256.c
+hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
+hmac256_LDADD = $(arch_gpg_error_libs)
+
+if USE_RANDOM_DAEMON
+gcryptrnd_SOURCES = gcryptrnd.c
+gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+
+getrandom_SOURCES = getrandom.c
+endif USE_RANDOM_DAEMON
+
+
+install-data-local: install-def-file
+
+uninstall-local: uninstall-def-file
+
+# FIXME: We need to figure out how to get the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without installing libgcrypt first.
+#install-exec-hook:
+# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \
+# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am - for gcrypt/src
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+# 2006, 2007 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = dumpsexp$(EXEEXT) hmac256$(EXEEXT) $(am__EXEEXT_1)
+@USE_RANDOM_DAEMON_TRUE@sbin_PROGRAMS = gcryptrnd$(EXEEXT)
+@USE_RANDOM_DAEMON_TRUE@am__append_1 = getrandom
+subdir = src
+DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/gcrypt.h.in \
+ $(srcdir)/libgcrypt-config.in $(srcdir)/versioninfo.rc.in \
+ ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = gcrypt.h libgcrypt-config versioninfo.rc
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(includedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+@HAVE_W32_SYSTEM_TRUE@am__DEPENDENCIES_1 = versioninfo.lo
+am__DEPENDENCIES_2 =
+am_libgcrypt_la_OBJECTS = libgcrypt_la-visibility.lo \
+ libgcrypt_la-misc.lo libgcrypt_la-global.lo \
+ libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo \
+ libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo \
+ libgcrypt_la-missing-string.lo libgcrypt_la-module.lo \
+ libgcrypt_la-fips.lo libgcrypt_la-hmac256.lo \
+ libgcrypt_la-ath.lo
+libgcrypt_la_OBJECTS = $(am_libgcrypt_la_OBJECTS)
+libgcrypt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgcrypt_la_CFLAGS) \
+ $(CFLAGS) $(libgcrypt_la_LDFLAGS) $(LDFLAGS) -o $@
+@USE_RANDOM_DAEMON_TRUE@am__EXEEXT_1 = getrandom$(EXEEXT)
+PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS)
+am_dumpsexp_OBJECTS = dumpsexp-dumpsexp.$(OBJEXT)
+dumpsexp_OBJECTS = $(am_dumpsexp_OBJECTS)
+@HAVE_W32CE_SYSTEM_TRUE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
+dumpsexp_DEPENDENCIES = $(am__DEPENDENCIES_3)
+dumpsexp_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(dumpsexp_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+am__gcryptrnd_SOURCES_DIST = gcryptrnd.c
+@USE_RANDOM_DAEMON_TRUE@am_gcryptrnd_OBJECTS = \
+@USE_RANDOM_DAEMON_TRUE@ gcryptrnd-gcryptrnd.$(OBJEXT)
+gcryptrnd_OBJECTS = $(am_gcryptrnd_OBJECTS)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_DEPENDENCIES = libgcrypt.la \
+@USE_RANDOM_DAEMON_TRUE@ $(am__DEPENDENCIES_2) \
+@USE_RANDOM_DAEMON_TRUE@ $(am__DEPENDENCIES_2)
+gcryptrnd_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gcryptrnd_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am__getrandom_SOURCES_DIST = getrandom.c
+@USE_RANDOM_DAEMON_TRUE@am_getrandom_OBJECTS = getrandom.$(OBJEXT)
+getrandom_OBJECTS = $(am_getrandom_OBJECTS)
+getrandom_LDADD = $(LDADD)
+am_hmac256_OBJECTS = hmac256-hmac256.$(OBJEXT)
+hmac256_OBJECTS = $(am_hmac256_OBJECTS)
+hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3)
+hmac256_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(hmac256_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libgcrypt_la_SOURCES) $(dumpsexp_SOURCES) \
+ $(gcryptrnd_SOURCES) $(getrandom_SOURCES) $(hmac256_SOURCES)
+DIST_SOURCES = $(libgcrypt_la_SOURCES) $(dumpsexp_SOURCES) \
+ $(am__gcryptrnd_SOURCES_DIST) $(am__getrandom_SOURCES_DIST) \
+ $(hmac256_SOURCES)
+DATA = $(m4data_DATA)
+HEADERS = $(include_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
+ gcrypt.h.in libgcrypt.def
+
+bin_SCRIPTS = libgcrypt-config
+m4datadir = $(datadir)/aclocal
+m4data_DATA = libgcrypt.m4
+include_HEADERS = gcrypt.h gcrypt-module.h
+lib_LTLIBRARIES = libgcrypt.la
+@HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_cflags =
+
+# Depending on the architecture some targets require libgpg-error.
+@HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
+@HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_libs =
+@HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+@HAVE_LD_VERSION_SCRIPT_FALSE@libgcrypt_version_script_cmd =
+@HAVE_LD_VERSION_SCRIPT_TRUE@libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
+libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
+libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
+ cipher.h cipher-proto.h \
+ misc.c global.c sexp.c hwfeatures.c \
+ stdmem.c stdmem.h secmem.c secmem.h \
+ mpi.h missing-string.c module.c fips.c \
+ hmac256.c hmac256.h \
+ ath.h ath.c
+
+@HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+@HAVE_W32_SYSTEM_TRUE@ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
+
+@HAVE_W32_SYSTEM_TRUE@LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE)
+@HAVE_W32_SYSTEM_TRUE@SUFFIXES = .rc .lo
+@HAVE_W32_SYSTEM_FALSE@gcrypt_res =
+@HAVE_W32_SYSTEM_TRUE@gcrypt_res = versioninfo.lo
+@HAVE_W32_SYSTEM_FALSE@no_undefined =
+@HAVE_W32_SYSTEM_TRUE@no_undefined = -no-undefined
+@HAVE_W32_SYSTEM_FALSE@export_symbols =
+@HAVE_W32_SYSTEM_TRUE@export_symbols = -export-symbols $(srcdir)/libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@gcrypt_deps =
+@HAVE_W32_SYSTEM_TRUE@gcrypt_deps = $(gcrypt_res) libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@gcrypt_res_ldflag =
+libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
+ $(libgcrypt_version_script_cmd) -version-info \
+ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
+
+libgcrypt_la_DEPENDENCIES = \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la \
+ $(srcdir)/libgcrypt.vers $(gcrypt_deps)
+
+libgcrypt_la_LIBADD = $(gcrypt_res) \
+ ../cipher/libcipher.la \
+ ../random/librandom.la \
+ ../mpi/libmpi.la \
+ ../compat/libcompat.la $(GPG_ERROR_LIBS)
+
+dumpsexp_SOURCES = dumpsexp.c
+dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
+dumpsexp_LDADD = $(arch_gpg_error_libs)
+hmac256_SOURCES = hmac256.c
+hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
+hmac256_LDADD = $(arch_gpg_error_libs)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_SOURCES = gcryptrnd.c
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+@USE_RANDOM_DAEMON_TRUE@getrandom_SOURCES = getrandom.c
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .rc .lo .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+gcrypt.h: $(top_builddir)/config.status $(srcdir)/gcrypt.h.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+libgcrypt-config: $(top_builddir)/config.status $(srcdir)/libgcrypt-config.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+versioninfo.rc: $(top_builddir)/config.status $(srcdir)/versioninfo.rc.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgcrypt.la: $(libgcrypt_la_OBJECTS) $(libgcrypt_la_DEPENDENCIES)
+ $(libgcrypt_la_LINK) -rpath $(libdir) $(libgcrypt_la_OBJECTS) $(libgcrypt_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+dumpsexp$(EXEEXT): $(dumpsexp_OBJECTS) $(dumpsexp_DEPENDENCIES)
+ @rm -f dumpsexp$(EXEEXT)
+ $(dumpsexp_LINK) $(dumpsexp_OBJECTS) $(dumpsexp_LDADD) $(LIBS)
+gcryptrnd$(EXEEXT): $(gcryptrnd_OBJECTS) $(gcryptrnd_DEPENDENCIES)
+ @rm -f gcryptrnd$(EXEEXT)
+ $(gcryptrnd_LINK) $(gcryptrnd_OBJECTS) $(gcryptrnd_LDADD) $(LIBS)
+getrandom$(EXEEXT): $(getrandom_OBJECTS) $(getrandom_DEPENDENCIES)
+ @rm -f getrandom$(EXEEXT)
+ $(LINK) $(getrandom_OBJECTS) $(getrandom_LDADD) $(LIBS)
+hmac256$(EXEEXT): $(hmac256_OBJECTS) $(hmac256_DEPENDENCIES)
+ @rm -f hmac256$(EXEEXT)
+ $(hmac256_LINK) $(hmac256_OBJECTS) $(hmac256_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dumpsexp-dumpsexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcryptrnd-gcryptrnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrandom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac256-hmac256.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-ath.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-fips.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-global.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hmac256.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-misc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-missing-string.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-module.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-secmem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-sexp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-stdmem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-visibility.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libgcrypt_la-visibility.lo: visibility.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-visibility.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-visibility.Tpo -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-visibility.Tpo $(DEPDIR)/libgcrypt_la-visibility.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='visibility.c' object='libgcrypt_la-visibility.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+
+libgcrypt_la-misc.lo: misc.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-misc.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-misc.Tpo -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-misc.Tpo $(DEPDIR)/libgcrypt_la-misc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='misc.c' object='libgcrypt_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+
+libgcrypt_la-global.lo: global.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-global.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-global.Tpo -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-global.Tpo $(DEPDIR)/libgcrypt_la-global.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='global.c' object='libgcrypt_la-global.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+
+libgcrypt_la-sexp.lo: sexp.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-sexp.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-sexp.Tpo -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-sexp.Tpo $(DEPDIR)/libgcrypt_la-sexp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sexp.c' object='libgcrypt_la-sexp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+
+libgcrypt_la-hwfeatures.lo: hwfeatures.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwfeatures.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo $(DEPDIR)/libgcrypt_la-hwfeatures.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hwfeatures.c' object='libgcrypt_la-hwfeatures.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+
+libgcrypt_la-stdmem.lo: stdmem.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-stdmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-stdmem.Tpo -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-stdmem.Tpo $(DEPDIR)/libgcrypt_la-stdmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='stdmem.c' object='libgcrypt_la-stdmem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+
+libgcrypt_la-secmem.lo: secmem.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-secmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-secmem.Tpo -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-secmem.Tpo $(DEPDIR)/libgcrypt_la-secmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='secmem.c' object='libgcrypt_la-secmem.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+
+libgcrypt_la-missing-string.lo: missing-string.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-missing-string.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-missing-string.Tpo -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-missing-string.Tpo $(DEPDIR)/libgcrypt_la-missing-string.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='missing-string.c' object='libgcrypt_la-missing-string.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
+
+libgcrypt_la-module.lo: module.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-module.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-module.Tpo -c -o libgcrypt_la-module.lo `test -f 'module.c' || echo '$(srcdir)/'`module.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-module.Tpo $(DEPDIR)/libgcrypt_la-module.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='module.c' object='libgcrypt_la-module.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-module.lo `test -f 'module.c' || echo '$(srcdir)/'`module.c
+
+libgcrypt_la-fips.lo: fips.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-fips.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-fips.Tpo -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-fips.Tpo $(DEPDIR)/libgcrypt_la-fips.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fips.c' object='libgcrypt_la-fips.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+
+libgcrypt_la-hmac256.lo: hmac256.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hmac256.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hmac256.Tpo -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-hmac256.Tpo $(DEPDIR)/libgcrypt_la-hmac256.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hmac256.c' object='libgcrypt_la-hmac256.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+
+libgcrypt_la-ath.lo: ath.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-ath.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-ath.Tpo -c -o libgcrypt_la-ath.lo `test -f 'ath.c' || echo '$(srcdir)/'`ath.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/libgcrypt_la-ath.Tpo $(DEPDIR)/libgcrypt_la-ath.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ath.c' object='libgcrypt_la-ath.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-ath.lo `test -f 'ath.c' || echo '$(srcdir)/'`ath.c
+
+dumpsexp-dumpsexp.o: dumpsexp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.o -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dumpsexp.c' object='dumpsexp-dumpsexp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+
+dumpsexp-dumpsexp.obj: dumpsexp.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.obj -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='dumpsexp.c' object='dumpsexp-dumpsexp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+
+gcryptrnd-gcryptrnd.o: gcryptrnd.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.o -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+
+gcryptrnd-gcryptrnd.obj: gcryptrnd.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.obj -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+
+hmac256-hmac256.o: hmac256.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.o -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hmac256.c' object='hmac256-hmac256.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+
+hmac256-hmac256.obj: hmac256.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.obj -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='hmac256.c' object='hmac256-hmac256.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-m4dataDATA: $(m4data_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)"
+ @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \
+ done
+
+uninstall-m4dataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(m4datadir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(m4datadir)" && rm -f $$files
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(includedir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+ $(HEADERS)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+ clean-libtool clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-includeHEADERS \
+ install-m4dataDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+ install-libLTLIBRARIES install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+ uninstall-includeHEADERS uninstall-libLTLIBRARIES \
+ uninstall-local uninstall-m4dataDATA uninstall-sbinPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic clean-libLTLIBRARIES clean-libtool \
+ clean-sbinPROGRAMS ctags distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-binPROGRAMS install-binSCRIPTS install-data \
+ install-data-am install-data-local install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-libLTLIBRARIES install-m4dataDATA install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-sbinPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-binSCRIPTS uninstall-includeHEADERS \
+ uninstall-libLTLIBRARIES uninstall-local uninstall-m4dataDATA \
+ uninstall-sbinPROGRAMS
+
+
+@HAVE_W32_SYSTEM_TRUE@.rc.lo:
+@HAVE_W32_SYSTEM_TRUE@ $(LTRCCOMPILE) -i "$<" -o "$@"
+
+@HAVE_W32_SYSTEM_TRUE@install-def-file:
+@HAVE_W32_SYSTEM_TRUE@ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
+
+@HAVE_W32_SYSTEM_TRUE@uninstall-def-file:
+@HAVE_W32_SYSTEM_TRUE@ -rm $(DESTDIR)$(libdir)/libgcrypt.def
+@HAVE_W32_SYSTEM_FALSE@install-def-file:
+@HAVE_W32_SYSTEM_FALSE@uninstall-def-file:
+
+install-data-local: install-def-file
+
+uninstall-local: uninstall-def-file
+
+# FIXME: We need to figure out how to get the actual name (parsing
+# libgcrypt.la?) and how to create the hmac file already at link time
+# so that it can be used without installing libgcrypt first.
+#install-exec-hook:
+# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \
+# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \
+# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+# Manifest - checksums of the src directory
+# Copyright 2004 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# Checksums for all source files in this directory. Format is
+# filename, blanks, base-64 part of an OpenPGP detached signature
+# without the header lines. Blank lines and lines beginning with a
+# hash mark are ignored. A tool to process this file is available by
+# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
+#
+# The special entry "$names$" holds a signature over all sorted
+# filenames excluding itself.
+
+gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz
+gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5
+
+ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3
+ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w
+
+cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW
+g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk
+mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf
+
+global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1
+misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2
+missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn
+module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD
+secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr
+secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE
+sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE
+stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ
+stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN
+
+types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3
+
+
+# Configuration
+Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun
+libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB
+libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS
+libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq
+
+$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z
--- /dev/null
+/* ath.c - Thread-safeness library.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with Libgcrypt; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h> /* Right: We need to use assert and not gcry_assert. */
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#else
+# include <sys/time.h>
+#endif
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/wait.h>
+#endif
+#include <errno.h>
+
+#include "ath.h"
+
+
+\f
+/* The interface table. */
+static struct ath_ops ops;
+
+/* True if we should use the external callbacks. */
+static int ops_set;
+
+
+/* For the dummy interface. */
+#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
+#define MUTEX_LOCKED ((ath_mutex_t) 1)
+#define MUTEX_DESTROYED ((ath_mutex_t) 2)
+
+
+/* Return the thread type from the option field. */
+#define GET_OPTION(a) ((a) & 0xff)
+/* Return the version number from the option field. */
+#define GET_VERSION(a) (((a) >> 8)& 0xff)
+
+
+\f
+/* The lock we take while checking for lazy lock initialization. */
+static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
+
+int
+ath_init (void)
+{
+ int err = 0;
+
+ if (ops_set)
+ {
+ if (ops.init)
+ err = (*ops.init) ();
+ if (err)
+ return err;
+ err = (*ops.mutex_init) (&check_init_lock);
+ }
+ return err;
+}
+
+
+/* Initialize the locking library. Returns 0 if the operation was
+ successful, EINVAL if the operation table was invalid and EBUSY if
+ we already were initialized. */
+gpg_err_code_t
+ath_install (struct ath_ops *ath_ops, int check_only)
+{
+ if (check_only)
+ {
+ unsigned int option = 0;
+
+ /* Check if the requested thread option is compatible to the
+ thread option we are already committed to. */
+ if (ath_ops)
+ option = ath_ops->option;
+
+ if (!ops_set && GET_OPTION (option))
+ return GPG_ERR_NOT_SUPPORTED;
+
+ if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER
+ || GET_OPTION (option) == ATH_THREAD_OPTION_USER
+ || GET_OPTION (ops.option) != GET_OPTION (option)
+ || GET_VERSION (ops.option) != GET_VERSION (option))
+ return GPG_ERR_NOT_SUPPORTED;
+
+ return 0;
+ }
+
+ if (ath_ops)
+ {
+ /* It is convenient to not require DESTROY. */
+ if (!ath_ops->mutex_init || !ath_ops->mutex_lock
+ || !ath_ops->mutex_unlock)
+ return GPG_ERR_INV_ARG;
+
+ ops = *ath_ops;
+ ops_set = 1;
+ }
+ else
+ ops_set = 0;
+
+ return 0;
+}
+
+
+static int
+mutex_init (ath_mutex_t *lock, int just_check)
+{
+ int err = 0;
+
+ if (just_check)
+ (*ops.mutex_lock) (&check_init_lock);
+ if (*lock == ATH_MUTEX_INITIALIZER || !just_check)
+ err = (*ops.mutex_init) (lock);
+ if (just_check)
+ (*ops.mutex_unlock) (&check_init_lock);
+ return err;
+}
+
+
+int
+ath_mutex_init (ath_mutex_t *lock)
+{
+ if (ops_set)
+ return mutex_init (lock, 0);
+
+#ifndef NDEBUG
+ *lock = MUTEX_UNLOCKED;
+#endif
+ return 0;
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+ if (ops_set)
+ {
+ if (!ops.mutex_destroy)
+ return 0;
+
+ (*ops.mutex_lock) (&check_init_lock);
+ if (*lock == ATH_MUTEX_INITIALIZER)
+ {
+ (*ops.mutex_unlock) (&check_init_lock);
+ return 0;
+ }
+ (*ops.mutex_unlock) (&check_init_lock);
+ return (*ops.mutex_destroy) (lock);
+ }
+
+#ifndef NDEBUG
+ assert (*lock == MUTEX_UNLOCKED);
+
+ *lock = MUTEX_DESTROYED;
+#endif
+ return 0;
+}
+
+
+int
+ath_mutex_lock (ath_mutex_t *lock)
+{
+ if (ops_set)
+ {
+ int ret = mutex_init (lock, 1);
+ if (ret)
+ return ret;
+ return (*ops.mutex_lock) (lock);
+ }
+
+#ifndef NDEBUG
+ assert (*lock == MUTEX_UNLOCKED);
+
+ *lock = MUTEX_LOCKED;
+#endif
+ return 0;
+}
+
+
+int
+ath_mutex_unlock (ath_mutex_t *lock)
+{
+ if (ops_set)
+ {
+ int ret = mutex_init (lock, 1);
+ if (ret)
+ return ret;
+ return (*ops.mutex_unlock) (lock);
+ }
+
+#ifndef NDEBUG
+ assert (*lock == MUTEX_LOCKED);
+
+ *lock = MUTEX_UNLOCKED;
+#endif
+ return 0;
+}
+
+
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
+{
+ if (ops_set && ops.read)
+ return (*ops.read) (fd, buf, nbytes);
+ else
+ return read (fd, buf, nbytes);
+}
+
+
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+ if (ops_set && ops.write)
+ return (*ops.write) (fd, buf, nbytes);
+ else
+ return write (fd, buf, nbytes);
+}
+
+
+ssize_t
+#ifdef _WIN32
+ath_select (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout)
+#else
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout)
+#endif
+{
+ if (ops_set && ops.select)
+ return (*ops.select) (nfd, rset, wset, eset, timeout);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return select (nfd, rset, wset, eset, timeout);
+#endif
+}
+
+
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+ if (ops_set && ops.waitpid)
+ return (*ops.waitpid) (pid, status, options);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return waitpid (pid, status, options);
+#endif
+}
+
+
+int
+#ifdef _WIN32
+ath_accept (int s, void *addr, int *length_ptr)
+#else
+ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
+#endif
+{
+ if (ops_set && ops.accept)
+ return (*ops.accept) (s, addr, length_ptr);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return accept (s, addr, length_ptr);
+#endif
+}
+
+
+int
+#ifdef _WIN32
+ath_connect (int s, void *addr, int length)
+#else
+ath_connect (int s, struct sockaddr *addr, socklen_t length)
+#endif
+{
+ if (ops_set && ops.connect)
+ return (*ops.connect) (s, addr, length);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return connect (s, addr, length);
+#endif
+}
+
+
+int
+#ifdef _WIN32
+ath_sendmsg (int s, const void *msg, int flags)
+#else
+ath_sendmsg (int s, const struct msghdr *msg, int flags)
+#endif
+{
+ if (ops_set && ops.sendmsg)
+ return (*ops.sendmsg) (s, msg, flags);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return sendmsg (s, msg, flags);
+#endif
+}
+
+
+int
+#ifdef _WIN32
+ath_recvmsg (int s, void *msg, int flags)
+#else
+ath_recvmsg (int s, struct msghdr *msg, int flags)
+#endif
+{
+ if (ops_set && ops.recvmsg)
+ return (*ops.recvmsg) (s, msg, flags);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return recvmsg (s, msg, flags);
+#endif
+}
--- /dev/null
+/* ath.h - Thread-safeness library.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with Libgcrypt; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
+
+#ifndef ATH_H
+#define ATH_H
+
+#include <config.h>
+
+#ifdef _WIN32
+# include <windows.h>
+#else /* !_WIN32 */
+# ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+# else
+# include <sys/time.h>
+# endif
+# include <sys/types.h>
+# ifdef HAVE_SYS_MSG_H
+# include <sys/msg.h> /* (e.g. for zOS) */
+# endif
+# include <sys/socket.h>
+#endif /* !_WIN32 */
+#include <gpg-error.h>
+
+
+\f
+/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols
+ a prefix. */
+#define _ATH_EXT_SYM_PREFIX _gcry_
+
+#ifdef _ATH_EXT_SYM_PREFIX
+#define _ATH_PREFIX1(x,y) x ## y
+#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y)
+#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
+#define ath_install _ATH_PREFIX(ath_install)
+#define ath_init _ATH_PREFIX(ath_init)
+#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
+#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
+#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
+#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
+#define ath_read _ATH_PREFIX(ath_read)
+#define ath_write _ATH_PREFIX(ath_write)
+#define ath_select _ATH_PREFIX(ath_select)
+#define ath_waitpid _ATH_PREFIX(ath_waitpid)
+#define ath_connect _ATH_PREFIX(ath_connect)
+#define ath_accept _ATH_PREFIX(ath_accept)
+#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
+#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
+#endif
+
+\f
+enum ath_thread_option
+ {
+ ATH_THREAD_OPTION_DEFAULT = 0,
+ ATH_THREAD_OPTION_USER = 1,
+ ATH_THREAD_OPTION_PTH = 2,
+ ATH_THREAD_OPTION_PTHREAD = 3
+ };
+
+struct ath_ops
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number.
+ */
+ unsigned int option;
+
+ int (*init) (void);
+ int (*mutex_init) (void **priv);
+ int (*mutex_destroy) (void *priv);
+ int (*mutex_lock) (void *priv);
+ int (*mutex_unlock) (void *priv);
+ ssize_t (*read) (int fd, void *buf, size_t nbytes);
+ ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, void *addr, int *length_ptr);
+ int (*connect) (int s, void *addr, int length);
+ int (*sendmsg) (int s, const void *msg, int flags);
+ int (*recvmsg) (int s, void *msg, int flags);
+#else
+ ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
+ int (*connect) (int s, struct sockaddr *addr, socklen_t length);
+ int (*sendmsg) (int s, const struct msghdr *msg, int flags);
+ int (*recvmsg) (int s, struct msghdr *msg, int flags);
+#endif
+};
+
+gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only);
+int ath_init (void);
+
+
+/* Functions for mutual exclusion. */
+typedef void *ath_mutex_t;
+#define ATH_MUTEX_INITIALIZER 0
+
+int ath_mutex_init (ath_mutex_t *mutex);
+int ath_mutex_destroy (ath_mutex_t *mutex);
+int ath_mutex_lock (ath_mutex_t *mutex);
+int ath_mutex_unlock (ath_mutex_t *mutex);
+
+/* Replacement for the POSIX functions, which can be used to allow
+ other (user-level) threads to run. */
+ssize_t ath_read (int fd, void *buf, size_t nbytes);
+ssize_t ath_write (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ssize_t ath_select (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+int ath_accept (int s, void *addr, int *length_ptr);
+int ath_connect (int s, void *addr, int length);
+int ath_sendmsg (int s, const void *msg, int flags);
+int ath_recvmsg (int s, void *msg, int flags);
+#else
+ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
+int ath_connect (int s, struct sockaddr *addr, socklen_t length);
+int ath_sendmsg (int s, const struct msghdr *msg, int flags);
+int ath_recvmsg (int s, struct msghdr *msg, int flags);
+#endif
+
+#endif /* ATH_H */
--- /dev/null
+/* cipher-proto.h - Internal declarations
+ * Copyright (C) 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file has been factored out from cipher.h so that it can be
+ used standalone in visibility.c . */
+
+#ifndef G10_CIPHER_PROTO_H
+#define G10_CIPHER_PROTO_H
+
+/* Definition of a function used to report selftest failures.
+ DOMAIN is a string describing the function block:
+ "cipher", "digest", "pubkey or "random",
+ ALGO is the algorithm under test,
+ WHAT is a string describing what has been tested,
+ DESC is a string describing the error. */
+typedef void (*selftest_report_func_t)(const char *domain,
+ int algo,
+ const char *what,
+ const char *errdesc);
+
+/* Definition of the selftest functions. */
+typedef gpg_err_code_t (*selftest_func_t)
+ (int algo, int extended, selftest_report_func_t report);
+
+
+/* An extended type of the generate function. */
+typedef gcry_err_code_t (*pk_ext_generate_t)
+ (int algo,
+ unsigned int nbits,
+ unsigned long evalue,
+ gcry_sexp_t genparms,
+ gcry_mpi_t *skey,
+ gcry_mpi_t **retfactors,
+ gcry_sexp_t *extrainfo);
+
+/* The type used to compute the keygrip. */
+typedef gpg_err_code_t (*pk_comp_keygrip_t)
+ (gcry_md_hd_t md, gcry_sexp_t keyparm);
+
+/* The type used to query ECC curve parameters. */
+typedef gcry_err_code_t (*pk_get_param_t)
+ (const char *name, gcry_mpi_t *pkey);
+
+/* The type used to query an ECC curve name. */
+typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
+ unsigned int *r_nbits);
+
+/* The type used to query ECC curve parameters by name. */
+typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
+
+/* The type used to convey additional information to a cipher. */
+typedef gpg_err_code_t (*cipher_set_extra_info_t)
+ (void *c, int what, const void *buffer, size_t buflen);
+
+
+/* Extra module specification structures. These are used for internal
+ modules which provide more functions than available through the
+ public algorithm register APIs. */
+typedef struct cipher_extra_spec
+{
+ selftest_func_t selftest;
+ cipher_set_extra_info_t set_extra_info;
+} cipher_extra_spec_t;
+
+typedef struct md_extra_spec
+{
+ selftest_func_t selftest;
+} md_extra_spec_t;
+
+typedef struct pk_extra_spec
+{
+ selftest_func_t selftest;
+ pk_ext_generate_t ext_generate;
+ pk_comp_keygrip_t comp_keygrip;
+ pk_get_param_t get_param;
+ pk_get_curve_t get_curve;
+ pk_get_curve_param_t get_curve_param;
+} pk_extra_spec_t;
+
+
+
+/* The private register functions. */
+gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher,
+ cipher_extra_spec_t *extraspec,
+ int *algorithm_id,
+ gcry_module_t *module);
+gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
+ md_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module);
+gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
+ pk_extra_spec_t *extraspec,
+ unsigned int *algorithm_id,
+ gcry_module_t *module);
+
+/* The selftest functions. */
+gcry_error_t _gcry_cipher_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_md_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_pk_selftest (int algo, int extended,
+ selftest_report_func_t report);
+gcry_error_t _gcry_hmac_selftest (int algo, int extended,
+ selftest_report_func_t report);
+
+gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
+
+#endif /*G10_CIPHER_PROTO_H*/
--- /dev/null
+/* cipher.h
+ * Copyright (C) 1998, 2002, 2003, 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+#ifndef G10_CIPHER_H
+#define G10_CIPHER_H
+
+#include <gcrypt.h>
+
+#define DBG_CIPHER _gcry_get_debug_flag( 1 )
+
+#include "../random/random.h"
+
+#define PUBKEY_FLAG_NO_BLINDING (1 << 0)
+
+enum pk_operation
+ {
+ PUBKEY_OP_ENCRYPT,
+ PUBKEY_OP_DECRYPT,
+ PUBKEY_OP_SIGN,
+ PUBKEY_OP_VERIFY
+ };
+
+enum pk_encoding
+ {
+ PUBKEY_ENC_RAW,
+ PUBKEY_ENC_PKCS1,
+ PUBKEY_ENC_OAEP,
+ PUBKEY_ENC_PSS,
+ PUBKEY_ENC_UNKNOWN
+ };
+
+struct pk_encoding_ctx
+{
+ enum pk_operation op;
+ unsigned int nbits;
+
+ enum pk_encoding encoding;
+ int flags;
+
+ int hash_algo;
+
+ /* for OAEP */
+ unsigned char *label;
+ size_t labellen;
+
+ /* for PSS */
+ size_t saltlen;
+
+ int (* verify_cmp) (void *opaque, gcry_mpi_t tmp);
+ void *verify_arg;
+};
+
+#define CIPHER_INFO_NO_WEAK_KEY 1
+
+#include "cipher-proto.h"
+
+
+/*-- rmd160.c --*/
+void _gcry_rmd160_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+/*-- sha1.c --*/
+void _gcry_sha1_hash_buffer (void *outbuf,
+ const void *buffer, size_t length);
+
+/*-- rijndael.c --*/
+void _gcry_aes_cfb_enc (void *context, unsigned char *iv,
+ void *outbuf, const void *inbuf,
+ unsigned int nblocks);
+void _gcry_aes_cfb_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+void _gcry_aes_cbc_enc (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks, int cbc_mac);
+void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+
+
+/*-- dsa.c --*/
+void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
+
+/*-- elgamal.c --*/
+void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+
+/*-- ecc.c --*/
+void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc,
+ void *cb_data);
+
+
+/*-- primegen.c --*/
+void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
+ void *cb_data);
+
+/*-- pubkey.c --*/
+const char * _gcry_pk_aliased_algo_name (int algorithm);
+
+/* Declarations for the cipher specifications. */
+extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_des;
+extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour;
+extern gcry_cipher_spec_t _gcry_cipher_spec_cast5;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_aes256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish;
+extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
+extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
+extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
+
+extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192;
+extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256;
+
+
+/* Declarations for the digest specifications. */
+extern gcry_md_spec_t _gcry_digest_spec_crc32;
+extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510;
+extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440;
+extern gcry_md_spec_t _gcry_digest_spec_md4;
+extern gcry_md_spec_t _gcry_digest_spec_md5;
+extern gcry_md_spec_t _gcry_digest_spec_rmd160;
+extern gcry_md_spec_t _gcry_digest_spec_sha1;
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
+extern gcry_md_spec_t _gcry_digest_spec_sha256;
+extern gcry_md_spec_t _gcry_digest_spec_sha512;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
+extern gcry_md_spec_t _gcry_digest_spec_tiger;
+extern gcry_md_spec_t _gcry_digest_spec_tiger1;
+extern gcry_md_spec_t _gcry_digest_spec_tiger2;
+extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
+
+extern md_extra_spec_t _gcry_digest_extraspec_sha1;
+extern md_extra_spec_t _gcry_digest_extraspec_sha224;
+extern md_extra_spec_t _gcry_digest_extraspec_sha256;
+extern md_extra_spec_t _gcry_digest_extraspec_sha384;
+extern md_extra_spec_t _gcry_digest_extraspec_sha512;
+
+/* Declarations for the pubkey cipher specifications. */
+extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;
+
+extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_elg;
+extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa;
+
+
+#endif /*G10_CIPHER_H*/
--- /dev/null
+/* dumpsexp.c - Dump S-expressions.
+ * Copyright (C) 2007, 2010 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 3 of the License,
+ * or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <errno.h>
+/* For a native WindowsCE binary we need to include gpg-error.h to
+ provide a replacement for strerror. */
+#ifdef __MINGW32CE__
+# include <gpg-error.h>
+#endif
+
+#define PGM "dumpsexp"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static int verbose; /* Verbose mode. */
+static int decimal; /* Print addresses in decimal. */
+static int assume_hex; /* Assume input is hexencoded. */
+static int advanced; /* Advanced format output. */
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2010 Free Software Foundation, Inc.\n"
+ "License GPLv3+: GNU GPL version 3 or later "
+ "<http://gnu.org/licenses/gpl.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [file]\n"
+ "Debug tool for S-expressions\n"
+ "\n"
+ " --decimal Print offsets using decimal notation\n"
+ " --assume-hex Assume input is a hex dump\n"
+ " --advanced Print file in advanced format\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
+#define digit_p(a) ((a) >= '0' && (a) <= '9')
+#define octdigit_p(a) ((a) >= '0' && (a) <= '7')
+#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \
+ || ((a) >= 'a' && (a) <= 'z'))
+#define hexdigit_p(a) (digit_p (a) \
+ || ((a) >= 'A' && (a) <= 'F') \
+ || ((a) >= 'a' && (a) <= 'f'))
+#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \
+ (a) <= 'F'? ((a)-'A'+10):((a)-'a'+10))
+
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+static inline int
+whitespace_p (int c)
+{
+ switch (c)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+/* The raw data buffer and its current length */
+static unsigned char databuffer[16];
+static int databufferlen;
+/* The number of bytes in databuffer which should be skipped at a flush. */
+static int skipdatabufferlen;
+/* The number of raw bytes printed on the last line. */
+static int nbytesprinted;
+/* The file offset of the current data buffer . */
+static unsigned long databufferoffset;
+
+
+
+static int
+my_getc (FILE *fp)
+{
+ int c1, c2;
+
+ if (!assume_hex)
+ return getc (fp);
+
+ while ( (c1=getc (fp)) != EOF && space_p (c1) )
+ ;
+ if (c1 == EOF)
+ return EOF;
+
+ if (!hexdigit_p (c1))
+ {
+ logit ("non hex-digit encountered\n");
+ return EOF;
+ }
+
+ while ( (c2=getc (fp)) != EOF && space_p (c2) )
+ ;
+ if (c2 == EOF)
+ {
+ logit ("error reading second hex nibble\n");
+ return EOF;
+ }
+ if (!hexdigit_p (c2))
+ {
+ logit ("second hex nibble is not a hex-digit\n");
+ return EOF;
+ }
+ return xtoi_1 (c1) * 16 + xtoi_1 (c2);
+}
+
+
+
+
+
+/* Flush the raw data buffer. */
+static void
+flushdatabuffer (void)
+{
+ int i;
+
+ if (!databufferlen)
+ return;
+ nbytesprinted = 0;
+ if (decimal)
+ printf ("%08lu ", databufferoffset);
+ else
+ printf ("%08lx ", databufferoffset);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i < skipdatabufferlen)
+ fputs (" ", stdout);
+ else
+ {
+ printf (" %02x", databuffer[i]);
+ databufferoffset++;
+ }
+ nbytesprinted++;
+ }
+ for (; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ fputs (" ", stdout);
+ }
+ fputs (" |", stdout);
+ for (i=0; i < databufferlen; i++)
+ {
+ if (i < skipdatabufferlen)
+ putchar (' ');
+ else if (databuffer[i] >= ' ' && databuffer[i] <= '~'
+ && databuffer[i] != '|')
+ putchar (databuffer[i]);
+ else
+ putchar ('.');
+ }
+ putchar ('|');
+ putchar ('\n');
+ databufferlen = 0;
+ skipdatabufferlen = 0;
+}
+
+
+/* Add C to the raw data buffer and flush as needed. */
+static void
+addrawdata (int c)
+{
+ if ( databufferlen >= sizeof databuffer )
+ flushdatabuffer ();
+ databuffer[databufferlen++] = c;
+}
+
+
+static void
+printcursor (int both)
+{
+ int i;
+
+ flushdatabuffer ();
+ printf ("%8s ", "");
+ for (i=0; i < sizeof (databuffer); i++)
+ {
+ if (i == 8)
+ putchar (' ');
+ if (i+1 == nbytesprinted)
+ {
+ fputs (" ^ ", stdout);
+ if (!both)
+ break;
+ }
+ else
+ fputs (" ", stdout);
+ }
+ if (both)
+ {
+ fputs (" ", stdout);
+ for (i=0; i < nbytesprinted-1; i++)
+ putchar (' ');
+ putchar ('^');
+ }
+ databufferlen = skipdatabufferlen = nbytesprinted;
+}
+
+static void
+printerr (const char *text)
+{
+ printcursor (1);
+ printf ("\n Error: %s\n", text);
+}
+
+static void
+printctl (const char *text)
+{
+ if (verbose && !advanced)
+ {
+ printcursor (0);
+ printf ("%s\n", text);
+ }
+}
+
+static void
+printchr (int c)
+{
+ putchar (c);
+}
+
+/* static void */
+/* printhex (int c) */
+/* { */
+/* printf ("\\x%02x", c); */
+/* } */
+
+
+#if 0
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+gcry_sexp_sprint (const gcry_sexp_t list,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if (indent)
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ putchar ('(');
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ putchar (')');
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP)
+ {
+ putchar ('\n');
+ for (i=0; i < indent; i++)
+ putchar (' ');
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy (&n, s, sizeof n);
+ s += sizeof n;
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ if (s[n] != ST_CLOSE)
+ putchar (' ');
+ }
+ else
+ {
+ snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
+ d = stpcpy (d, numbuf);
+ memcpy (d, s, n);
+ d += n;
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ putchar ('\n');
+ return len;
+}
+#endif
+
+
+/* Prepare for saving a chunk of data. */
+static void
+init_data (void)
+{
+
+}
+
+/* Push C on the current data chunk. */
+static void
+push_data (int c)
+{
+ (void)c;
+}
+
+/* Flush and thus print the current data chunk. */
+static void
+flush_data (void)
+{
+
+}
+
+
+/* Returns 0 on success. */
+static int
+parse_and_print (FILE *fp)
+{
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ int c;
+ int level = 0;
+ int tokenc = 0;
+ int hexcount = 0;
+ int disphint = 0;
+ unsigned long datalen = 0;
+ char quote_buf[10];
+ int quote_idx = 0;
+ enum
+ {
+ INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING,
+ IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC,
+ CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64
+ }
+ state = INIT_STATE;
+
+
+ while ((c = my_getc (fp)) != EOF )
+ {
+ addrawdata (c);
+ switch (state)
+ {
+ case INIT_STATE:
+ if (tokenc)
+ {
+ if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ continue;
+ }
+ tokenc = 0;
+ }
+ parse_init_state:
+ if (c == '(')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("open");
+ level++;
+ }
+ else if (c == ')')
+ {
+ if (disphint)
+ {
+ printerr ("unmatched display hint");
+ disphint = 0;
+ }
+ printctl ("close");
+ level--;
+ }
+ else if (c == '\"')
+ {
+ state = IN_STRING;
+ printctl ("beginstring");
+ init_data ();
+ }
+ else if (c == '#')
+ {
+ state = IN_HEXFMT;
+ hexcount = 0;
+ printctl ("beginhex");
+ init_data ();
+ }
+ else if (c == '|')
+ {
+ state = IN_BASE64;
+ printctl ("beginbase64");
+ init_data ();
+ }
+ else if (c == '[')
+ {
+ if (disphint)
+ printerr ("nested display hint");
+ disphint = c;
+ }
+ else if (c == ']')
+ {
+ if (!disphint)
+ printerr ("no open display hint");
+ disphint = 0;
+ }
+ else if (c >= '0' && c <= '9')
+ {
+ if (c == '0')
+ printerr ("zero prefixed length");
+ state = IN_NUMBER;
+ datalen = (c - '0');
+ }
+ else if (strchr (tokenchars, c))
+ {
+ printchr (c);
+ tokenc = c;
+ }
+ else if (whitespace_p (c))
+ ;
+ else if (c == '{')
+ {
+ printerr ("rescanning is not supported");
+ }
+ else if (c == '&' || c == '\\')
+ {
+ printerr ("reserved punctuation detected");
+ }
+ else
+ {
+ printerr ("bad character detected");
+ }
+ break;
+
+ case IN_NUMBER:
+ if (digit_p (c))
+ {
+ unsigned long tmp = datalen * 10 + (c - '0');
+ if (tmp < datalen)
+ {
+ printerr ("overflow in data length");
+ state = INIT_STATE;
+ datalen = 0;
+ }
+ else
+ datalen = tmp;
+ }
+ else if (c == ':')
+ {
+ if (!datalen)
+ {
+ printerr ("no data length");
+ state = INIT_STATE;
+ }
+ else
+ state = PRE_DATA;
+ }
+ else if (c == '\"' || c == '#' || c == '|' )
+ {
+ /* We ignore the optional length and divert to the init
+ state parser code. */
+ goto parse_init_state;
+ }
+ else
+ printerr ("invalid length specification");
+ break;
+
+ case PRE_DATA:
+ state = IN_DATA;
+ printctl ("begindata");
+ init_data ();
+ case IN_DATA:
+ if (datalen)
+ {
+ push_data (c);
+ datalen--;
+ }
+ if (!datalen)
+ {
+ state = INIT_STATE;
+ printctl ("enddata");
+ flush_data ();
+ }
+ break;
+
+ case IN_STRING:
+ if (c == '\"')
+ {
+ printctl ("endstring");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (c == '\\')
+ state = IN_ESCAPE;
+ else
+ push_data (c);
+ break;
+
+ case IN_ESCAPE:
+ switch (c)
+ {
+ case 'b': push_data ('\b'); state = IN_STRING; break;
+ case 't': push_data ('\t'); state = IN_STRING; break;
+ case 'v': push_data ('\v'); state = IN_STRING; break;
+ case 'n': push_data ('\n'); state = IN_STRING; break;
+ case 'f': push_data ('\f'); state = IN_STRING; break;
+ case 'r': push_data ('\r'); state = IN_STRING; break;
+ case '"': push_data ('"'); state = IN_STRING; break;
+ case '\'': push_data ('\''); state = IN_STRING; break;
+ case '\\': push_data ('\\'); state = IN_STRING; break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ state = IN_OCT_ESC;
+ quote_idx = 0;
+ quote_buf[quote_idx++] = c;
+ break;
+
+ case 'x':
+ state = IN_HEX_ESC;
+ quote_idx = 0;
+ break;
+
+ case '\r':
+ state = CR_ESC;
+ break;
+
+ case '\n':
+ state = LF_ESC;
+ break;
+
+ default:
+ printerr ("invalid escape sequence");
+ state = IN_STRING;
+ break;
+ }
+ break;
+
+ case IN_OCT_ESC:
+ if (quote_idx < 3 && strchr ("01234567", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 3)
+ {
+ push_data ((unsigned int)quote_buf[0] * 8 * 8
+ + (unsigned int)quote_buf[1] * 8
+ + (unsigned int)quote_buf[2]);
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case IN_HEX_ESC:
+ if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c))
+ {
+ quote_buf[quote_idx++] = c;
+ if (quote_idx == 2)
+ {
+ push_data (xtoi_1 (quote_buf[0]) * 16
+ + xtoi_1 (quote_buf[1]));
+ state = IN_STRING;
+ }
+ }
+ else
+ state = IN_STRING;
+ break;
+ case CR_ESC:
+ state = IN_STRING;
+ break;
+ case LF_ESC:
+ state = IN_STRING;
+ break;
+
+ case IN_HEXFMT:
+ if (hexdigit_p (c))
+ {
+ push_data (c);
+ hexcount++;
+ }
+ else if (c == '#')
+ {
+ if ((hexcount & 1))
+ printerr ("odd number of hex digits");
+ printctl ("endhex");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else if (!whitespace_p (c))
+ printerr ("bad hex character");
+ break;
+
+ case IN_BASE64:
+ if (c == '|')
+ {
+ printctl ("endbase64");
+ flush_data ();
+ state = INIT_STATE;
+ }
+ else
+ push_data (c);
+ break;
+
+ default:
+ logit ("invalid state %d detected", state);
+ exit (1);
+ }
+ }
+ flushdatabuffer ();
+ if (ferror (fp))
+ {
+ logit ("error reading input: %s\n", strerror (errno));
+ return -1;
+ }
+ return 0;
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int rc;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else if (!strcmp (*argv, "--decimal"))
+ {
+ argc--; argv++;
+ decimal = 1;
+ }
+ else if (!strcmp (*argv, "--assume-hex"))
+ {
+ argc--; argv++;
+ assume_hex = 1;
+ }
+ else if (!strcmp (*argv, "--advanced"))
+ {
+ argc--; argv++;
+ advanced = 1;
+ }
+ else
+ print_usage ();
+ }
+
+ if (!argc)
+ {
+ rc = parse_and_print (stdin);
+ }
+ else
+ {
+ rc = 0;
+ for (; argc; argv++, argc--)
+ {
+ FILE *fp = fopen (*argv, "rb");
+ if (!fp)
+ {
+ logit ("can't open `%s': %s\n", *argv, strerror (errno));
+ rc = 1;
+ }
+ else
+ {
+ if (parse_and_print (fp))
+ rc = 1;
+ fclose (fp);
+ }
+ }
+ }
+
+ return !!rc;
+}
--- /dev/null
+/* fips.c - FIPS mode management
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#ifdef ENABLE_HMAC_BINARY_CHECK
+# include <dlfcn.h>
+#endif
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "ath.h"
+#include "cipher-proto.h"
+#include "hmac256.h"
+
+
+/* The name of the file used to foce libgcrypt into fips mode. */
+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
+
+
+/* The states of the finite state machine used in fips mode. */
+enum module_states
+ {
+ /* POWEROFF cannot be represented. */
+ STATE_POWERON = 0,
+ STATE_INIT,
+ STATE_SELFTEST,
+ STATE_OPERATIONAL,
+ STATE_ERROR,
+ STATE_FATALERROR,
+ STATE_SHUTDOWN
+ };
+
+
+/* Flag telling whether we are in fips mode. It uses inverse logic so
+ that fips mode is the default unless changed by the initialization
+ code. To check whether fips mode is enabled, use the function
+ fips_mode()! */
+static int no_fips_mode_required;
+
+/* Flag to indicate that we are in the enforced FIPS mode. */
+static int enforced_fips_mode;
+
+/* If this flag is set, the application may no longer assume that the
+ process is running in FIPS mode. This flag is protected by the
+ FSM_LOCK. */
+static int inactive_fips_mode;
+
+/* This is the lock we use to protect the FSM. */
+static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER;
+
+/* The current state of the FSM. The whole state machinery is only
+ used while in fips mode. Change this only while holding fsm_lock. */
+static enum module_states current_state;
+
+
+
+
+\f
+static void fips_new_state (enum module_states new_state);
+
+
+\f
+/* Convert lowercase hex digits; assumes valid hex digits. */
+#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10))
+#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1))
+
+/* Returns true if P points to a lowercase hex digit. */
+#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
+
+
+\f
+/* Check whether the OS is in FIPS mode and record that in a module
+ local variable. If FORCE is passed as true, fips mode will be
+ enabled anyway. Note: This function is not thread-safe and should
+ be called before any threads are created. This function may only
+ be called once. */
+void
+_gcry_initialize_fips_mode (int force)
+{
+ static int done;
+ gpg_error_t err;
+
+ /* Make sure we are not accidently called twice. */
+ if (done)
+ {
+ if ( fips_mode () )
+ {
+ fips_new_state (STATE_FATALERROR);
+ fips_noreturn ();
+ }
+ /* If not in fips mode an assert is sufficient. */
+ gcry_assert (!done);
+ }
+ done = 1;
+
+ /* If the calling application explicitly requested fipsmode, do so. */
+ if (force)
+ {
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+
+ /* For testing the system it is useful to override the system
+ provided detection of the FIPS mode and force FIPS mode using a
+ file. The filename is hardwired so that there won't be any
+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
+ actually used. The file itself may be empty. */
+ if ( !access (FIPS_FORCE_FILE, F_OK) )
+ {
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+
+ /* Checking based on /proc file properties. */
+ {
+ static const char procfname[] = "/proc/sys/crypto/fips_enabled";
+ FILE *fp;
+ int saved_errno;
+
+ fp = fopen (procfname, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ {
+ /* System is in fips mode. */
+ fclose (fp);
+ gcry_assert (!no_fips_mode_required);
+ goto leave;
+ }
+ fclose (fp);
+ }
+ else if ((saved_errno = errno) != ENOENT
+ && saved_errno != EACCES
+ && !access ("/proc/version", F_OK) )
+ {
+ /* Problem reading the fips file despite that we have the proc
+ file system. We better stop right away. */
+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
+ procfname, strerror (saved_errno));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "reading `%s' failed: %s - abort",
+ procfname, strerror (saved_errno));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+ }
+
+ /* Fips not not requested, set flag. */
+ no_fips_mode_required = 1;
+
+ leave:
+ if (!no_fips_mode_required)
+ {
+ /* Yes, we are in FIPS mode. */
+ FILE *fp;
+
+ /* Intitialize the lock to protect the FSM. */
+ err = ath_mutex_init (&fsm_lock);
+ if (err)
+ {
+ /* If that fails we can't do anything but abort the
+ process. We need to use log_info so that the FSM won't
+ get involved. */
+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "creating FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+
+
+ /* If the FIPS force files exists, is readable and has a number
+ != 0 on its first line, we enable the enforced fips mode. */
+ fp = fopen (FIPS_FORCE_FILE, "r");
+ if (fp)
+ {
+ char line[256];
+
+ if (fgets (line, sizeof line, fp) && atoi (line))
+ enforced_fips_mode = 1;
+ fclose (fp);
+ }
+
+ /* Now get us into the INIT state. */
+ fips_new_state (STATE_INIT);
+
+ }
+ return;
+}
+
+static void
+lock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = ath_mutex_lock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "acquiring FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+static void
+unlock_fsm (void)
+{
+ gpg_error_t err;
+
+ err = ath_mutex_unlock (&fsm_lock);
+ if (err)
+ {
+ log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
+ strerror (err));
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "releasing FSM lock failed: %s - abort",
+ strerror (err));
+#endif /*HAVE_SYSLOG*/
+ abort ();
+ }
+}
+
+
+/* This function returns true if fips mode is enabled. This is
+ independent of the fips required finite state machine and only used
+ to enable fips specific code. Please use the fips_mode macro
+ instead of calling this function directly. */
+int
+_gcry_fips_mode (void)
+{
+ /* No locking is required because we have the requirement that this
+ variable is only initialized once with no other threads
+ existing. */
+ return !no_fips_mode_required;
+}
+
+
+/* Return a flag telling whether we are in the enforced fips mode. */
+int
+_gcry_enforced_fips_mode (void)
+{
+ return enforced_fips_mode;
+}
+
+
+/* If we do not want to enforce the fips mode, we can set a flag so
+ that the application may check whether it is still in fips mode.
+ TEXT will be printed as part of a syslog message. This function
+ may only be be called if in fips mode. */
+void
+_gcry_inactivate_fips_mode (const char *text)
+{
+ gcry_assert (_gcry_fips_mode ());
+
+ if (_gcry_enforced_fips_mode () )
+ {
+ /* Get us into the error state. */
+ fips_signal_error (text);
+ return;
+ }
+
+ lock_fsm ();
+ if (!inactive_fips_mode)
+ {
+ inactive_fips_mode = 1;
+ unlock_fsm ();
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "%s - FIPS mode inactivated", text);
+#endif /*HAVE_SYSLOG*/
+ }
+ else
+ unlock_fsm ();
+}
+
+
+/* Return the FIPS mode inactive flag. If it is true the FIPS mode is
+ not anymore active. */
+int
+_gcry_is_fips_mode_inactive (void)
+{
+ int flag;
+
+ if (!_gcry_fips_mode ())
+ return 0;
+ lock_fsm ();
+ flag = inactive_fips_mode;
+ unlock_fsm ();
+ return flag;
+}
+
+
+
+static const char *
+state2str (enum module_states state)
+{
+ const char *s;
+
+ switch (state)
+ {
+ case STATE_POWERON: s = "Power-On"; break;
+ case STATE_INIT: s = "Init"; break;
+ case STATE_SELFTEST: s = "Self-Test"; break;
+ case STATE_OPERATIONAL: s = "Operational"; break;
+ case STATE_ERROR: s = "Error"; break;
+ case STATE_FATALERROR: s = "Fatal-Error"; break;
+ case STATE_SHUTDOWN: s = "Shutdown"; break;
+ default: s = "?"; break;
+ }
+ return s;
+}
+
+
+/* Return true if the library is in the operational state. */
+int
+_gcry_fips_is_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ if (current_state == STATE_INIT)
+ {
+ /* If we are still in the INIT state, we need to run the
+ selftests so that the FSM can eventually get into
+ operational state. Given that we would need a 2-phase
+ initialization of libgcrypt, but that has traditionally
+ not been enforced, we use this on demand self-test
+ checking. Note that Proper applications would do the
+ application specific libgcrypt initialization between a
+ gcry_check_version() and gcry_control
+ (GCRYCTL_INITIALIZATION_FINISHED) where the latter will
+ run the selftests. The drawback of these on-demand
+ self-tests are a small chance that self-tests are
+ performed by severeal threads; that is no problem because
+ our FSM make sure that we won't oversee any error. */
+ unlock_fsm ();
+ _gcry_fips_run_selftests (0);
+ lock_fsm ();
+ }
+
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is test on whether the library is in the operational state. In
+ contrast to _gcry_fips_is_operational this function won't do a
+ state transition on the fly. */
+int
+_gcry_fips_test_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+/* This is a test on whether the library is in the error or
+ operational state. */
+int
+_gcry_fips_test_error_or_operational (void)
+{
+ int result;
+
+ if (!fips_mode ())
+ result = 1;
+ else
+ {
+ lock_fsm ();
+ result = (current_state == STATE_OPERATIONAL
+ || current_state == STATE_ERROR);
+ unlock_fsm ();
+ }
+ return result;
+}
+
+
+static void
+reporter (const char *domain, int algo, const char *what, const char *errtxt)
+{
+ if (!errtxt && !_gcry_log_verbosity (2))
+ return;
+
+ log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
+ !strcmp (domain, "hmac")? "digest":domain,
+ !strcmp (domain, "hmac")? "HMAC-":"",
+ !strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) :
+ !strcmp (domain, "digest")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "hmac")? _gcry_md_algo_name (algo) :
+ !strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "",
+ algo, errtxt? errtxt:"Okay",
+ what?" (":"", what? what:"", what?")":"");
+}
+
+/* Run self-tests for all required cipher algorithms. Return 0 on
+ success. */
+static int
+run_cipher_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_CIPHER_3DES,
+ GCRY_CIPHER_AES128,
+ GCRY_CIPHER_AES192,
+ GCRY_CIPHER_AES256,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_cipher_selftest (algos[idx], extended, reporter);
+ reporter ("cipher", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required hash algorithms. Return 0 on
+ success. */
+static int
+run_digest_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA224,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ GCRY_MD_SHA512,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_md_selftest (algos[idx], extended, reporter);
+ reporter ("digest", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all HMAC algorithms. Return 0 on success. */
+static int
+run_hmac_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_MD_SHA1,
+ GCRY_MD_SHA224,
+ GCRY_MD_SHA256,
+ GCRY_MD_SHA384,
+ GCRY_MD_SHA512,
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_hmac_selftest (algos[idx], extended, reporter);
+ reporter ("hmac", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for all required public key algorithms. Return 0 on
+ success. */
+static int
+run_pubkey_selftests (int extended)
+{
+ static int algos[] =
+ {
+ GCRY_PK_RSA,
+ GCRY_PK_DSA,
+ /* GCRY_PK_ECDSA is not enabled in fips mode. */
+ 0
+ };
+ int idx;
+ gpg_error_t err;
+ int anyerr = 0;
+
+ for (idx=0; algos[idx]; idx++)
+ {
+ err = _gcry_pk_selftest (algos[idx], extended, reporter);
+ reporter ("pubkey", algos[idx], NULL,
+ err? gpg_strerror (err):NULL);
+ if (err)
+ anyerr = 1;
+ }
+ return anyerr;
+}
+
+
+/* Run self-tests for the random number generator. Returns 0 on
+ success. */
+static int
+run_random_selftests (void)
+{
+ gpg_error_t err;
+
+ err = _gcry_random_selftest (reporter);
+ reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
+
+ return !!err;
+}
+
+/* Run an integrity check on the binary. Returns 0 on success. */
+static int
+check_binary_integrity (void)
+{
+#ifdef ENABLE_HMAC_BINARY_CHECK
+ gpg_error_t err;
+ Dl_info info;
+ unsigned char digest[32];
+ int dlen;
+ char *fname = NULL;
+ const char key[] = "What am I, a doctor or a moonshuttle conductor?";
+
+ if (!dladdr ("gcry_check_version", &info))
+ err = gpg_error_from_syserror ();
+ else
+ {
+ dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
+ key, strlen (key));
+ if (dlen < 0)
+ err = gpg_error_from_syserror ();
+ else if (dlen != 32)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ {
+ fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 );
+ if (!fname)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ FILE *fp;
+ char *p;
+
+ /* Prefix the basename with a dot. */
+ strcpy (fname, info.dli_fname);
+ p = strrchr (fname, '/');
+ if (p)
+ p++;
+ else
+ p = fname;
+ memmove (p+1, p, strlen (p)+1);
+ *p = '.';
+ strcat (fname, ".hmac");
+
+ /* Open the file. */
+ fp = fopen (fname, "r");
+ if (!fp)
+ err = gpg_error_from_syserror ();
+ else
+ {
+ /* A buffer of 64 bytes plus one for a LF and one to
+ detect garbage. */
+ unsigned char buffer[64+1+1];
+ const unsigned char *s;
+ int n;
+
+ /* The HMAC files consists of lowercase hex digits
+ only with an optional trailing linefeed. Fail if
+ there is any garbage. */
+ err = gpg_error (GPG_ERR_SELFTEST_FAILED);
+ n = fread (buffer, 1, sizeof buffer, fp);
+ if (n == 64 || (n == 65 && buffer[64] == '\n'))
+ {
+ buffer[64] = 0;
+ for (n=0, s= buffer;
+ n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
+ n++, s += 2)
+ buffer[n] = loxtoi_2 (s);
+ if ( n == 32 && !memcmp (digest, buffer, 32) )
+ err = 0;
+ }
+ fclose (fp);
+ }
+ }
+ }
+ }
+ reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
+#ifdef HAVE_SYSLOG
+ if (err)
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "integrity check using `%s' failed: %s",
+ fname? fname:"[?]", gpg_strerror (err));
+#endif /*HAVE_SYSLOG*/
+ gcry_free (fname);
+ return !!err;
+#else
+ return 0;
+#endif
+}
+
+
+/* Run the self-tests. If EXTENDED is true, extended versions of the
+ selftest are run, that is more tests than required by FIPS. */
+gpg_err_code_t
+_gcry_fips_run_selftests (int extended)
+{
+ enum module_states result = STATE_ERROR;
+ gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
+
+ if (fips_mode ())
+ fips_new_state (STATE_SELFTEST);
+
+ if (run_cipher_selftests (extended))
+ goto leave;
+
+ if (run_digest_selftests (extended))
+ goto leave;
+
+ if (run_hmac_selftests (extended))
+ goto leave;
+
+ /* Run random tests before the pubkey tests because the latter
+ require random. */
+ if (run_random_selftests ())
+ goto leave;
+
+ if (run_pubkey_selftests (extended))
+ goto leave;
+
+ /* Now check the integrity of the binary. We do this this after
+ having checked the HMAC code. */
+ if (check_binary_integrity ())
+ goto leave;
+
+ /* All selftests passed. */
+ result = STATE_OPERATIONAL;
+ ec = 0;
+
+ leave:
+ if (fips_mode ())
+ fips_new_state (result);
+
+ return ec;
+}
+
+
+/* This function is used to tell the FSM about errors in the library.
+ The FSM will be put into an error state. This function should not
+ be called directly but by one of the macros
+
+ fips_signal_error (description)
+ fips_signal_fatal_error (description)
+
+ where DESCRIPTION is a string describing the error. */
+void
+_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
+ int is_fatal, const char *description)
+{
+ if (!fips_mode ())
+ return; /* Not required. */
+
+ /* Set new state before printing an error. */
+ fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
+
+ /* Print error. */
+ log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
+ "%serror in file %s, line %d%s%s: %s",
+ is_fatal? "fatal ":"",
+ srcfile, srcline,
+ srcfunc? ", function ":"", srcfunc? srcfunc:"",
+ description? description : "no description available");
+#endif /*HAVE_SYSLOG*/
+}
+
+
+/* Perform a state transition to NEW_STATE. If this is an invalid
+ transition, the module will go into a fatal error state. */
+static void
+fips_new_state (enum module_states new_state)
+{
+ int ok = 0;
+ enum module_states last_state;
+
+ lock_fsm ();
+
+ last_state = current_state;
+ switch (current_state)
+ {
+ case STATE_POWERON:
+ if (new_state == STATE_INIT
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_INIT:
+ if (new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_SELFTEST:
+ if (new_state == STATE_OPERATIONAL
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_OPERATIONAL:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_SELFTEST
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR)
+ ok = 1;
+ break;
+
+ case STATE_ERROR:
+ if (new_state == STATE_SHUTDOWN
+ || new_state == STATE_ERROR
+ || new_state == STATE_FATALERROR
+ || new_state == STATE_SELFTEST)
+ ok = 1;
+ break;
+
+ case STATE_FATALERROR:
+ if (new_state == STATE_SHUTDOWN )
+ ok = 1;
+ break;
+
+ case STATE_SHUTDOWN:
+ /* We won't see any transition *from* Shutdown because the only
+ allowed new state is Power-Off and that one can't be
+ represented. */
+ break;
+
+ }
+
+ if (ok)
+ {
+ current_state = new_state;
+ }
+
+ unlock_fsm ();
+
+ if (!ok || _gcry_log_verbosity (2))
+ log_info ("libgcrypt state transition %s => %s %s\n",
+ state2str (last_state), state2str (new_state),
+ ok? "granted":"denied");
+
+ if (!ok)
+ {
+ /* Invalid state transition. Halting library. */
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR,
+ "Libgcrypt error: invalid state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ fips_noreturn ();
+ }
+ else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING,
+ "Libgcrypt notice: state transition %s => %s",
+ state2str (last_state), state2str (new_state));
+#endif /*HAVE_SYSLOG*/
+ }
+}
+
+
+
+
+/* This function should be called to ensure that the execution shall
+ not continue. */
+void
+_gcry_fips_noreturn (void)
+{
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
+#endif /*HAVE_SYSLOG*/
+ fflush (NULL);
+ abort ();
+ /*NOTREACHED*/
+}
--- /dev/null
+/* g10lib.h - Internal definitions for libgcrypt
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+ * 2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This header is to be used inside of libgcrypt in place of gcrypt.h.
+ This way we can better distinguish between internal and external
+ usage of gcrypt.h. */
+
+#ifndef G10LIB_H
+#define G10LIB_H 1
+
+#ifdef _GCRYPT_H
+#error gcrypt.h already included
+#endif
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error something is wrong with config.h
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "visibility.h"
+#include "types.h"
+
+
+\f
+
+/* Attribute handling macros. */
+
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
+#define JNLIB_GCC_M_FUNCTION 1
+#define JNLIB_GCC_A_NR __attribute__ ((noreturn))
+#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
+#define JNLIB_GCC_A_NR_PRINTF( f, a ) \
+ __attribute__ ((noreturn, format (printf,f,a)))
+#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
+#else
+#define JNLIB_GCC_A_NR
+#define JNLIB_GCC_A_PRINTF( f, a )
+#define JNLIB_GCC_A_NR_PRINTF( f, a )
+#define GCC_ATTR_NORETURN
+#endif
+
+#if __GNUC__ >= 3
+/* According to glibc this attribute is available since 2.8 however we
+ better play safe and use it only with gcc 3 or newer. */
+#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a)))
+#else
+#define GCC_ATTR_FORMAT_ARG(a)
+#endif
+
+
+/* Gettext macros. */
+
+#define _(a) _gcry_gettext(a)
+#define N_(a) (a)
+
+/* Some handy macros */
+#ifndef STR
+#define STR(v) #v
+#endif
+#define STR2(v) STR(v)
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+\f
+
+/*-- src/global.c -*/
+int _gcry_global_is_operational (void);
+gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
+void _gcry_check_heap (const void *a);
+int _gcry_get_debug_flag (unsigned int mask);
+
+
+/*-- src/misc.c --*/
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void _gcry_bug (const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+void _gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func) GCC_ATTR_NORETURN;
+#else
+void _gcry_bug (const char *file, int line);
+void _gcry_assert_failed (const char *expr, const char *file, int line);
+#endif
+
+const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
+void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
+void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
+void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+int _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
+ JNLIB_GCC_A_PRINTF(2,3);
+void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
+void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
+
+void _gcry_set_log_verbosity( int level );
+int _gcry_log_verbosity( int level );
+
+#ifdef JNLIB_GCC_M_FUNCTION
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
+#elif __STDC_VERSION__ >= 199901L
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
+#else
+#define BUG() _gcry_bug( __FILE__ , __LINE__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
+#endif
+
+
+#define log_bug _gcry_log_bug
+#define log_fatal _gcry_log_fatal
+#define log_error _gcry_log_error
+#define log_info _gcry_log_info
+#define log_debug _gcry_log_debug
+#define log_printf _gcry_log_printf
+#define log_printhex _gcry_log_printhex
+
+
+/*-- src/hwfeatures.c --*/
+/* (Do not change these values unless synced with the asm code.) */
+#define HWF_PADLOCK_RNG 1
+#define HWF_PADLOCK_AES 2
+#define HWF_PADLOCK_SHA 4
+#define HWF_PADLOCK_MMUL 8
+
+#define HWF_INTEL_AESNI 256
+
+
+unsigned int _gcry_get_hw_features (void);
+void _gcry_detect_hw_features (unsigned int);
+
+
+/*-- mpi/mpiutil.c --*/
+const char *_gcry_mpi_get_hw_config (void);
+
+
+/*-- cipher/pubkey.c --*/
+
+/* FIXME: shouldn't this go into mpi.h? */
+#ifndef mpi_powm
+#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) )
+#endif
+
+/*-- primegen.c --*/
+gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
+ gcry_random_level_t random_level,
+ int (*extra_check)(void*, gcry_mpi_t),
+ void *extra_check_arg);
+gcry_mpi_t _gcry_generate_elg_prime (int mode,
+ unsigned int pbits, unsigned int qbits,
+ gcry_mpi_t g, gcry_mpi_t **factors);
+gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
+ const gcry_mpi_t xp1, const gcry_mpi_t xp2,
+ const gcry_mpi_t e,
+ gcry_mpi_t *r_p1, gcry_mpi_t *r_p2);
+gpg_err_code_t _gcry_generate_fips186_2_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen);
+gpg_err_code_t _gcry_generate_fips186_3_prime
+ (unsigned int pbits, unsigned int qbits,
+ const void *seed, size_t seedlen,
+ gcry_mpi_t *r_q, gcry_mpi_t *r_p,
+ int *r_counter,
+ void **r_seed, size_t *r_seedlen, int *r_hashalgo);
+
+
+/* Replacements of missing functions (missing-string.c). */
+#ifndef HAVE_STPCPY
+char *stpcpy (char *a, const char *b);
+#endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
+#endif
+
+#include "../compat/libcompat.h"
+
+
+/* Macros used to rename missing functions. */
+#ifndef HAVE_STRTOUL
+#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
+#endif
+#ifndef HAVE_MEMMOVE
+#define memmove(d, s, n) bcopy((s), (d), (n))
+#endif
+#ifndef HAVE_STRICMP
+#define stricmp(a,b) strcasecmp( (a), (b) )
+#endif
+#ifndef HAVE_ATEXIT
+#define atexit(a) (on_exit((a),0))
+#endif
+#ifndef HAVE_RAISE
+#define raise(a) kill(getpid(), (a))
+#endif
+
+
+/* Stack burning. */
+
+void _gcry_burn_stack (int bytes);
+
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+/* Digit predicates. */
+
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
+#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \
+ || (*(a) >= 'a' && *(a) <= 'z'))
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+
+/* Management for ciphers/digests/pubkey-ciphers. */
+
+/* Structure for each registered `module'. */
+struct gcry_module
+{
+ struct gcry_module *next; /* List pointers. */
+ struct gcry_module **prevp;
+ void *spec; /* Pointer to the subsystem-specific
+ specification structure. */
+ void *extraspec; /* Pointer to the subsystem-specific
+ extra specification structure. */
+ int flags; /* Associated flags. */
+ int counter; /* Use counter. */
+ unsigned int mod_id; /* ID of this module. */
+};
+
+/* Flags for the `flags' member of gcry_module_t. */
+#define FLAG_MODULE_DISABLED (1 << 0)
+
+gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
+ unsigned int id,
+ void *spec,
+ void *extraspec,
+ gcry_module_t *module);
+
+typedef int (*gcry_module_lookup_t) (void *spec, void *data);
+
+/* Lookup a module specification by it's ID. After a successful
+ lookup, the module has it's resource counter incremented. */
+gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
+ unsigned int id);
+
+/* Internal function. Lookup a module specification. */
+gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
+ gcry_module_lookup_t func);
+
+/* Release a module. In case the use-counter reaches zero, destroy
+ the module. */
+void _gcry_module_release (gcry_module_t entry);
+
+/* Add a reference to a module. */
+void _gcry_module_use (gcry_module_t module);
+
+/* Return a list of module IDs. */
+gcry_err_code_t _gcry_module_list (gcry_module_t modules,
+ int *list, int *list_length);
+
+gcry_err_code_t _gcry_cipher_init (void);
+gcry_err_code_t _gcry_md_init (void);
+gcry_err_code_t _gcry_pk_init (void);
+gcry_err_code_t _gcry_ac_init (void);
+
+gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
+void _gcry_pk_module_release (gcry_module_t module);
+gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
+
+/* Memory management. */
+#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
+
+
+/*-- sexp.c --*/
+gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr);
+char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
+
+
+/*-- fips.c --*/
+
+void _gcry_initialize_fips_mode (int force);
+
+int _gcry_fips_mode (void);
+#define fips_mode() _gcry_fips_mode ()
+
+int _gcry_enforced_fips_mode (void);
+
+void _gcry_inactivate_fips_mode (const char *text);
+int _gcry_is_fips_mode_inactive (void);
+
+
+void _gcry_fips_signal_error (const char *srcfile,
+ int srcline,
+ const char *srcfunc,
+ int is_fatal,
+ const char *description);
+#ifdef JNLIB_GCC_M_FUNCTION
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a))
+#else
+# define fips_signal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a))
+# define fips_signal_fatal_error(a) \
+ _gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
+#endif
+
+int _gcry_fips_is_operational (void);
+#define fips_is_operational() (_gcry_global_is_operational ())
+#define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL)
+
+int _gcry_fips_test_operational (void);
+int _gcry_fips_test_error_or_operational (void);
+
+gpg_err_code_t _gcry_fips_run_selftests (int extended);
+
+void _gcry_fips_noreturn (void);
+#define fips_noreturn() (_gcry_fips_noreturn ())
+
+
+
+#endif /* G10LIB_H */
--- /dev/null
+/* gcrypt-module.h - GNU Cryptographic Library Interface
+ Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This file contains the necessary declarations/definitions for
+ working with Libgcrypt modules.
+ */
+
+#ifndef _GCRYPT_MODULE_H
+#define _GCRYPT_MODULE_H
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* keep Emacsens's auto-indent happy */
+}
+#endif
+#endif
+
+/* The interfaces using the module system reserve a certain range of
+ IDs for application use. These IDs are not valid within Libgcrypt
+ but Libgcrypt makes sure never to allocate such a module ID. */
+#define GCRY_MODULE_ID_USER 1024
+#define GCRY_MODULE_ID_USER_LAST 4095
+
+
+/* This type represents a `module'. */
+typedef struct gcry_module *gcry_module_t;
+
+/* Check that the library fulfills the version requirement. */
+
+/* Type for the cipher_setkey function. */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+ const unsigned char *key,
+ unsigned keylen);
+
+/* Type for the cipher_encrypt function. */
+typedef void (*gcry_cipher_encrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function. */
+typedef void (*gcry_cipher_decrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function. */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ unsigned int n);
+
+/* Type for the cipher_stdecrypt function. */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+ unsigned char *outbuf,
+ const unsigned char *inbuf,
+ unsigned int n);
+
+typedef struct gcry_cipher_oid_spec
+{
+ const char *oid;
+ int mode;
+} gcry_cipher_oid_spec_t;
+
+/* Module specification structure for ciphers. */
+typedef struct gcry_cipher_spec
+{
+ const char *name;
+ const char **aliases;
+ gcry_cipher_oid_spec_t *oids;
+ size_t blocksize;
+ size_t keylen;
+ size_t contextsize;
+ gcry_cipher_setkey_t setkey;
+ gcry_cipher_encrypt_t encrypt;
+ gcry_cipher_decrypt_t decrypt;
+ gcry_cipher_stencrypt_t stencrypt;
+ gcry_cipher_stdecrypt_t stdecrypt;
+} gcry_cipher_spec_t;
+
+/* Register a new cipher module whose specification can be found in
+ CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representing this module is stored in MODULE. */
+gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher,
+ int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+
+/* Unregister the cipher identified by MODULE, which must have been
+ registered with gcry_cipher_register. */
+void gcry_cipher_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* ********************** */
+
+/* Type for the pk_generate function. */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
+ unsigned int nbits,
+ unsigned long use_e,
+ gcry_mpi_t *skey,
+ gcry_mpi_t **retfactors);
+
+/* Type for the pk_check_secret_key function. */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_encrypt function. */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *pkey,
+ int flags);
+
+/* Type for the pk_decrypt function. */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
+ gcry_mpi_t *result,
+ gcry_mpi_t *data,
+ gcry_mpi_t *skey,
+ int flags);
+
+/* Type for the pk_sign function. */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
+ gcry_mpi_t *resarr,
+ gcry_mpi_t data,
+ gcry_mpi_t *skey);
+
+/* Type for the pk_verify function. */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
+ gcry_mpi_t hash,
+ gcry_mpi_t *data,
+ gcry_mpi_t *pkey,
+ int (*cmp) (void *, gcry_mpi_t),
+ void *opaquev);
+
+/* Type for the pk_get_nbits function. */
+typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
+
+/* Module specification structure for message digests. */
+typedef struct gcry_pk_spec
+{
+ const char *name;
+ const char **aliases;
+ const char *elements_pkey;
+ const char *elements_skey;
+ const char *elements_enc;
+ const char *elements_sig;
+ const char *elements_grip;
+ int use;
+ gcry_pk_generate_t generate;
+ gcry_pk_check_secret_key_t check_secret_key;
+ gcry_pk_encrypt_t encrypt;
+ gcry_pk_decrypt_t decrypt;
+ gcry_pk_sign_t sign;
+ gcry_pk_verify_t verify;
+ gcry_pk_get_nbits_t get_nbits;
+} gcry_pk_spec_t;
+
+/* Register a new pubkey module whose specification can be found in
+ PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t gcry_pk_register (gcry_pk_spec_t *pubkey,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Unregister the pubkey identified by ID, which must have been
+ registered with gcry_pk_register. */
+void gcry_pk_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* ********************** */
+
+/* Type for the md_init function. */
+typedef void (*gcry_md_init_t) (void *c);
+
+/* Type for the md_write function. */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function. */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function. */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
+{
+ const char *oidstring;
+} gcry_md_oid_spec_t;
+
+/* Module specification structure for message digests. */
+typedef struct gcry_md_spec
+{
+ const char *name;
+ unsigned char *asnoid;
+ int asnlen;
+ gcry_md_oid_spec_t *oids;
+ int mdlen;
+ gcry_md_init_t init;
+ gcry_md_write_t write;
+ gcry_md_final_t final;
+ gcry_md_read_t read;
+ size_t contextsize; /* allocate this amount of context */
+} gcry_md_spec_t;
+
+/* Register a new digest module whose specification can be found in
+ DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t gcry_md_register (gcry_md_spec_t *digest,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Unregister the digest identified by ID, which must have been
+ registered with gcry_digest_register. */
+void gcry_md_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+#if 0 /* keep Emacsens's auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ File: src/gcrypt.h. Generated from gcrypt.h.in by configure. */
+
+#ifndef _GCRYPT_H
+#define _GCRYPT_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <gpg-error.h>
+
+#include <sys/types.h>
+
+#if defined _WIN32 || defined __WIN32__
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <time.h>
+# ifndef __GNUC__
+ typedef long ssize_t;
+ typedef int pid_t;
+# endif /*!__GNUC__*/
+#else
+# include <sys/socket.h>
+# include <sys/time.h>
+# include <sys/select.h>
+#endif /*!_WIN32*/
+
+typedef socklen_t gcry_socklen_t;
+
+/* This is required for error code compatibility. */
+#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+}
+#endif
+#endif
+
+/* The version of this header should match the one of the library. It
+ should not be used by a program because gcry_check_version() should
+ return the same version. The purpose of this macro is to let
+ autoconf (using the AM_PATH_GCRYPT macro) check that this header
+ matches the installed library. */
+#define GCRYPT_VERSION "1.5.0"
+
+/* Internal: We can't use the convenience macros for the multi
+ precision integer functions when building this library. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#ifndef GCRYPT_NO_MPI_MACROS
+#define GCRYPT_NO_MPI_MACROS 1
+#endif
+#endif
+
+/* We want to use gcc attributes when possible. Warning: Don't use
+ these macros in your programs: As indicated by the leading
+ underscore they are subject to change without notice. */
+#ifdef __GNUC__
+
+#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#if _GCRY_GCC_VERSION >= 30100
+#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 29600
+#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 30200
+#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__))
+#endif
+
+#endif /*__GNUC__*/
+
+#ifndef _GCRY_GCC_ATTR_DEPRECATED
+#define _GCRY_GCC_ATTR_DEPRECATED
+#endif
+#ifndef _GCRY_GCC_ATTR_PURE
+#define _GCRY_GCC_ATTR_PURE
+#endif
+#ifndef _GCRY_GCC_ATTR_MALLOC
+#define _GCRY_GCC_ATTR_MALLOC
+#endif
+
+/* Make up an attribute to mark functions and types as deprecated but
+ allow internal use by Libgcrypt. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#define _GCRY_ATTR_INTERNAL
+#else
+#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED
+#endif
+
+/* Wrappers for the libgpg-error library. */
+
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+typedef gpg_err_source_t gcry_err_source_t;
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
+{
+ return gpg_err_make (source, code);
+}
+
+/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
+ file to specify a default source for gpg_error. */
+#ifndef GCRY_ERR_SOURCE_DEFAULT
+#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1
+#endif
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_error (gcry_err_code_t code)
+{
+ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
+}
+
+static GPG_ERR_INLINE gcry_err_code_t
+gcry_err_code (gcry_error_t err)
+{
+ return gpg_err_code (err);
+}
+
+
+static GPG_ERR_INLINE gcry_err_source_t
+gcry_err_source (gcry_error_t err)
+{
+ return gpg_err_source (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *gcry_strerror (gcry_error_t err);
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *gcry_strsource (gcry_error_t err);
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t gcry_err_code_from_errno (int err);
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int gcry_err_code_to_errno (gcry_err_code_t code);
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
+
+/* Return an error value with the system error ERR. */
+gcry_err_code_t gcry_error_from_errno (int err);
+
+\f
+/* This enum is deprecated; it is only declared for the sake of
+ complete API compatibility. */
+enum gcry_thread_option
+ {
+ _GCRY_THREAD_OPTION_DUMMY
+ } _GCRY_GCC_ATTR_DEPRECATED;
+
+
+/* Constants defining the thread model to use. Used with the OPTION
+ field of the struct gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_DEFAULT 0
+#define GCRY_THREAD_OPTION_USER 1
+#define GCRY_THREAD_OPTION_PTH 2
+#define GCRY_THREAD_OPTION_PTHREAD 3
+
+/* The version number encoded in the OPTION field of the struct
+ gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_VERSION 0
+
+/* Wrapper for struct ath_ops. */
+struct gcry_thread_cbs
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number.
+ */
+ unsigned int option;
+
+ int (*init) (void);
+ int (*mutex_init) (void **priv);
+ int (*mutex_destroy) (void **priv);
+ int (*mutex_lock) (void **priv);
+ int (*mutex_unlock) (void **priv);
+ ssize_t (*read) (int fd, void *buf, size_t nbytes);
+ ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, void *addr, int *length_ptr);
+ int (*connect) (int s, void *addr, gcry_socklen_t length);
+ int (*sendmsg) (int s, const void *msg, int flags);
+ int (*recvmsg) (int s, void *msg, int flags);
+#else
+ ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr);
+ int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length);
+ int (*sendmsg) (int s, const struct msghdr *msg, int flags);
+ int (*recvmsg) (int s, struct msghdr *msg, int flags);
+#endif
+};
+
+#ifdef _WIN32
+# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \
+static ssize_t gcry_pth_select (int nfd, void *rset, void *wset, \
+ void *eset, struct timeval *timeout) \
+ { return pth_select (nfd, rset, wset, eset, timeout); } \
+static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \
+ { return pth_waitpid (pid, status, options); } \
+static int gcry_pth_accept (int s, void *addr, \
+ gcry_socklen_t *length_ptr) \
+ { return pth_accept (s, addr, length_ptr); } \
+static int gcry_pth_connect (int s, void *addr, \
+ gcry_socklen_t length) \
+ { return pth_connect (s, addr, length); }
+#else /*!_WIN32*/
+# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \
+static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \
+ fd_set *eset, struct timeval *timeout) \
+ { return pth_select (nfd, rset, wset, eset, timeout); } \
+static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \
+ { return pth_waitpid (pid, status, options); } \
+static int gcry_pth_accept (int s, struct sockaddr *addr, \
+ gcry_socklen_t *length_ptr) \
+ { return pth_accept (s, addr, length_ptr); } \
+static int gcry_pth_connect (int s, struct sockaddr *addr, \
+ gcry_socklen_t length) \
+ { return pth_connect (s, addr, length); }
+#endif /*!_WIN32*/
+
+
+
+#define GCRY_THREAD_OPTION_PTH_IMPL \
+static int gcry_pth_init (void) \
+{ return (pth_init () == FALSE) ? errno : 0; } \
+static int gcry_pth_mutex_init (void **priv) \
+{ \
+ int err = 0; \
+ pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); \
+ \
+ if (!lock) \
+ err = ENOMEM; \
+ if (!err) \
+ { \
+ err = pth_mutex_init (lock); \
+ if (err == FALSE) \
+ err = errno; \
+ else \
+ err = 0; \
+ if (err) \
+ free (lock); \
+ else \
+ *priv = lock; \
+ } \
+ return err; \
+} \
+static int gcry_pth_mutex_destroy (void **lock) \
+ { /* GNU Pth has no destructor function. */ free (*lock); return 0; } \
+static int gcry_pth_mutex_lock (void **lock) \
+ { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE) \
+ ? errno : 0; } \
+static int gcry_pth_mutex_unlock (void **lock) \
+ { return ((pth_mutex_release (*lock)) == FALSE) \
+ ? errno : 0; } \
+static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes) \
+ { return pth_read (fd, buf, nbytes); } \
+static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes) \
+ { return pth_write (fd, buf, nbytes); } \
+_GCRY_THREAD_OPTION_PTH_IMPL_NET \
+ \
+/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg. */ \
+static struct gcry_thread_cbs gcry_threads_pth = { \
+ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)), \
+ gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy, \
+ gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write, \
+ gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, \
+ NULL, NULL }
+
+
+#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
+static int gcry_pthread_mutex_init (void **priv) \
+{ \
+ int err = 0; \
+ pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\
+ \
+ if (!lock) \
+ err = ENOMEM; \
+ if (!err) \
+ { \
+ err = pthread_mutex_init (lock, NULL); \
+ if (err) \
+ free (lock); \
+ else \
+ *priv = lock; \
+ } \
+ return err; \
+} \
+static int gcry_pthread_mutex_destroy (void **lock) \
+ { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock); \
+ free (*lock); return err; } \
+static int gcry_pthread_mutex_lock (void **lock) \
+ { return pthread_mutex_lock ((pthread_mutex_t*)*lock); } \
+static int gcry_pthread_mutex_unlock (void **lock) \
+ { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); } \
+ \
+static struct gcry_thread_cbs gcry_threads_pthread = { \
+ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), \
+ NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, \
+ gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock, \
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+
+\f
+/* The data object used to hold a multi precision integer. */
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+\f
+
+/* Check that the library fulfills the version requirement. */
+const char *gcry_check_version (const char *req_version);
+
+/* Codes for function dispatchers. */
+
+/* Codes used with the gcry_control function. */
+enum gcry_ctl_cmds
+ {
+ GCRYCTL_SET_KEY = 1,
+ GCRYCTL_SET_IV = 2,
+ GCRYCTL_CFB_SYNC = 3,
+ GCRYCTL_RESET = 4, /* e.g. for MDs */
+ GCRYCTL_FINALIZE = 5,
+ GCRYCTL_GET_KEYLEN = 6,
+ GCRYCTL_GET_BLKLEN = 7,
+ GCRYCTL_TEST_ALGO = 8,
+ GCRYCTL_IS_SECURE = 9,
+ GCRYCTL_GET_ASNOID = 10,
+ GCRYCTL_ENABLE_ALGO = 11,
+ GCRYCTL_DISABLE_ALGO = 12,
+ GCRYCTL_DUMP_RANDOM_STATS = 13,
+ GCRYCTL_DUMP_SECMEM_STATS = 14,
+ GCRYCTL_GET_ALGO_NPKEY = 15,
+ GCRYCTL_GET_ALGO_NSKEY = 16,
+ GCRYCTL_GET_ALGO_NSIGN = 17,
+ GCRYCTL_GET_ALGO_NENCR = 18,
+ GCRYCTL_SET_VERBOSITY = 19,
+ GCRYCTL_SET_DEBUG_FLAGS = 20,
+ GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
+ GCRYCTL_USE_SECURE_RNDPOOL= 22,
+ GCRYCTL_DUMP_MEMORY_STATS = 23,
+ GCRYCTL_INIT_SECMEM = 24,
+ GCRYCTL_TERM_SECMEM = 25,
+ GCRYCTL_DISABLE_SECMEM_WARN = 27,
+ GCRYCTL_SUSPEND_SECMEM_WARN = 28,
+ GCRYCTL_RESUME_SECMEM_WARN = 29,
+ GCRYCTL_DROP_PRIVS = 30,
+ GCRYCTL_ENABLE_M_GUARD = 31,
+ GCRYCTL_START_DUMP = 32,
+ GCRYCTL_STOP_DUMP = 33,
+ GCRYCTL_GET_ALGO_USAGE = 34,
+ GCRYCTL_IS_ALGO_ENABLED = 35,
+ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
+ GCRYCTL_DISABLE_SECMEM = 37,
+ GCRYCTL_INITIALIZATION_FINISHED = 38,
+ GCRYCTL_INITIALIZATION_FINISHED_P = 39,
+ GCRYCTL_ANY_INITIALIZATION_P = 40,
+ GCRYCTL_SET_CBC_CTS = 41,
+ GCRYCTL_SET_CBC_MAC = 42,
+ GCRYCTL_SET_CTR = 43,
+ GCRYCTL_ENABLE_QUICK_RANDOM = 44,
+ GCRYCTL_SET_RANDOM_SEED_FILE = 45,
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
+ GCRYCTL_SET_THREAD_CBS = 47,
+ GCRYCTL_FAST_POLL = 48,
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
+ GCRYCTL_USE_RANDOM_DAEMON = 50,
+ GCRYCTL_FAKED_RANDOM_P = 51,
+ GCRYCTL_SET_RNDEGD_SOCKET = 52,
+ GCRYCTL_PRINT_CONFIG = 53,
+ GCRYCTL_OPERATIONAL_P = 54,
+ GCRYCTL_FIPS_MODE_P = 55,
+ GCRYCTL_FORCE_FIPS_MODE = 56,
+ GCRYCTL_SELFTEST = 57,
+ /* Note: 58 .. 62 are used internally. */
+ GCRYCTL_DISABLE_HWF = 63
+ };
+
+/* Perform various operations defined by CMD. */
+gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
+
+\f
+/* S-expression management. */
+
+/* The object to represent an S-expression as used with the public key
+ functions. */
+struct gcry_sexp;
+typedef struct gcry_sexp *gcry_sexp_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* The possible values for the S-expression format. */
+enum gcry_sexp_format
+ {
+ GCRYSEXP_FMT_DEFAULT = 0,
+ GCRYSEXP_FMT_CANON = 1,
+ GCRYSEXP_FMT_BASE64 = 2,
+ GCRYSEXP_FMT_ADVANCED = 3
+ };
+
+/* Create an new S-expression object from BUFFER of size LENGTH and
+ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER
+ is expected to be in canonized format. */
+gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect);
+
+ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
+ effect to transfer ownership of BUFFER to the created object. */
+gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *));
+
+/* Scan BUFFER and return a new S-expression object in RETSEXP. This
+ function expects a printf like string in BUFFER. */
+gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length);
+
+/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
+ only be used for certain encodings. */
+gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...);
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list);
+
+/* Release the S-expression object SEXP */
+void gcry_sexp_release (gcry_sexp_t sexp);
+
+/* Calculate the length of an canonized S-expresion in BUFFER and
+ check for a valid encoding. */
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode);
+
+/* Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. */
+size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+ size_t maxlength);
+
+/* Dumps the S-expression object A in a format suitable for debugging
+ to Libgcrypt's logging stream. */
+void gcry_sexp_dump (const gcry_sexp_t a);
+
+gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+
+/* Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ `NULL' when not found. */
+gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
+ const char *tok, size_t toklen);
+/* Return the length of the LIST. For a valid S-expression this
+ should be at least 1. */
+int gcry_sexp_length (const gcry_sexp_t list);
+
+/* Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, `NULL' is returned. */
+gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
+
+/* Create and return a new S-expression from the first element in
+ LIST; this called the "type" and should always exist and be a
+ string. `NULL' is returned in case of a problem. */
+gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
+
+/* Create and return a new list form all elements except for the first
+ one. Note, that this function may return an invalid S-expression
+ because it is not guaranteed, that the type exists and is a string.
+ However, for parsing a complex S-expression it might be useful for
+ intermediate lists. Returns `NULL' on error. */
+gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
+
+gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
+
+
+/* This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, `NULL' is returned.
+ *Note:* The returned pointer is valid as long as LIST is not
+ modified or released. */
+const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+ size_t *datalen);
+
+/* This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release the returned value using `gcry_free'. If there is no data
+ at the given index, the index represents a list or the value can't
+ be converted to a string, `NULL' is returned. */
+char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
+
+/* This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using `gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, `NULL' is returned. */
+gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+
+
+\f
+/*******************************************
+ * *
+ * Multi Precision Integer Functions *
+ * *
+ *******************************************/
+
+/* Different formats of external big integer representation. */
+enum gcry_mpi_format
+ {
+ GCRYMPI_FMT_NONE= 0,
+ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */
+ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */
+ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */
+ GCRYMPI_FMT_HEX = 4, /* Hex format. */
+ GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */
+ };
+
+/* Flags used for creating big integers. */
+enum gcry_mpi_flag
+ {
+ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */
+ GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just
+ a way to store some bytes. This is
+ useful for encrypted big integers. */
+ };
+
+
+/* Allocate a new big integer object, initialize it with 0 and
+ initially allocate memory for a number of at least NBITS. */
+gcry_mpi_t gcry_mpi_new (unsigned int nbits);
+
+/* Same as gcry_mpi_new() but allocate in "secure" memory. */
+gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
+
+/* Release the number A and free all associated resources. */
+void gcry_mpi_release (gcry_mpi_t a);
+
+/* Create a new number with the same value as A. */
+gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
+
+/* Store the big integer value U in W. */
+gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+
+/* Store the unsigned integer value U in W. */
+gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+
+/* Swap the values of A and B. */
+void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+
+/* Compare the big integer number U and V returning 0 for equality, a
+ positive value for U > V and a negative for U < V. */
+int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+
+/* Compare the big integer number U with the unsigned integer V
+ returning 0 for equality, a positive value for U > V and a negative
+ for U < V. */
+int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NSCANNED is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned);
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. */
+gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Convert the big integer A int the external representation described
+ by FORMAT and store it in a newly allocated buffer which address
+ will be put into BUFFER. NWRITTEN receives the actual lengths of the
+ external representation. */
+gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void gcry_mpi_dump (const gcry_mpi_t a);
+
+
+/* W = U + V. */
+void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U + V. V is an unsigned integer. */
+void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+
+/* W = U + V mod M. */
+void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U - V. */
+void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U - V. V is an unsigned integer. */
+void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U - V mod M */
+void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * V. */
+void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U * V. V is an unsigned integer. */
+void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U * V mod M. */
+void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * (2 ^ CNT). */
+void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+
+/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
+ Q or R may be passed as NULL. ROUND should be negative or 0. */
+void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+
+/* R = DIVIDEND % DIVISOR */
+void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* W = B ^ E mod M. */
+void gcry_mpi_powm (gcry_mpi_t w,
+ const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m);
+
+/* Set G to the greatest common divisor of A and B.
+ Return true if the G is 1. */
+int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+
+/* Set X to the multiplicative inverse of A mod M.
+ Return true if the value exists. */
+int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+
+
+/* Return the number of bits required to represent A. */
+unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
+
+/* Return true when bit number N (counting from 0) is set in A. */
+int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A. */
+void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A. */
+void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A and clear all bits greater than N. */
+void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A and all bits greater than N. */
+void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the right and store the result in X. */
+void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the left and store the result in X. */
+void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+ value. WARNING: Never use an opaque MPI for anything thing else then
+ gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+
+/* Return a pointer to an opaque value stored in A and return its size
+ in NBITS. Note that the returned pointer is still owned by A and
+ that the function should never be used for an non-opaque MPI. */
+void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+
+/* Set the FLAG for the big integer A. Currently only the flag
+ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
+ stored in "secure" memory. */
+void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Clear FLAG for the big integer A. Note that this function is
+ currently useless as no flags are allowed. */
+void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Return true when the FLAG is set for A. */
+int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
+ convenience macros for the big integer functions. */
+#ifndef GCRYPT_NO_MPI_MACROS
+#define mpi_new(n) gcry_mpi_new( (n) )
+#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
+#define mpi_release(a) \
+ do \
+ { \
+ gcry_mpi_release ((a)); \
+ (a) = NULL; \
+ } \
+ while (0)
+
+#define mpi_copy( a ) gcry_mpi_copy( (a) )
+#define mpi_set( w, u) gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) )
+#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) )
+#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) )
+
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) )
+#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) )
+#endif /* GCRYPT_NO_MPI_MACROS */
+
+
+\f
+/************************************
+ * *
+ * Symmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_cipher_handle;
+typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* All symmetric encryption algorithms are identified by their IDs.
+ More IDs may be registered at runtime. */
+enum gcry_cipher_algos
+ {
+ GCRY_CIPHER_NONE = 0,
+ GCRY_CIPHER_IDEA = 1,
+ GCRY_CIPHER_3DES = 2,
+ GCRY_CIPHER_CAST5 = 3,
+ GCRY_CIPHER_BLOWFISH = 4,
+ GCRY_CIPHER_SAFER_SK128 = 5,
+ GCRY_CIPHER_DES_SK = 6,
+ GCRY_CIPHER_AES = 7,
+ GCRY_CIPHER_AES192 = 8,
+ GCRY_CIPHER_AES256 = 9,
+ GCRY_CIPHER_TWOFISH = 10,
+
+ /* Other cipher numbers are above 300 for OpenPGP reasons. */
+ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */
+ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */
+ GCRY_CIPHER_TWOFISH128 = 303,
+ GCRY_CIPHER_SERPENT128 = 304,
+ GCRY_CIPHER_SERPENT192 = 305,
+ GCRY_CIPHER_SERPENT256 = 306,
+ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */
+ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */
+ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */
+ GCRY_CIPHER_CAMELLIA128 = 310,
+ GCRY_CIPHER_CAMELLIA192 = 311,
+ GCRY_CIPHER_CAMELLIA256 = 312
+ };
+
+/* The Rijndael algorithm is basically AES, so provide some macros. */
+#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
+#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
+#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
+
+/* The supported encryption modes. Note that not all of them are
+ supported for each algorithm. */
+enum gcry_cipher_modes
+ {
+ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */
+ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */
+ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */
+ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */
+ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */
+ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */
+ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */
+ GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_cipher_flags
+ {
+ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */
+ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */
+ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */
+ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */
+ };
+
+
+/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may
+ be given as an bitwise OR of the gcry_cipher_flags values. */
+gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags);
+
+/* Close the cioher handle H and release all resource. */
+void gcry_cipher_close (gcry_cipher_hd_t h);
+
+/* Perform various operations on the cipher object H. */
+gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+
+/* Retrieve various information about the cipher object H. */
+gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the cipher algorithm ALGO. */
+gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if
+ the algorithm name is not known. */
+int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Given an ASN.1 object identifier in standard IETF dotted decimal
+ format in STRING, return the encryption mode associated with that
+ OID or 0 if not known or applicable. */
+int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+
+/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
+ into the buffer OUT which has an allocated length of OUTSIZE. For
+ most algorithms it is possible to pass NULL for in and 0 for INLEN
+ and do a in-place decryption of the data provided in OUT. */
+gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* The counterpart to gcry_cipher_encrypt. */
+gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* Set KEY of length KEYLEN bytes for the cipher handle HD. */
+gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
+ const void *key, size_t keylen);
+
+
+/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
+gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
+ const void *iv, size_t ivlen);
+
+
+/* Reset the handle to the state after open. */
+#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Perform the OpenPGP sync operation if this is enabled for the
+ cipher handle H. */
+#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
+
+/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
+#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
+ NULL, on )
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero block. */
+gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
+ const void *ctr, size_t ctrlen);
+
+/* Retrieved the key length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_keylen (int algo);
+
+/* Retrieve the block length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_blklen (int algo);
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_cipher_test_algo(a) \
+ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded cipher modules. If
+ LIST is zero, write the number of loaded cipher modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_cipher_list (int *list, int *list_length);
+
+\f
+/************************************
+ * *
+ * Asymmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The algorithms and their IDs we support. */
+enum gcry_pk_algos
+ {
+ GCRY_PK_RSA = 1,
+ GCRY_PK_RSA_E = 2, /* (deprecated) */
+ GCRY_PK_RSA_S = 3, /* (deprecated) */
+ GCRY_PK_ELG_E = 16,
+ GCRY_PK_DSA = 17,
+ GCRY_PK_ELG = 20,
+ GCRY_PK_ECDSA = 301,
+ GCRY_PK_ECDH = 302
+ };
+
+/* Flags describing usage capabilities of a PK algorithm. */
+#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */
+#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */
+#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */
+#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */
+#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
+
+/* Encrypt the DATA using the public key PKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Decrypt the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Sign the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Check the signature SIGVAL on DATA using the public key PKEY. */
+gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Check that private KEY is sane. */
+gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
+
+/* Generate a new key pair according to the parameters given in
+ S_PARMS. The new key pair is returned in as an S-expression in
+ R_KEY. */
+gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+
+/* Catch all function for miscellaneous operations. */
+gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+
+/* Retrieve information about the public key algorithm ALGO. */
+gcry_error_t gcry_pk_algo_info (int algo, int what,
+ void *buffer, size_t *nbytes);
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a public key algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* Return what is commonly referred as the key length for the given
+ public or private KEY. */
+unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+
+/* Please note that keygrip is still experimental and should not be
+ used without contacting the author. */
+unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+
+/* Return the name of the curve matching KEY. */
+const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+ unsigned int *r_nbits);
+
+/* Return an S-expression with the parameters of the named ECC curve
+ NAME. ALGO must be set to an ECC algorithm. */
+gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
+
+/* Return 0 if the public key algorithm A is available for use. */
+#define gcry_pk_test_algo(a) \
+ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded pubkey modules. If
+ LIST is zero, write the number of loaded pubkey modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less pubkey modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_pk_list (int *list, int *list_length);
+
+\f
+
+/************************************
+ * *
+ * Cryptograhic Hash Functions *
+ * *
+ ************************************/
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+ are implemnted. */
+enum gcry_md_algos
+ {
+ GCRY_MD_NONE = 0,
+ GCRY_MD_MD5 = 1,
+ GCRY_MD_SHA1 = 2,
+ GCRY_MD_RMD160 = 3,
+ GCRY_MD_MD2 = 5,
+ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */
+ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */
+ GCRY_MD_SHA256 = 8,
+ GCRY_MD_SHA384 = 9,
+ GCRY_MD_SHA512 = 10,
+ GCRY_MD_SHA224 = 11,
+ GCRY_MD_MD4 = 301,
+ GCRY_MD_CRC32 = 302,
+ GCRY_MD_CRC32_RFC1510 = 303,
+ GCRY_MD_CRC24_RFC2440 = 304,
+ GCRY_MD_WHIRLPOOL = 305,
+ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */
+ GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_md_flags
+ {
+ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */
+ GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */
+ };
+
+/* (Forward declaration.) */
+struct gcry_md_context;
+
+/* This object is used to hold a handle to a message digest object.
+ This structure is private - only to be used by the public gcry_md_*
+ macros. */
+typedef struct gcry_md_handle
+{
+ /* Actual context. */
+ struct gcry_md_context *ctx;
+
+ /* Buffer management. */
+ int bufpos;
+ int bufsize;
+ unsigned char buf[1];
+} *gcry_md_hd_t;
+
+/* Compatibility types, do not use them. */
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. */
+gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+
+/* Release the message digest object HD. */
+void gcry_md_close (gcry_md_hd_t hd);
+
+/* Add the message digest algorithm ALGO to the digest object HD. */
+gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
+
+/* Create a new digest object as an exact copy of the object HD. */
+gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+
+/* Reset the digest object HD to its initial state. */
+void gcry_md_reset (gcry_md_hd_t hd);
+
+/* Perform various operations on the digest object HD. */
+gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+ void *buffer, size_t buflen);
+
+/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
+ it can update the digest values. This is the actual hash
+ function. */
+void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+
+/* Read out the final digest from HD return the digest value for
+ algorithm ALGO. */
+unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
+
+/* Convenience function to calculate the hash from the data in BUFFER
+ of size LENGTH using the algorithm ALGO avoiding the creating of a
+ hash object. The hash is returned in the caller provided buffer
+ DIGEST which must be large enough to hold the digest of the given
+ algorithm. */
+void gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length);
+
+/* Retrieve the algorithm used with HD. This does not work reliable
+ if more than one algorithm is enabled in HD. */
+int gcry_md_get_algo (gcry_md_hd_t hd);
+
+/* Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. */
+unsigned int gcry_md_get_algo_dlen (int algo);
+
+/* Return true if the the algorithm ALGO is enabled in the digest
+ object A. */
+int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+
+/* Return true if the digest object A is allocated in "secure" memory. */
+int gcry_md_is_secure (gcry_md_hd_t a);
+
+/* Retrieve various information about the object H. */
+gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the algorithm ALGO. */
+gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns
+ "?". */
+const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a digest algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* For use with the HMAC feature, the set MAC key to the KEY of
+ KEYLEN bytes. */
+gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
+
+/* Start or stop debugging for digest handle HD; i.e. create a file
+ named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL,
+ debugging stops and the file will be closed. */
+void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+
+/* Update the hash(s) of H with the character C. This is a buffered
+ version of the gcry_md_write function. */
+#define gcry_md_putc(h,c) \
+ do { \
+ gcry_md_hd_t h__ = (h); \
+ if( (h__)->bufpos == (h__)->bufsize ) \
+ gcry_md_write( (h__), NULL, 0 ); \
+ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+ } while(0)
+
+/* Finalize the digest calculation. This is not really needed because
+ gcry_md_read() does this implicitly. */
+#define gcry_md_final(a) \
+ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_md_test_algo(a) \
+ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
+ must point to size_t variable with the available size of buffer B.
+ After return it will receive the actual size of the returned
+ OID. */
+#define gcry_md_get_asnoid(a,b,n) \
+ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+
+/* Enable debugging for digest object A; i.e. create files named
+ dbgmd-<n>.<string> while hashing. B is a string used as the suffix
+ for the filename. This macro is deprecated, use gcry_md_debug. */
+#ifndef GCRYPT_NO_DEPRECATED
+#define gcry_md_start_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
+
+/* Disable the debugging of A. This macro is deprecated, use
+ gcry_md_debug. */
+#define gcry_md_stop_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
+#endif
+
+/* Get a list consisting of the IDs of the loaded message digest
+ modules. If LIST is zero, write the number of loaded message
+ digest modules to LIST_LENGTH and return. If LIST is non-zero, the
+ first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+ of according size. In case there are less message digest modules
+ than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+ number. */
+gcry_error_t gcry_md_list (int *list, int *list_length);
+
+\f
+/* Alternative interface for asymmetric cryptography. This interface
+ is deprecated. */
+
+/* The algorithm IDs. */
+typedef enum gcry_ac_id
+ {
+ GCRY_AC_RSA = 1,
+ GCRY_AC_DSA = 17,
+ GCRY_AC_ELG = 20,
+ GCRY_AC_ELG_E = 16
+ }
+gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+
+/* Key types. */
+typedef enum gcry_ac_key_type
+ {
+ GCRY_AC_KEY_SECRET,
+ GCRY_AC_KEY_PUBLIC
+ }
+gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+
+/* Encoding methods. */
+typedef enum gcry_ac_em
+ {
+ GCRY_AC_EME_PKCS_V1_5,
+ GCRY_AC_EMSA_PKCS_V1_5
+ }
+gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+
+/* Encryption and Signature schemes. */
+typedef enum gcry_ac_scheme
+ {
+ GCRY_AC_ES_PKCS_V1_5,
+ GCRY_AC_SSA_PKCS_V1_5
+ }
+gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
+
+/* AC data. */
+#define GCRY_AC_FLAG_DEALLOC (1 << 0)
+#define GCRY_AC_FLAG_COPY (1 << 1)
+#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
+
+/* This type represents a `data set'. */
+typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a single `key', either a secret one or a
+ public one. */
+typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `key pair' containing a secret and a public
+ key. */
+typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `handle' that is needed by functions
+ performing cryptographic operations. */
+typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t *buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_WRITABLE
+ }
+gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_STRING,
+ GCRY_AC_IO_CALLBACK
+ }
+gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+
+typedef struct gcry_ac_io
+{
+ /* This is an INTERNAL structure, do NOT use manually. */
+ gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
+ gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
+ union
+ {
+ union
+ {
+ struct
+ {
+ gcry_ac_data_read_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char *data;
+ size_t data_n;
+ } string;
+ void *opaque;
+ } readable;
+ union
+ {
+ struct
+ {
+ gcry_ac_data_write_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char **data;
+ size_t *data_n;
+ } string;
+ void *opaque;
+ } writable;
+ } io _GCRY_ATTR_INTERNAL;
+}
+gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+
+/* The caller of gcry_ac_key_pair_generate can provide one of these
+ structures in order to influence the key generation process in an
+ algorithm-specific way. */
+typedef struct gcry_ac_key_spec_rsa
+{
+ gcry_mpi_t e; /* E to use. */
+} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EME-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_eme_pkcs_v1_5
+{
+ size_t key_size;
+} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EMSA-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_emsa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+ size_t em_n;
+} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `SSA-PKCS-V1_5' signature scheme. */
+typedef struct gcry_ac_ssa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+
+#ifndef GCRYPT_NO_DEPRECATED
+/* Returns a new, empty data set in DATA. */
+gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy the data set DATA. */
+void gcry_ac_data_destroy (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a copy of the data set DATA and store it in DATA_CP. */
+gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+ gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Return the number of named MPI values inside of the data set
+ DATA. */
+unsigned int gcry_ac_data_length (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy any values contained in the data set DATA. */
+void gcry_ac_data_clear (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Add the value MPI to DATA with the label NAME. If FLAGS contains
+ GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
+ and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
+ GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
+ be deallocated when they are to be removed from the data set. */
+gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the value labelled with NAME found in DATA in MPI. If FLAGS
+ contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
+ in the data set. MPI may be NULL. */
+gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+ set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY,
+ store copies of the values contained in the data set. NAME or MPI
+ may be NULL. */
+gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+ stored in SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+ S-Expression SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments AP. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new ac handle. */
+gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy an ac handle. */
+void gcry_ac_close (gcry_ac_handle_t handle)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize a key from a given data set. */
+gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+ stores it in KEY_PAIR. In case non-standard settings are wanted, a
+ pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+ matching the selected algorithm, can be given as KEY_SPEC.
+ MISC_DATA is not used yet. */
+gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
+gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the data set contained in the key KEY. */
+gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies that the key KEY is sane via HANDLE. */
+gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE. */
+gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+ HANDLE. */
+gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key. */
+void gcry_ac_key_destroy (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key pair. */
+void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
+ the control of the flags FLAGS and store the resulting data set
+ into DATA_ENCRYPTED. */
+gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
+ with the key KEY under the control of the flags FLAGS and store the
+ resulting plain text MPI value in DATA_PLAIN. */
+gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Sign the data contained in DATA with the key KEY and store the
+ resulting signature in the data set DATA_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verify that the signature contained in the data set DATA_SIGNATURE
+ is indeed the result of signing the data contained in DATA with the
+ secret key belonging to the public key KEY. */
+gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
+ with the public key KEY according to SCHEME, FLAGS and OPTS. If
+ OPTS is not NULL, it has to be a pointer to a structure specific to
+ the chosen scheme (gcry_ac_es_*_t). The encrypted message is
+ written to IO_CIPHER. */
+gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
+ with the secret key KEY according to SCHEME, @var{flags} and OPTS.
+ If OPTS is not NULL, it has to be a pointer to a structure specific
+ to the chosen scheme (gcry_ac_es_*_t). The decrypted message is
+ written to IO_MESSAGE. */
+gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Signs the message readable from IO_MESSAGE through HANDLE with the
+ secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not
+ NULL, it has to be a pointer to a structure specific to the chosen
+ scheme (gcry_ac_ssa_*_t). The signature is written to
+ IO_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies through HANDLE that the signature readable from
+ IO_SIGNATURE is indeed the result of signing the message readable
+ from IO_MESSAGE with the secret key belonging to the public key KEY
+ according to SCHEME and OPTS. If OPTS is not NULL, it has to be an
+ anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
+ scheme. */
+gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the textual representation of the algorithm whose id is given
+ in ALGORITHM in NAME. This function is deprecated; use
+ gcry_pk_algo_name. */
+gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
+ const char **name)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+/* Store the numeric ID of the algorithm whose textual representation
+ is contained in NAME in ALGORITHM. This function is deprecated;
+ use gcry_pk_map_name. */
+gcry_error_t gcry_ac_name_to_id (const char *name,
+ gcry_ac_id_t *algorithm)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+#endif /*GCRYPT_NO_DEPRECATED*/
+
+\f
+/******************************
+ * *
+ * Key Derivation Functions *
+ * *
+ ******************************/
+
+/* Algorithm IDs for the KDFs. */
+enum gcry_kdf_algos
+ {
+ GCRY_KDF_NONE = 0,
+ GCRY_KDF_SIMPLE_S2K = 16,
+ GCRY_KDF_SALTED_S2K = 17,
+ GCRY_KDF_ITERSALTED_S2K = 19,
+ GCRY_KDF_PBKDF1 = 33,
+ GCRY_KDF_PBKDF2 = 34
+ };
+
+/* Derive a key from a passphrase. */
+gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+
+
+\f
+/************************************
+ * *
+ * Random Generating Functions *
+ * *
+ ************************************/
+
+/* The possible values for the random quality. The rule of thumb is
+ to use STRONG for session keys and VERY_STRONG for key material.
+ WEAK is usually an alias for STRONG and should not be used anymore
+ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
+typedef enum gcry_random_level
+ {
+ GCRY_WEAK_RANDOM = 0,
+ GCRY_STRONG_RANDOM = 1,
+ GCRY_VERY_STRONG_RANDOM = 2
+ }
+gcry_random_level_t;
+
+/* Fill BUFFER with LENGTH bytes of random, using random numbers of
+ quality LEVEL. */
+void gcry_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+
+/* Add the external random from BUFFER with LENGTH bytes into the
+ pool. QUALITY should either be -1 for unknown or in the range of 0
+ to 100 */
+gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
+ int quality);
+
+/* If random numbers are used in an application, this macro should be
+ called from time to time so that new stuff gets added to the
+ internal pool of the RNG. */
+#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL)
+
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. */
+void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. The random numbers are created returned in "secure"
+ memory. */
+void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+
+/* Set the big integer W to a random value of NBITS using a random
+ generator with quality LEVEL. Note that by using a level of
+ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
+void gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level);
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void gcry_create_nonce (void *buffer, size_t length);
+
+
+
+
+\f
+/*******************************/
+/* */
+/* Prime Number Functions */
+/* */
+/*******************************/
+
+/* Mode values passed to a gcry_prime_check_func_t. */
+#define GCRY_PRIME_CHECK_AT_FINISH 0
+#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1
+#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
+
+/* The function should return 1 if the operation shall continue, 0 to
+ reject the prime candidate. */
+typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
+ gcry_mpi_t candidate);
+
+/* Flags for gcry_prime_generate(): */
+
+/* Allocate prime numbers and factors in secure memory. */
+#define GCRY_PRIME_FLAG_SECRET (1 << 0)
+
+/* Make sure that at least one prime factor is of size
+ `FACTOR_BITS'. */
+#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags);
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ teh start for the search. */
+gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime,
+ gcry_mpi_t *factors,
+ gcry_mpi_t start_g);
+
+
+/* Convenience function to release the FACTORS array. */
+void gcry_prime_release_factors (gcry_mpi_t *factors);
+
+
+/* Check wether the number X is prime. */
+gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+\f
+/************************************
+ * *
+ * Miscellaneous Stuff *
+ * *
+ ************************************/
+
+/* Log levels used by the internal logging facility. */
+enum gcry_log_levels
+ {
+ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */
+ GCRY_LOG_INFO = 10,
+ GCRY_LOG_WARN = 20,
+ GCRY_LOG_ERROR = 30,
+ GCRY_LOG_FATAL = 40,
+ GCRY_LOG_BUG = 50,
+ GCRY_LOG_DEBUG = 100
+ };
+
+/* Type for progress handlers. */
+typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
+
+/* Type for memory allocation handlers. */
+typedef void *(*gcry_handler_alloc_t) (size_t n);
+
+/* Type for secure memory check handlers. */
+typedef int (*gcry_handler_secure_check_t) (const void *);
+
+/* Type for memory reallocation handlers. */
+typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
+
+/* Type for memory free handlers. */
+typedef void (*gcry_handler_free_t) (void *);
+
+/* Type for out-of-memory handlers. */
+typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
+
+/* Type for fatal error handlers. */
+typedef void (*gcry_handler_error_t) (void *, int, const char *);
+
+/* Type for logging handlers. */
+typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
+
+/* Certain operations can provide progress information. This function
+ is used to register a handler for retrieving these information. */
+void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Register a custom memory allocation functions. */
+void gcry_set_allocation_handler (
+ gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free);
+
+/* Register a function used instead of the internal out of memory
+ handler. */
+void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+
+/* Register a function used instead of the internal fatal error
+ handler. */
+void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+
+/* Register a function used instead of the internal logging
+ facility. */
+void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+
+/* Reserved for future use. */
+void gcry_set_gettext_handler (const char *(*f)(const char*));
+
+/* Libgcrypt uses its own memory allocation. It is important to use
+ gcry_free () to release memory allocated by libgcrypt. */
+void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_realloc (void *a, size_t n);
+char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void gcry_free (void *a);
+
+/* Return true if A is allocated in "secure" memory. */
+int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+/* Return true if Libgcrypt is in FIPS mode. */
+#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+
+
+/* Include support for Libgcrypt modules. */
+#include <gcrypt-module.h>
+
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GCRYPT_H */
+/*
+Local Variables:
+buffer-read-only: t
+End:
+*/
--- /dev/null
+/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
+ 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+ File: @configure_input@ */
+
+#ifndef _GCRYPT_H
+#define _GCRYPT_H
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <gpg-error.h>
+
+#include <sys/types.h>
+
+#if defined _WIN32 || defined __WIN32__
+# include <winsock2.h>
+# include <ws2tcpip.h>
+# include <time.h>
+# ifndef __GNUC__
+ typedef long ssize_t;
+ typedef int pid_t;
+# endif /*!__GNUC__*/
+#else
+# include <sys/socket.h>
+# include <sys/time.h>
+#@INSERT_SYS_SELECT_H@
+#endif /*!_WIN32*/
+
+@FALLBACK_SOCKLEN_T@
+
+/* This is required for error code compatibility. */
+#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT
+
+#ifdef __cplusplus
+extern "C" {
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+}
+#endif
+#endif
+
+/* The version of this header should match the one of the library. It
+ should not be used by a program because gcry_check_version() should
+ return the same version. The purpose of this macro is to let
+ autoconf (using the AM_PATH_GCRYPT macro) check that this header
+ matches the installed library. */
+#define GCRYPT_VERSION "@VERSION@"
+
+/* Internal: We can't use the convenience macros for the multi
+ precision integer functions when building this library. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#ifndef GCRYPT_NO_MPI_MACROS
+#define GCRYPT_NO_MPI_MACROS 1
+#endif
+#endif
+
+/* We want to use gcc attributes when possible. Warning: Don't use
+ these macros in your programs: As indicated by the leading
+ underscore they are subject to change without notice. */
+#ifdef __GNUC__
+
+#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \
+ + __GNUC_MINOR__ * 100 \
+ + __GNUC_PATCHLEVEL__)
+
+#if _GCRY_GCC_VERSION >= 30100
+#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 29600
+#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__))
+#endif
+
+#if _GCRY_GCC_VERSION >= 30200
+#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__))
+#endif
+
+#endif /*__GNUC__*/
+
+#ifndef _GCRY_GCC_ATTR_DEPRECATED
+#define _GCRY_GCC_ATTR_DEPRECATED
+#endif
+#ifndef _GCRY_GCC_ATTR_PURE
+#define _GCRY_GCC_ATTR_PURE
+#endif
+#ifndef _GCRY_GCC_ATTR_MALLOC
+#define _GCRY_GCC_ATTR_MALLOC
+#endif
+
+/* Make up an attribute to mark functions and types as deprecated but
+ allow internal use by Libgcrypt. */
+#ifdef _GCRYPT_IN_LIBGCRYPT
+#define _GCRY_ATTR_INTERNAL
+#else
+#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED
+#endif
+
+/* Wrappers for the libgpg-error library. */
+
+typedef gpg_error_t gcry_error_t;
+typedef gpg_err_code_t gcry_err_code_t;
+typedef gpg_err_source_t gcry_err_source_t;
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_err_make (gcry_err_source_t source, gcry_err_code_t code)
+{
+ return gpg_err_make (source, code);
+}
+
+/* The user can define GPG_ERR_SOURCE_DEFAULT before including this
+ file to specify a default source for gpg_error. */
+#ifndef GCRY_ERR_SOURCE_DEFAULT
+#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1
+#endif
+
+static GPG_ERR_INLINE gcry_error_t
+gcry_error (gcry_err_code_t code)
+{
+ return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code);
+}
+
+static GPG_ERR_INLINE gcry_err_code_t
+gcry_err_code (gcry_error_t err)
+{
+ return gpg_err_code (err);
+}
+
+
+static GPG_ERR_INLINE gcry_err_source_t
+gcry_err_source (gcry_error_t err)
+{
+ return gpg_err_source (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *gcry_strerror (gcry_error_t err);
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *gcry_strsource (gcry_error_t err);
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t gcry_err_code_from_errno (int err);
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int gcry_err_code_to_errno (gcry_err_code_t code);
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
+
+/* Return an error value with the system error ERR. */
+gcry_err_code_t gcry_error_from_errno (int err);
+
+\f
+/* This enum is deprecated; it is only declared for the sake of
+ complete API compatibility. */
+enum gcry_thread_option
+ {
+ _GCRY_THREAD_OPTION_DUMMY
+ } _GCRY_GCC_ATTR_DEPRECATED;
+
+
+/* Constants defining the thread model to use. Used with the OPTION
+ field of the struct gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_DEFAULT 0
+#define GCRY_THREAD_OPTION_USER 1
+#define GCRY_THREAD_OPTION_PTH 2
+#define GCRY_THREAD_OPTION_PTHREAD 3
+
+/* The version number encoded in the OPTION field of the struct
+ gcry_thread_cbs. */
+#define GCRY_THREAD_OPTION_VERSION 0
+
+/* Wrapper for struct ath_ops. */
+struct gcry_thread_cbs
+{
+ /* The OPTION field encodes the thread model and the version number
+ of this structure.
+ Bits 7 - 0 are used for the thread model
+ Bits 15 - 8 are used for the version number.
+ */
+ unsigned int option;
+
+ int (*init) (void);
+ int (*mutex_init) (void **priv);
+ int (*mutex_destroy) (void **priv);
+ int (*mutex_lock) (void **priv);
+ int (*mutex_unlock) (void **priv);
+ ssize_t (*read) (int fd, void *buf, size_t nbytes);
+ ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, void *addr, int *length_ptr);
+ int (*connect) (int s, void *addr, gcry_socklen_t length);
+ int (*sendmsg) (int s, const void *msg, int flags);
+ int (*recvmsg) (int s, void *msg, int flags);
+#else
+ ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr);
+ int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length);
+ int (*sendmsg) (int s, const struct msghdr *msg, int flags);
+ int (*recvmsg) (int s, struct msghdr *msg, int flags);
+#endif
+};
+
+#ifdef _WIN32
+# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \
+static ssize_t gcry_pth_select (int nfd, void *rset, void *wset, \
+ void *eset, struct timeval *timeout) \
+ { return pth_select (nfd, rset, wset, eset, timeout); } \
+static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \
+ { return pth_waitpid (pid, status, options); } \
+static int gcry_pth_accept (int s, void *addr, \
+ gcry_socklen_t *length_ptr) \
+ { return pth_accept (s, addr, length_ptr); } \
+static int gcry_pth_connect (int s, void *addr, \
+ gcry_socklen_t length) \
+ { return pth_connect (s, addr, length); }
+#else /*!_WIN32*/
+# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \
+static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \
+ fd_set *eset, struct timeval *timeout) \
+ { return pth_select (nfd, rset, wset, eset, timeout); } \
+static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \
+ { return pth_waitpid (pid, status, options); } \
+static int gcry_pth_accept (int s, struct sockaddr *addr, \
+ gcry_socklen_t *length_ptr) \
+ { return pth_accept (s, addr, length_ptr); } \
+static int gcry_pth_connect (int s, struct sockaddr *addr, \
+ gcry_socklen_t length) \
+ { return pth_connect (s, addr, length); }
+#endif /*!_WIN32*/
+
+
+
+#define GCRY_THREAD_OPTION_PTH_IMPL \
+static int gcry_pth_init (void) \
+{ return (pth_init () == FALSE) ? errno : 0; } \
+static int gcry_pth_mutex_init (void **priv) \
+{ \
+ int err = 0; \
+ pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); \
+ \
+ if (!lock) \
+ err = ENOMEM; \
+ if (!err) \
+ { \
+ err = pth_mutex_init (lock); \
+ if (err == FALSE) \
+ err = errno; \
+ else \
+ err = 0; \
+ if (err) \
+ free (lock); \
+ else \
+ *priv = lock; \
+ } \
+ return err; \
+} \
+static int gcry_pth_mutex_destroy (void **lock) \
+ { /* GNU Pth has no destructor function. */ free (*lock); return 0; } \
+static int gcry_pth_mutex_lock (void **lock) \
+ { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE) \
+ ? errno : 0; } \
+static int gcry_pth_mutex_unlock (void **lock) \
+ { return ((pth_mutex_release (*lock)) == FALSE) \
+ ? errno : 0; } \
+static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes) \
+ { return pth_read (fd, buf, nbytes); } \
+static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes) \
+ { return pth_write (fd, buf, nbytes); } \
+_GCRY_THREAD_OPTION_PTH_IMPL_NET \
+ \
+/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg. */ \
+static struct gcry_thread_cbs gcry_threads_pth = { \
+ (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)), \
+ gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy, \
+ gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write, \
+ gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, \
+ NULL, NULL }
+
+
+#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
+static int gcry_pthread_mutex_init (void **priv) \
+{ \
+ int err = 0; \
+ pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\
+ \
+ if (!lock) \
+ err = ENOMEM; \
+ if (!err) \
+ { \
+ err = pthread_mutex_init (lock, NULL); \
+ if (err) \
+ free (lock); \
+ else \
+ *priv = lock; \
+ } \
+ return err; \
+} \
+static int gcry_pthread_mutex_destroy (void **lock) \
+ { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock); \
+ free (*lock); return err; } \
+static int gcry_pthread_mutex_lock (void **lock) \
+ { return pthread_mutex_lock ((pthread_mutex_t*)*lock); } \
+static int gcry_pthread_mutex_unlock (void **lock) \
+ { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); } \
+ \
+static struct gcry_thread_cbs gcry_threads_pthread = { \
+ (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), \
+ NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, \
+ gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock, \
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+
+\f
+/* The data object used to hold a multi precision integer. */
+struct gcry_mpi;
+typedef struct gcry_mpi *gcry_mpi_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+\f
+
+/* Check that the library fulfills the version requirement. */
+const char *gcry_check_version (const char *req_version);
+
+/* Codes for function dispatchers. */
+
+/* Codes used with the gcry_control function. */
+enum gcry_ctl_cmds
+ {
+ GCRYCTL_SET_KEY = 1,
+ GCRYCTL_SET_IV = 2,
+ GCRYCTL_CFB_SYNC = 3,
+ GCRYCTL_RESET = 4, /* e.g. for MDs */
+ GCRYCTL_FINALIZE = 5,
+ GCRYCTL_GET_KEYLEN = 6,
+ GCRYCTL_GET_BLKLEN = 7,
+ GCRYCTL_TEST_ALGO = 8,
+ GCRYCTL_IS_SECURE = 9,
+ GCRYCTL_GET_ASNOID = 10,
+ GCRYCTL_ENABLE_ALGO = 11,
+ GCRYCTL_DISABLE_ALGO = 12,
+ GCRYCTL_DUMP_RANDOM_STATS = 13,
+ GCRYCTL_DUMP_SECMEM_STATS = 14,
+ GCRYCTL_GET_ALGO_NPKEY = 15,
+ GCRYCTL_GET_ALGO_NSKEY = 16,
+ GCRYCTL_GET_ALGO_NSIGN = 17,
+ GCRYCTL_GET_ALGO_NENCR = 18,
+ GCRYCTL_SET_VERBOSITY = 19,
+ GCRYCTL_SET_DEBUG_FLAGS = 20,
+ GCRYCTL_CLEAR_DEBUG_FLAGS = 21,
+ GCRYCTL_USE_SECURE_RNDPOOL= 22,
+ GCRYCTL_DUMP_MEMORY_STATS = 23,
+ GCRYCTL_INIT_SECMEM = 24,
+ GCRYCTL_TERM_SECMEM = 25,
+ GCRYCTL_DISABLE_SECMEM_WARN = 27,
+ GCRYCTL_SUSPEND_SECMEM_WARN = 28,
+ GCRYCTL_RESUME_SECMEM_WARN = 29,
+ GCRYCTL_DROP_PRIVS = 30,
+ GCRYCTL_ENABLE_M_GUARD = 31,
+ GCRYCTL_START_DUMP = 32,
+ GCRYCTL_STOP_DUMP = 33,
+ GCRYCTL_GET_ALGO_USAGE = 34,
+ GCRYCTL_IS_ALGO_ENABLED = 35,
+ GCRYCTL_DISABLE_INTERNAL_LOCKING = 36,
+ GCRYCTL_DISABLE_SECMEM = 37,
+ GCRYCTL_INITIALIZATION_FINISHED = 38,
+ GCRYCTL_INITIALIZATION_FINISHED_P = 39,
+ GCRYCTL_ANY_INITIALIZATION_P = 40,
+ GCRYCTL_SET_CBC_CTS = 41,
+ GCRYCTL_SET_CBC_MAC = 42,
+ GCRYCTL_SET_CTR = 43,
+ GCRYCTL_ENABLE_QUICK_RANDOM = 44,
+ GCRYCTL_SET_RANDOM_SEED_FILE = 45,
+ GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
+ GCRYCTL_SET_THREAD_CBS = 47,
+ GCRYCTL_FAST_POLL = 48,
+ GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49,
+ GCRYCTL_USE_RANDOM_DAEMON = 50,
+ GCRYCTL_FAKED_RANDOM_P = 51,
+ GCRYCTL_SET_RNDEGD_SOCKET = 52,
+ GCRYCTL_PRINT_CONFIG = 53,
+ GCRYCTL_OPERATIONAL_P = 54,
+ GCRYCTL_FIPS_MODE_P = 55,
+ GCRYCTL_FORCE_FIPS_MODE = 56,
+ GCRYCTL_SELFTEST = 57,
+ /* Note: 58 .. 62 are used internally. */
+ GCRYCTL_DISABLE_HWF = 63
+ };
+
+/* Perform various operations defined by CMD. */
+gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...);
+
+\f
+/* S-expression management. */
+
+/* The object to represent an S-expression as used with the public key
+ functions. */
+struct gcry_sexp;
+typedef struct gcry_sexp *gcry_sexp_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* The possible values for the S-expression format. */
+enum gcry_sexp_format
+ {
+ GCRYSEXP_FMT_DEFAULT = 0,
+ GCRYSEXP_FMT_CANON = 1,
+ GCRYSEXP_FMT_BASE64 = 2,
+ GCRYSEXP_FMT_ADVANCED = 3
+ };
+
+/* Create an new S-expression object from BUFFER of size LENGTH and
+ return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER
+ is expected to be in canonized format. */
+gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect);
+
+ /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the
+ effect to transfer ownership of BUFFER to the created object. */
+gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *));
+
+/* Scan BUFFER and return a new S-expression object in RETSEXP. This
+ function expects a printf like string in BUFFER. */
+gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length);
+
+/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus
+ only be used for certain encodings. */
+gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...);
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list);
+
+/* Release the S-expression object SEXP */
+void gcry_sexp_release (gcry_sexp_t sexp);
+
+/* Calculate the length of an canonized S-expresion in BUFFER and
+ check for a valid encoding. */
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode);
+
+/* Copies the S-expression object SEXP into BUFFER using the format
+ specified in MODE. */
+size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+ size_t maxlength);
+
+/* Dumps the S-expression object A in a format suitable for debugging
+ to Libgcrypt's logging stream. */
+void gcry_sexp_dump (const gcry_sexp_t a);
+
+gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b);
+gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array);
+gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...);
+gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n);
+gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n);
+
+/* Scan the S-expression for a sublist with a type (the car of the
+ list) matching the string TOKEN. If TOKLEN is not 0, the token is
+ assumed to be raw memory of this length. The function returns a
+ newly allocated S-expression consisting of the found sublist or
+ `NULL' when not found. */
+gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list,
+ const char *tok, size_t toklen);
+/* Return the length of the LIST. For a valid S-expression this
+ should be at least 1. */
+int gcry_sexp_length (const gcry_sexp_t list);
+
+/* Create and return a new S-expression from the element with index
+ NUMBER in LIST. Note that the first element has the index 0. If
+ there is no such element, `NULL' is returned. */
+gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number);
+
+/* Create and return a new S-expression from the first element in
+ LIST; this called the "type" and should always exist and be a
+ string. `NULL' is returned in case of a problem. */
+gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list);
+
+/* Create and return a new list form all elements except for the first
+ one. Note, that this function may return an invalid S-expression
+ because it is not guaranteed, that the type exists and is a string.
+ However, for parsing a complex S-expression it might be useful for
+ intermediate lists. Returns `NULL' on error. */
+gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list);
+
+gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
+
+
+/* This function is used to get data from a LIST. A pointer to the
+ actual data with index NUMBER is returned and the length of this
+ data will be stored to DATALEN. If there is no data at the given
+ index or the index represents another list, `NULL' is returned.
+ *Note:* The returned pointer is valid as long as LIST is not
+ modified or released. */
+const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+ size_t *datalen);
+
+/* This function is used to get and convert data from a LIST. The
+ data is assumed to be a Nul terminated string. The caller must
+ release the returned value using `gcry_free'. If there is no data
+ at the given index, the index represents a list or the value can't
+ be converted to a string, `NULL' is returned. */
+char *gcry_sexp_nth_string (gcry_sexp_t list, int number);
+
+/* This function is used to get and convert data from a LIST. This
+ data is assumed to be an MPI stored in the format described by
+ MPIFMT and returned as a standard Libgcrypt MPI. The caller must
+ release this returned value using `gcry_mpi_release'. If there is
+ no data at the given index, the index represents a list or the
+ value can't be converted to an MPI, `NULL' is returned. */
+gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+
+
+\f
+/*******************************************
+ * *
+ * Multi Precision Integer Functions *
+ * *
+ *******************************************/
+
+/* Different formats of external big integer representation. */
+enum gcry_mpi_format
+ {
+ GCRYMPI_FMT_NONE= 0,
+ GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */
+ GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */
+ GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */
+ GCRYMPI_FMT_HEX = 4, /* Hex format. */
+ GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */
+ };
+
+/* Flags used for creating big integers. */
+enum gcry_mpi_flag
+ {
+ GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */
+ GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just
+ a way to store some bytes. This is
+ useful for encrypted big integers. */
+ };
+
+
+/* Allocate a new big integer object, initialize it with 0 and
+ initially allocate memory for a number of at least NBITS. */
+gcry_mpi_t gcry_mpi_new (unsigned int nbits);
+
+/* Same as gcry_mpi_new() but allocate in "secure" memory. */
+gcry_mpi_t gcry_mpi_snew (unsigned int nbits);
+
+/* Release the number A and free all associated resources. */
+void gcry_mpi_release (gcry_mpi_t a);
+
+/* Create a new number with the same value as A. */
+gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a);
+
+/* Store the big integer value U in W. */
+gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+
+/* Store the unsigned integer value U in W. */
+gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+
+/* Swap the values of A and B. */
+void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+
+/* Compare the big integer number U and V returning 0 for equality, a
+ positive value for U > V and a negative for U < V. */
+int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+
+/* Compare the big integer number U with the unsigned integer V
+ returning 0 for equality, a positive value for U > V and a negative
+ for U < V. */
+int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+
+/* Convert the external representation of an integer stored in BUFFER
+ with a length of BUFLEN into a newly create MPI returned in
+ RET_MPI. If NSCANNED is not NULL, it will receive the number of
+ bytes actually scanned after a successful operation. */
+gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned);
+
+/* Convert the big integer A into the external representation
+ described by FORMAT and store it in the provided BUFFER which has
+ been allocated by the user with a size of BUFLEN bytes. NWRITTEN
+ receives the actual length of the external representation unless it
+ has been passed as NULL. */
+gcry_error_t gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Convert the big integer A int the external representation described
+ by FORMAT and store it in a newly allocated buffer which address
+ will be put into BUFFER. NWRITTEN receives the actual lengths of the
+ external representation. */
+gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a);
+
+/* Dump the value of A in a format suitable for debugging to
+ Libgcrypt's logging stream. Note that one leading space but no
+ trailing space or linefeed will be printed. It is okay to pass
+ NULL for A. */
+void gcry_mpi_dump (const gcry_mpi_t a);
+
+
+/* W = U + V. */
+void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U + V. V is an unsigned integer. */
+void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+
+/* W = U + V mod M. */
+void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U - V. */
+void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U - V. V is an unsigned integer. */
+void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U - V mod M */
+void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * V. */
+void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+
+/* W = U * V. V is an unsigned integer. */
+void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+
+/* W = U * V mod M. */
+void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+
+/* W = U * (2 ^ CNT). */
+void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+
+/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR,
+ Q or R may be passed as NULL. ROUND should be negative or 0. */
+void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+
+/* R = DIVIDEND % DIVISOR */
+void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* W = B ^ E mod M. */
+void gcry_mpi_powm (gcry_mpi_t w,
+ const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m);
+
+/* Set G to the greatest common divisor of A and B.
+ Return true if the G is 1. */
+int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+
+/* Set X to the multiplicative inverse of A mod M.
+ Return true if the value exists. */
+int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+
+
+/* Return the number of bits required to represent A. */
+unsigned int gcry_mpi_get_nbits (gcry_mpi_t a);
+
+/* Return true when bit number N (counting from 0) is set in A. */
+int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A. */
+void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A. */
+void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+
+/* Set bit number N in A and clear all bits greater than N. */
+void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Clear bit number N in A and all bits greater than N. */
+void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the right and store the result in X. */
+void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Shift the value of A by N bits to the left and store the result in X. */
+void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+
+/* Store NBITS of the value P points to in A and mark A as an opaque
+ value. WARNING: Never use an opaque MPI for anything thing else then
+ gcry_mpi_release, gcry_mpi_get_opaque. */
+gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+
+/* Return a pointer to an opaque value stored in A and return its size
+ in NBITS. Note that the returned pointer is still owned by A and
+ that the function should never be used for an non-opaque MPI. */
+void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+
+/* Set the FLAG for the big integer A. Currently only the flag
+ GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger
+ stored in "secure" memory. */
+void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Clear FLAG for the big integer A. Note that this function is
+ currently useless as no flags are allowed. */
+void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Return true when the FLAG is set for A. */
+int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+
+/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of
+ convenience macros for the big integer functions. */
+#ifndef GCRYPT_NO_MPI_MACROS
+#define mpi_new(n) gcry_mpi_new( (n) )
+#define mpi_secure_new( n ) gcry_mpi_snew( (n) )
+#define mpi_release(a) \
+ do \
+ { \
+ gcry_mpi_release ((a)); \
+ (a) = NULL; \
+ } \
+ while (0)
+
+#define mpi_copy( a ) gcry_mpi_copy( (a) )
+#define mpi_set( w, u) gcry_mpi_set( (w), (u) )
+#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) )
+#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) )
+#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) )
+
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) )
+#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0)
+#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1)
+#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m))
+#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) )
+#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) )
+
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) )
+#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) )
+#endif /* GCRYPT_NO_MPI_MACROS */
+
+
+\f
+/************************************
+ * *
+ * Symmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The data object used to hold a handle to an encryption object. */
+struct gcry_cipher_handle;
+typedef struct gcry_cipher_handle *gcry_cipher_hd_t;
+
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* All symmetric encryption algorithms are identified by their IDs.
+ More IDs may be registered at runtime. */
+enum gcry_cipher_algos
+ {
+ GCRY_CIPHER_NONE = 0,
+ GCRY_CIPHER_IDEA = 1,
+ GCRY_CIPHER_3DES = 2,
+ GCRY_CIPHER_CAST5 = 3,
+ GCRY_CIPHER_BLOWFISH = 4,
+ GCRY_CIPHER_SAFER_SK128 = 5,
+ GCRY_CIPHER_DES_SK = 6,
+ GCRY_CIPHER_AES = 7,
+ GCRY_CIPHER_AES192 = 8,
+ GCRY_CIPHER_AES256 = 9,
+ GCRY_CIPHER_TWOFISH = 10,
+
+ /* Other cipher numbers are above 300 for OpenPGP reasons. */
+ GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */
+ GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */
+ GCRY_CIPHER_TWOFISH128 = 303,
+ GCRY_CIPHER_SERPENT128 = 304,
+ GCRY_CIPHER_SERPENT192 = 305,
+ GCRY_CIPHER_SERPENT256 = 306,
+ GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */
+ GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */
+ GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */
+ GCRY_CIPHER_CAMELLIA128 = 310,
+ GCRY_CIPHER_CAMELLIA192 = 311,
+ GCRY_CIPHER_CAMELLIA256 = 312
+ };
+
+/* The Rijndael algorithm is basically AES, so provide some macros. */
+#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES
+#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128
+#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192
+#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256
+
+/* The supported encryption modes. Note that not all of them are
+ supported for each algorithm. */
+enum gcry_cipher_modes
+ {
+ GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */
+ GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */
+ GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */
+ GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */
+ GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */
+ GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */
+ GCRY_CIPHER_MODE_CTR = 6, /* Counter. */
+ GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_cipher_flags
+ {
+ GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */
+ GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */
+ GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */
+ GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */
+ };
+
+
+/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may
+ be given as an bitwise OR of the gcry_cipher_flags values. */
+gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags);
+
+/* Close the cioher handle H and release all resource. */
+void gcry_cipher_close (gcry_cipher_hd_t h);
+
+/* Perform various operations on the cipher object H. */
+gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+ size_t buflen);
+
+/* Retrieve various information about the cipher object H. */
+gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the cipher algorithm ALGO. */
+gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the cipher algorithm whose ID is contained in ALGORITHM to a
+ string representation of the algorithm name. For unknown algorithm
+ IDs this function returns "?". */
+const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if
+ the algorithm name is not known. */
+int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+/* Given an ASN.1 object identifier in standard IETF dotted decimal
+ format in STRING, return the encryption mode associated with that
+ OID or 0 if not known or applicable. */
+int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+
+/* Encrypt the plaintext of size INLEN in IN using the cipher handle H
+ into the buffer OUT which has an allocated length of OUTSIZE. For
+ most algorithms it is possible to pass NULL for in and 0 for INLEN
+ and do a in-place decryption of the data provided in OUT. */
+gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* The counterpart to gcry_cipher_encrypt. */
+gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen);
+
+/* Set KEY of length KEYLEN bytes for the cipher handle HD. */
+gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd,
+ const void *key, size_t keylen);
+
+
+/* Set initialization vector IV of length IVLEN for the cipher handle HD. */
+gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
+ const void *iv, size_t ivlen);
+
+
+/* Reset the handle to the state after open. */
+#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+/* Perform the OpenPGP sync operation if this is enabled for the
+ cipher handle H. */
+#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0)
+
+/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */
+#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \
+ NULL, on )
+
+/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of
+ block size length, or (NULL,0) to set the CTR to the all-zero block. */
+gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
+ const void *ctr, size_t ctrlen);
+
+/* Retrieved the key length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_keylen (int algo);
+
+/* Retrieve the block length in bytes used with algorithm A. */
+size_t gcry_cipher_get_algo_blklen (int algo);
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_cipher_test_algo(a) \
+ gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded cipher modules. If
+ LIST is zero, write the number of loaded cipher modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_cipher_list (int *list, int *list_length);
+
+\f
+/************************************
+ * *
+ * Asymmetric Cipher Functions *
+ * *
+ ************************************/
+
+/* The algorithms and their IDs we support. */
+enum gcry_pk_algos
+ {
+ GCRY_PK_RSA = 1,
+ GCRY_PK_RSA_E = 2, /* (deprecated) */
+ GCRY_PK_RSA_S = 3, /* (deprecated) */
+ GCRY_PK_ELG_E = 16,
+ GCRY_PK_DSA = 17,
+ GCRY_PK_ELG = 20,
+ GCRY_PK_ECDSA = 301,
+ GCRY_PK_ECDH = 302
+ };
+
+/* Flags describing usage capabilities of a PK algorithm. */
+#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */
+#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */
+#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */
+#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */
+#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */
+
+/* Encrypt the DATA using the public key PKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Decrypt the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Sign the DATA using the private key SKEY and store the result as
+ a newly created S-expression at RESULT. */
+gcry_error_t gcry_pk_sign (gcry_sexp_t *result,
+ gcry_sexp_t data, gcry_sexp_t skey);
+
+/* Check the signature SIGVAL on DATA using the public key PKEY. */
+gcry_error_t gcry_pk_verify (gcry_sexp_t sigval,
+ gcry_sexp_t data, gcry_sexp_t pkey);
+
+/* Check that private KEY is sane. */
+gcry_error_t gcry_pk_testkey (gcry_sexp_t key);
+
+/* Generate a new key pair according to the parameters given in
+ S_PARMS. The new key pair is returned in as an S-expression in
+ R_KEY. */
+gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+
+/* Catch all function for miscellaneous operations. */
+gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+
+/* Retrieve information about the public key algorithm ALGO. */
+gcry_error_t gcry_pk_algo_info (int algo, int what,
+ void *buffer, size_t *nbytes);
+
+/* Map the public key algorithm whose ID is contained in ALGORITHM to
+ a string representation of the algorithm name. For unknown
+ algorithm IDs this functions returns "?". */
+const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a public key algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* Return what is commonly referred as the key length for the given
+ public or private KEY. */
+unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+
+/* Please note that keygrip is still experimental and should not be
+ used without contacting the author. */
+unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+
+/* Return the name of the curve matching KEY. */
+const char *gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+ unsigned int *r_nbits);
+
+/* Return an S-expression with the parameters of the named ECC curve
+ NAME. ALGO must be set to an ECC algorithm. */
+gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
+
+/* Return 0 if the public key algorithm A is available for use. */
+#define gcry_pk_test_algo(a) \
+ gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Get a list consisting of the IDs of the loaded pubkey modules. If
+ LIST is zero, write the number of loaded pubkey modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less pubkey modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_pk_list (int *list, int *list_length);
+
+\f
+
+/************************************
+ * *
+ * Cryptograhic Hash Functions *
+ * *
+ ************************************/
+
+/* Algorithm IDs for the hash functions we know about. Not all of them
+ are implemnted. */
+enum gcry_md_algos
+ {
+ GCRY_MD_NONE = 0,
+ GCRY_MD_MD5 = 1,
+ GCRY_MD_SHA1 = 2,
+ GCRY_MD_RMD160 = 3,
+ GCRY_MD_MD2 = 5,
+ GCRY_MD_TIGER = 6, /* TIGER/192 as used by gpg <= 1.3.2. */
+ GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */
+ GCRY_MD_SHA256 = 8,
+ GCRY_MD_SHA384 = 9,
+ GCRY_MD_SHA512 = 10,
+ GCRY_MD_SHA224 = 11,
+ GCRY_MD_MD4 = 301,
+ GCRY_MD_CRC32 = 302,
+ GCRY_MD_CRC32_RFC1510 = 303,
+ GCRY_MD_CRC24_RFC2440 = 304,
+ GCRY_MD_WHIRLPOOL = 305,
+ GCRY_MD_TIGER1 = 306, /* TIGER fixed. */
+ GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */
+ };
+
+/* Flags used with the open function. */
+enum gcry_md_flags
+ {
+ GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */
+ GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */
+ };
+
+/* (Forward declaration.) */
+struct gcry_md_context;
+
+/* This object is used to hold a handle to a message digest object.
+ This structure is private - only to be used by the public gcry_md_*
+ macros. */
+typedef struct gcry_md_handle
+{
+ /* Actual context. */
+ struct gcry_md_context *ctx;
+
+ /* Buffer management. */
+ int bufpos;
+ int bufsize;
+ unsigned char buf[1];
+} *gcry_md_hd_t;
+
+/* Compatibility types, do not use them. */
+#ifndef GCRYPT_NO_DEPRECATED
+typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED;
+typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED;
+#endif
+
+/* Create a message digest object for algorithm ALGO. FLAGS may be
+ given as an bitwise OR of the gcry_md_flags values. ALGO may be
+ given as 0 if the algorithms to be used are later set using
+ gcry_md_enable. */
+gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+
+/* Release the message digest object HD. */
+void gcry_md_close (gcry_md_hd_t hd);
+
+/* Add the message digest algorithm ALGO to the digest object HD. */
+gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo);
+
+/* Create a new digest object as an exact copy of the object HD. */
+gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+
+/* Reset the digest object HD to its initial state. */
+void gcry_md_reset (gcry_md_hd_t hd);
+
+/* Perform various operations on the digest object HD. */
+gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd,
+ void *buffer, size_t buflen);
+
+/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that
+ it can update the digest values. This is the actual hash
+ function. */
+void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length);
+
+/* Read out the final digest from HD return the digest value for
+ algorithm ALGO. */
+unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
+
+/* Convenience function to calculate the hash from the data in BUFFER
+ of size LENGTH using the algorithm ALGO avoiding the creating of a
+ hash object. The hash is returned in the caller provided buffer
+ DIGEST which must be large enough to hold the digest of the given
+ algorithm. */
+void gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length);
+
+/* Retrieve the algorithm used with HD. This does not work reliable
+ if more than one algorithm is enabled in HD. */
+int gcry_md_get_algo (gcry_md_hd_t hd);
+
+/* Retrieve the length in bytes of the digest yielded by algorithm
+ ALGO. */
+unsigned int gcry_md_get_algo_dlen (int algo);
+
+/* Return true if the the algorithm ALGO is enabled in the digest
+ object A. */
+int gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+
+/* Return true if the digest object A is allocated in "secure" memory. */
+int gcry_md_is_secure (gcry_md_hd_t a);
+
+/* Retrieve various information about the object H. */
+gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+ size_t *nbytes);
+
+/* Retrieve various information about the algorithm ALGO. */
+gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer,
+ size_t *nbytes);
+
+/* Map the digest algorithm id ALGO to a string representation of the
+ algorithm name. For unknown algorithms this function returns
+ "?". */
+const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+
+/* Map the algorithm NAME to a digest algorithm Id. Return 0 if
+ the algorithm name is not known. */
+int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+
+/* For use with the HMAC feature, the set MAC key to the KEY of
+ KEYLEN bytes. */
+gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen);
+
+/* Start or stop debugging for digest handle HD; i.e. create a file
+ named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL,
+ debugging stops and the file will be closed. */
+void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+
+/* Update the hash(s) of H with the character C. This is a buffered
+ version of the gcry_md_write function. */
+#define gcry_md_putc(h,c) \
+ do { \
+ gcry_md_hd_t h__ = (h); \
+ if( (h__)->bufpos == (h__)->bufsize ) \
+ gcry_md_write( (h__), NULL, 0 ); \
+ (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \
+ } while(0)
+
+/* Finalize the digest calculation. This is not really needed because
+ gcry_md_read() does this implicitly. */
+#define gcry_md_final(a) \
+ gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+/* Return 0 if the algorithm A is available for use. */
+#define gcry_md_test_algo(a) \
+ gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+
+/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N
+ must point to size_t variable with the available size of buffer B.
+ After return it will receive the actual size of the returned
+ OID. */
+#define gcry_md_get_asnoid(a,b,n) \
+ gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+
+/* Enable debugging for digest object A; i.e. create files named
+ dbgmd-<n>.<string> while hashing. B is a string used as the suffix
+ for the filename. This macro is deprecated, use gcry_md_debug. */
+#ifndef GCRYPT_NO_DEPRECATED
+#define gcry_md_start_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
+
+/* Disable the debugging of A. This macro is deprecated, use
+ gcry_md_debug. */
+#define gcry_md_stop_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
+#endif
+
+/* Get a list consisting of the IDs of the loaded message digest
+ modules. If LIST is zero, write the number of loaded message
+ digest modules to LIST_LENGTH and return. If LIST is non-zero, the
+ first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+ of according size. In case there are less message digest modules
+ than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+ number. */
+gcry_error_t gcry_md_list (int *list, int *list_length);
+
+\f
+/* Alternative interface for asymmetric cryptography. This interface
+ is deprecated. */
+
+/* The algorithm IDs. */
+typedef enum gcry_ac_id
+ {
+ GCRY_AC_RSA = 1,
+ GCRY_AC_DSA = 17,
+ GCRY_AC_ELG = 20,
+ GCRY_AC_ELG_E = 16
+ }
+gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+
+/* Key types. */
+typedef enum gcry_ac_key_type
+ {
+ GCRY_AC_KEY_SECRET,
+ GCRY_AC_KEY_PUBLIC
+ }
+gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+
+/* Encoding methods. */
+typedef enum gcry_ac_em
+ {
+ GCRY_AC_EME_PKCS_V1_5,
+ GCRY_AC_EMSA_PKCS_V1_5
+ }
+gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+
+/* Encryption and Signature schemes. */
+typedef enum gcry_ac_scheme
+ {
+ GCRY_AC_ES_PKCS_V1_5,
+ GCRY_AC_SSA_PKCS_V1_5
+ }
+gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
+
+/* AC data. */
+#define GCRY_AC_FLAG_DEALLOC (1 << 0)
+#define GCRY_AC_FLAG_COPY (1 << 1)
+#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
+
+/* This type represents a `data set'. */
+typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a single `key', either a secret one or a
+ public one. */
+typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `key pair' containing a secret and a public
+ key. */
+typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `handle' that is needed by functions
+ performing cryptographic operations. */
+typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t *buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_WRITABLE
+ }
+gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_STRING,
+ GCRY_AC_IO_CALLBACK
+ }
+gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+
+typedef struct gcry_ac_io
+{
+ /* This is an INTERNAL structure, do NOT use manually. */
+ gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
+ gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
+ union
+ {
+ union
+ {
+ struct
+ {
+ gcry_ac_data_read_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char *data;
+ size_t data_n;
+ } string;
+ void *opaque;
+ } readable;
+ union
+ {
+ struct
+ {
+ gcry_ac_data_write_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char **data;
+ size_t *data_n;
+ } string;
+ void *opaque;
+ } writable;
+ } io _GCRY_ATTR_INTERNAL;
+}
+gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+
+/* The caller of gcry_ac_key_pair_generate can provide one of these
+ structures in order to influence the key generation process in an
+ algorithm-specific way. */
+typedef struct gcry_ac_key_spec_rsa
+{
+ gcry_mpi_t e; /* E to use. */
+} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EME-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_eme_pkcs_v1_5
+{
+ size_t key_size;
+} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EMSA-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_emsa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+ size_t em_n;
+} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `SSA-PKCS-V1_5' signature scheme. */
+typedef struct gcry_ac_ssa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+
+#ifndef GCRYPT_NO_DEPRECATED
+/* Returns a new, empty data set in DATA. */
+gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy the data set DATA. */
+void gcry_ac_data_destroy (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a copy of the data set DATA and store it in DATA_CP. */
+gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+ gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Return the number of named MPI values inside of the data set
+ DATA. */
+unsigned int gcry_ac_data_length (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy any values contained in the data set DATA. */
+void gcry_ac_data_clear (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Add the value MPI to DATA with the label NAME. If FLAGS contains
+ GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
+ and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
+ GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
+ be deallocated when they are to be removed from the data set. */
+gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the value labelled with NAME found in DATA in MPI. If FLAGS
+ contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
+ in the data set. MPI may be NULL. */
+gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+ set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY,
+ store copies of the values contained in the data set. NAME or MPI
+ may be NULL. */
+gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+ stored in SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+ S-Expression SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments AP. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new ac handle. */
+gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy an ac handle. */
+void gcry_ac_close (gcry_ac_handle_t handle)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize a key from a given data set. */
+gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+ stores it in KEY_PAIR. In case non-standard settings are wanted, a
+ pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+ matching the selected algorithm, can be given as KEY_SPEC.
+ MISC_DATA is not used yet. */
+gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
+gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the data set contained in the key KEY. */
+gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies that the key KEY is sane via HANDLE. */
+gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE. */
+gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+ HANDLE. */
+gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key. */
+void gcry_ac_key_destroy (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key pair. */
+void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
+ the control of the flags FLAGS and store the resulting data set
+ into DATA_ENCRYPTED. */
+gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
+ with the key KEY under the control of the flags FLAGS and store the
+ resulting plain text MPI value in DATA_PLAIN. */
+gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Sign the data contained in DATA with the key KEY and store the
+ resulting signature in the data set DATA_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verify that the signature contained in the data set DATA_SIGNATURE
+ is indeed the result of signing the data contained in DATA with the
+ secret key belonging to the public key KEY. */
+gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
+ with the public key KEY according to SCHEME, FLAGS and OPTS. If
+ OPTS is not NULL, it has to be a pointer to a structure specific to
+ the chosen scheme (gcry_ac_es_*_t). The encrypted message is
+ written to IO_CIPHER. */
+gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
+ with the secret key KEY according to SCHEME, @var{flags} and OPTS.
+ If OPTS is not NULL, it has to be a pointer to a structure specific
+ to the chosen scheme (gcry_ac_es_*_t). The decrypted message is
+ written to IO_MESSAGE. */
+gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Signs the message readable from IO_MESSAGE through HANDLE with the
+ secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not
+ NULL, it has to be a pointer to a structure specific to the chosen
+ scheme (gcry_ac_ssa_*_t). The signature is written to
+ IO_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies through HANDLE that the signature readable from
+ IO_SIGNATURE is indeed the result of signing the message readable
+ from IO_MESSAGE with the secret key belonging to the public key KEY
+ according to SCHEME and OPTS. If OPTS is not NULL, it has to be an
+ anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
+ scheme. */
+gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the textual representation of the algorithm whose id is given
+ in ALGORITHM in NAME. This function is deprecated; use
+ gcry_pk_algo_name. */
+gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
+ const char **name)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+/* Store the numeric ID of the algorithm whose textual representation
+ is contained in NAME in ALGORITHM. This function is deprecated;
+ use gcry_pk_map_name. */
+gcry_error_t gcry_ac_name_to_id (const char *name,
+ gcry_ac_id_t *algorithm)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+#endif /*GCRYPT_NO_DEPRECATED*/
+
+\f
+/******************************
+ * *
+ * Key Derivation Functions *
+ * *
+ ******************************/
+
+/* Algorithm IDs for the KDFs. */
+enum gcry_kdf_algos
+ {
+ GCRY_KDF_NONE = 0,
+ GCRY_KDF_SIMPLE_S2K = 16,
+ GCRY_KDF_SALTED_S2K = 17,
+ GCRY_KDF_ITERSALTED_S2K = 19,
+ GCRY_KDF_PBKDF1 = 33,
+ GCRY_KDF_PBKDF2 = 34
+ };
+
+/* Derive a key from a passphrase. */
+gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer);
+
+
+
+\f
+/************************************
+ * *
+ * Random Generating Functions *
+ * *
+ ************************************/
+
+/* The possible values for the random quality. The rule of thumb is
+ to use STRONG for session keys and VERY_STRONG for key material.
+ WEAK is usually an alias for STRONG and should not be used anymore
+ (except with gcry_mpi_randomize); use gcry_create_nonce instead. */
+typedef enum gcry_random_level
+ {
+ GCRY_WEAK_RANDOM = 0,
+ GCRY_STRONG_RANDOM = 1,
+ GCRY_VERY_STRONG_RANDOM = 2
+ }
+gcry_random_level_t;
+
+/* Fill BUFFER with LENGTH bytes of random, using random numbers of
+ quality LEVEL. */
+void gcry_randomize (void *buffer, size_t length,
+ enum gcry_random_level level);
+
+/* Add the external random from BUFFER with LENGTH bytes into the
+ pool. QUALITY should either be -1 for unknown or in the range of 0
+ to 100 */
+gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length,
+ int quality);
+
+/* If random numbers are used in an application, this macro should be
+ called from time to time so that new stuff gets added to the
+ internal pool of the RNG. */
+#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL)
+
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. */
+void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+/* Return NBYTES of allocated random using a random numbers of quality
+ LEVEL. The random numbers are created returned in "secure"
+ memory. */
+void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+ _GCRY_GCC_ATTR_MALLOC;
+
+
+/* Set the big integer W to a random value of NBITS using a random
+ generator with quality LEVEL. Note that by using a level of
+ GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */
+void gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level);
+
+
+/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
+void gcry_create_nonce (void *buffer, size_t length);
+
+
+
+
+\f
+/*******************************/
+/* */
+/* Prime Number Functions */
+/* */
+/*******************************/
+
+/* Mode values passed to a gcry_prime_check_func_t. */
+#define GCRY_PRIME_CHECK_AT_FINISH 0
+#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1
+#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2
+
+/* The function should return 1 if the operation shall continue, 0 to
+ reject the prime candidate. */
+typedef int (*gcry_prime_check_func_t) (void *arg, int mode,
+ gcry_mpi_t candidate);
+
+/* Flags for gcry_prime_generate(): */
+
+/* Allocate prime numbers and factors in secure memory. */
+#define GCRY_PRIME_FLAG_SECRET (1 << 0)
+
+/* Make sure that at least one prime factor is of size
+ `FACTOR_BITS'. */
+#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1)
+
+/* Generate a new prime number of PRIME_BITS bits and store it in
+ PRIME. If FACTOR_BITS is non-zero, one of the prime factors of
+ (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is
+ non-zero, allocate a new, NULL-terminated array holding the prime
+ factors and store it in FACTORS. FLAGS might be used to influence
+ the prime number generation process. */
+gcry_error_t gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags);
+
+/* Find a generator for PRIME where the factorization of (prime-1) is
+ in the NULL terminated array FACTORS. Return the generator as a
+ newly allocated MPI in R_G. If START_G is not NULL, use this as
+ teh start for the search. */
+gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime,
+ gcry_mpi_t *factors,
+ gcry_mpi_t start_g);
+
+
+/* Convenience function to release the FACTORS array. */
+void gcry_prime_release_factors (gcry_mpi_t *factors);
+
+
+/* Check wether the number X is prime. */
+gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+
+\f
+/************************************
+ * *
+ * Miscellaneous Stuff *
+ * *
+ ************************************/
+
+/* Log levels used by the internal logging facility. */
+enum gcry_log_levels
+ {
+ GCRY_LOG_CONT = 0, /* (Continue the last log line.) */
+ GCRY_LOG_INFO = 10,
+ GCRY_LOG_WARN = 20,
+ GCRY_LOG_ERROR = 30,
+ GCRY_LOG_FATAL = 40,
+ GCRY_LOG_BUG = 50,
+ GCRY_LOG_DEBUG = 100
+ };
+
+/* Type for progress handlers. */
+typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int);
+
+/* Type for memory allocation handlers. */
+typedef void *(*gcry_handler_alloc_t) (size_t n);
+
+/* Type for secure memory check handlers. */
+typedef int (*gcry_handler_secure_check_t) (const void *);
+
+/* Type for memory reallocation handlers. */
+typedef void *(*gcry_handler_realloc_t) (void *p, size_t n);
+
+/* Type for memory free handlers. */
+typedef void (*gcry_handler_free_t) (void *);
+
+/* Type for out-of-memory handlers. */
+typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int);
+
+/* Type for fatal error handlers. */
+typedef void (*gcry_handler_error_t) (void *, int, const char *);
+
+/* Type for logging handlers. */
+typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list);
+
+/* Certain operations can provide progress information. This function
+ is used to register a handler for retrieving these information. */
+void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+
+/* Register a custom memory allocation functions. */
+void gcry_set_allocation_handler (
+ gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free);
+
+/* Register a function used instead of the internal out of memory
+ handler. */
+void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+
+/* Register a function used instead of the internal fatal error
+ handler. */
+void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+
+/* Register a function used instead of the internal logging
+ facility. */
+void gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+
+/* Reserved for future use. */
+void gcry_set_gettext_handler (const char *(*f)(const char*));
+
+/* Libgcrypt uses its own memory allocation. It is important to use
+ gcry_free () to release memory allocated by libgcrypt. */
+void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_realloc (void *a, size_t n);
+char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC;
+void *gcry_xrealloc (void *a, size_t n);
+char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC;
+void gcry_free (void *a);
+
+/* Return true if A is allocated in "secure" memory. */
+int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+/* Return true if Libgcrypt is in FIPS mode. */
+#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+
+
+/* Include support for Libgcrypt modules. */
+#include <gcrypt-module.h>
+
+#if 0 /* (Keep Emacsens' auto-indent happy.) */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GCRYPT_H */
+/*
+@emacs_local_vars_begin@
+@emacs_local_vars_read_only@
+@emacs_local_vars_end@
+*/
--- /dev/null
+/* gcryptrnd.c - Libgcrypt Random Number Daemon
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Gcryptend is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Gcryptrnd 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/* We require vsyslog pth
+ We need to test for: setrlimit
+
+ We should also prioritize requests. This is best done by putting
+ the requests into queues and have a main thread processing these
+ queues.
+
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pth.h>
+#include <gcrypt.h>
+
+#define PGM "gcryptrnd"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+/* Pth wrapper function definitions. */
+GCRY_THREAD_OPTION_PTH_IMPL;
+
+
+/* Flag set to true if we have been daemonized. */
+static int running_detached;
+/* Flag indicating that a shutdown has been requested. */
+static int shutdown_pending;
+/* Counter for active connections. */
+static int active_connections;
+
+
+
+/* Local prototypes. */
+static void serve (int listen_fd);
+
+
+
+\f
+
+/* To avoid that a compiler optimizes certain memset calls away, these
+ macros may be used instead. */
+#define wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
+
+
+
+
+/* Error printing utility. PRIORITY should be one of syslog's
+ priority levels. This functions prints to the stderr or syslog
+ depending on whether we are already daemonized. */
+static void
+logit (int priority, const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ if (running_detached)
+ {
+ vsyslog (priority, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ }
+ va_end (arg_ptr);
+}
+
+/* Callback used by libgcrypt for logging. */
+static void
+my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
+{
+ (void)dummy;
+
+ /* Map the log levels. */
+ switch (level)
+ {
+ case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
+ case GCRY_LOG_INFO: level = LOG_INFO; break;
+ case GCRY_LOG_WARN: level = LOG_WARNING; break;
+ case GCRY_LOG_ERROR:level = LOG_ERR; break;
+ case GCRY_LOG_FATAL:level = LOG_CRIT; break;
+ case GCRY_LOG_BUG: level = LOG_CRIT; break;
+ case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
+ default: level = LOG_ERR; break;
+ }
+ if (running_detached)
+ {
+ vsyslog (level, format, arg_ptr);
+ }
+ else
+ {
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ if (!*format || format[strlen (format)-1] != '\n')
+ putc ('\n', stderr);
+ }
+}
+
+
+/* The cleanup handler - used to wipe out the secure memory. */
+static void
+cleanup (void)
+{
+ gcry_control (GCRYCTL_TERM_SECMEM );
+}
+
+
+/* Make us a daemon and open the syslog. */
+static void
+daemonize (void)
+{
+ int i;
+ pid_t pid;
+
+ fflush (NULL);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, "fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0);
+
+ if (setsid() == -1)
+ {
+ logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
+ exit (1);
+ }
+
+ signal (SIGHUP, SIG_IGN);
+
+ pid = fork ();
+ if (pid == (pid_t)-1)
+ {
+ logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
+ exit (1);
+ }
+ if (pid)
+ exit (0); /* First child exits. */
+
+ running_detached = 1;
+
+ if (chdir("/"))
+ {
+ logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
+ exit (1);
+ }
+ umask (0);
+
+ for (i=0; i <= 2; i++)
+ close (i);
+
+ openlog (PGM, LOG_PID, LOG_DAEMON);
+}
+
+
+static void
+disable_core_dumps (void)
+{
+#ifdef HAVE_SETRLIMIT
+ struct rlimit limit;
+
+ if (getrlimit (RLIMIT_CORE, &limit))
+ limit.rlim_max = 0;
+ limit.rlim_cur = 0;
+ if( !setrlimit (RLIMIT_CORE, &limit) )
+ return 0;
+ if (errno != EINVAL && errno != ENOSYS)
+ logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
+#endif /* HAVE_SETRLIMIT */
+}
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
+ "Start Libgcrypt's random number daemon listening"
+ " on socket SOCKETNAME\n"
+ "SOCKETNAME defaults to XXX\n"
+ "\n"
+ " --no-detach do not deatach from the console\n"
+ " --version print version of the program and exit\n"
+ " --help display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int no_detach = 0;
+ gpg_error_t err;
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--no-detach"))
+ {
+ no_detach = 1;
+ argc--; argv++;
+ }
+ else
+ print_usage ();
+ }
+
+ if (argc == 1)
+ socketname = argv[0];
+ else if (argc > 1)
+ print_usage ();
+
+ if (!no_detach)
+ daemonize ();
+
+ signal (SIGPIPE, SIG_IGN);
+
+ logit (LOG_NOTICE, "started version " VERSION );
+
+ /* Libgcrypt requires us to register the threading model before we
+ do anything else with it. Note that this also calls pth_init. We
+ do the initialization while already running as a daemon to avoid
+ overhead with double initialization of Libgcrypt. */
+ err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
+ if (err)
+ {
+ logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
+ gpg_strerror (err));
+ exit (1);
+ }
+
+ /* Check that the libgcrypt version is sufficient. */
+ if (!gcry_check_version (VERSION) )
+ {
+ logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
+ VERSION, gcry_check_version (NULL) );
+ exit (1);
+ }
+
+ /* Register the logging callback and tell Libcgrypt to put the
+ random pool into secure memory. */
+ gcry_set_log_handler (my_gcry_logger, NULL);
+ gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
+
+ /* Obviously we don't want to allow any core dumps. */
+ disable_core_dumps ();
+
+ /* Initialize the secure memory stuff which will also drop any extra
+ privileges we have. */
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ /* Register a cleanup handler. */
+ atexit (cleanup);
+
+ /* Create and listen on the socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit (LOG_CRIT, "socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1 && errno == EADDRINUSE)
+ {
+ remove (socketname);
+ rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
+ }
+ if (rc == -1)
+ {
+ logit (LOG_CRIT, "error binding socket to `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ if (listen (fd, 5 ) == -1)
+ {
+ logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ logit (LOG_INFO, "listening on socket `%s', fd=%d",
+ srvr_addr->sun_path, fd);
+
+ serve (fd);
+ close (fd);
+
+ logit (LOG_NOTICE, "stopped version " VERSION );
+ return 0;
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n = pth_write (fd, buffer, length);
+ if (n < 0)
+ {
+ logit (LOG_ERR, "connection %d: write error: %s",
+ fd, strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char*)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+/* Send an error response back. Returns 0 on success. */
+static int
+send_error (int fd, int errcode)
+{
+ unsigned char buf[2];
+
+ buf[0] = errcode;
+ buf[1] = 0;
+ return writen (fd, buf, 2 );
+}
+
+/* Send a pong response back. Returns 0 on success or another value
+ on write error. */
+static int
+send_pong (int fd)
+{
+ return writen (fd, "\x00\x04pong", 6);
+}
+
+/* Send a nonce of size LENGTH back. Return 0 on success. */
+static int
+send_nonce (int fd, int length)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ buf[0] = 0;
+ buf[1] = length;
+ gcry_create_nonce (buf+2, length);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
+ success. */
+static int
+send_random (int fd, int length, int level)
+{
+ unsigned char buf[2+255];
+ int rc;
+
+ assert (length >= 0 && length <= 255);
+ assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
+ buf[0] = 0;
+ buf[1] = length;
+ /* Note that we don't bother putting the random stuff into secure
+ memory because this daemon is anyway intended to be run under
+ root and it is questionable whether the kernel buffers etc. are
+ equally well protected. */
+ gcry_randomize (buf+2, length, level);
+ rc = writen (fd, buf, 2+length );
+ wipememory (buf+2, length);
+ return rc;
+}
+
+/* Main processing loop for a connection.
+
+ A request is made up of:
+
+ 1 byte Total length of request; must be 3
+ 1 byte Command
+ 0 = Ping
+ 10 = GetNonce
+ 11 = GetStrongRandom
+ 12 = GetVeryStrongRandom
+ (all other values are reserved)
+ 1 byte Number of requested bytes.
+ This is ignored for command Ping.
+
+ A response is made up of:
+
+ 1 byte Error Code
+ 0 = Everything is fine
+ 1 = Bad Command
+ 0xff = Other error.
+ (For a bad request the connection will simply be closed)
+ 1 byte Length of data
+ n byte data
+
+ The requests are read as long as the connection is open.
+
+
+ */
+static void
+connection_loop (int fd)
+{
+ unsigned char request[3];
+ unsigned char *p;
+ int nleft, n;
+ int rc;
+
+ for (;;)
+ {
+ for (nleft=3, p=request; nleft > 0; )
+ {
+ n = pth_read (fd, p, nleft);
+ if (!n && p == request)
+ return; /* Client terminated connection. */
+ if (n <= 0)
+ {
+ logit (LOG_ERR, "connection %d: read error: %s",
+ fd, n? strerror (errno) : "Unexpected EOF");
+ return;
+ }
+ p += n;
+ nleft -= n;
+ }
+ if (request[0] != 3)
+ {
+ logit (LOG_ERR, "connection %d: invalid length (%d) of request",
+ fd, request[0]);
+ return;
+ }
+
+ switch (request[1])
+ {
+ case 0: /* Ping */
+ rc = send_pong (fd);
+ break;
+ case 10: /* GetNonce */
+ rc = send_nonce (fd, request[2]);
+ break;
+ case 11: /* GetStrongRandom */
+ rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
+ break;
+ case 12: /* GetVeryStrongRandom */
+ rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
+ break;
+
+ default: /* Invalid command */
+ rc = send_error (fd, 1);
+ break;
+ }
+ if (rc)
+ break; /* A write error occurred while sending the response. */
+ }
+}
+
+
+
+/* Entry point for a connection's thread. */
+static void *
+connection_thread (void *arg)
+{
+ int fd = (int)arg;
+
+ active_connections++;
+ logit (LOG_INFO, "connection handler for fd %d started", fd);
+
+ connection_loop (fd);
+
+ close (fd);
+ logit (LOG_INFO, "connection handler for fd %d terminated", fd);
+ active_connections--;
+
+ return NULL;
+}
+
+
+/* This signal handler is called from the main loop between acepting
+ connections. It is called on the regular stack, thus no special
+ caution needs to be taken. It returns true to indicate that the
+ process should terminate. */
+static int
+handle_signal (int signo)
+{
+ switch (signo)
+ {
+ case SIGHUP:
+ logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
+ break;
+
+ case SIGUSR1:
+ logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
+ break;
+
+ case SIGUSR2:
+ logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
+ break;
+
+ case SIGTERM:
+ if (!shutdown_pending)
+ logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
+ else
+ logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
+ active_connections);
+ shutdown_pending++;
+ if (shutdown_pending > 2)
+ {
+ logit (LOG_NOTICE, "shutdown forced");
+ return 1;
+ }
+ break;
+
+ case SIGINT:
+ logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
+ return 1;
+
+ default:
+ logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
+ }
+ return 0;
+}
+
+
+
+/* Main server loop. This is called with the FD of the listening
+ socket. */
+static void
+serve (int listen_fd)
+{
+ pth_attr_t tattr;
+ pth_event_t ev;
+ sigset_t sigs;
+ int signo;
+ struct sockaddr_un paddr;
+ socklen_t plen = sizeof (paddr);
+ int fd;
+
+ tattr = pth_attr_new();
+ pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
+ pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
+ pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
+
+ sigemptyset (&sigs);
+ sigaddset (&sigs, SIGHUP);
+ sigaddset (&sigs, SIGUSR1);
+ sigaddset (&sigs, SIGUSR2);
+ sigaddset (&sigs, SIGINT);
+ sigaddset (&sigs, SIGTERM);
+ ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
+
+ for (;;)
+ {
+ if (shutdown_pending)
+ {
+ if (!active_connections)
+ break; /* Ready. */
+
+ /* Do not accept anymore connections but wait for existing
+ connections to terminate. */
+ signo = 0;
+ pth_wait (ev);
+ if (pth_event_occurred (ev) && signo)
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+
+ gcry_fast_random_poll ();
+ fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
+ if (fd == -1)
+ {
+ if (pth_event_occurred (ev))
+ {
+ if (handle_signal (signo))
+ break; /* Stop the loop. */
+ continue;
+ }
+ logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
+ strerror (errno));
+ gcry_fast_random_poll ();
+ pth_sleep (1);
+ continue;
+ }
+
+ if (!pth_spawn (tattr, connection_thread, (void*)fd))
+ {
+ logit (LOG_ERR, "error spawning connection handler: %s\n",
+ strerror (errno) );
+ close (fd);
+ }
+ }
+
+ pth_event_free (ev, PTH_FREE_ALL);
+}
--- /dev/null
+/* getrandom.c - Libgcrypt Random Number client
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * Getrandom is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * Getrandom 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define PGM "getrandom"
+#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
+#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
+
+
+static void
+logit (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format) ;
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ putc ('\n', stderr);
+ va_end (arg_ptr);
+}
+
+
+/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
+ success or another value on write error. */
+static int
+writen (int fd, const void *buffer, size_t length)
+{
+ while (length)
+ {
+ ssize_t n;
+
+ do
+ n = write (fd, buffer, length);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("write error: %s", strerror (errno));
+ return -1; /* write error */
+ }
+ length -= n;
+ buffer = (const char *)buffer + n;
+ }
+ return 0; /* Okay */
+}
+
+
+
+
+static void
+print_version (int with_help)
+{
+ fputs (MYVERSION_LINE "\n"
+ "Copyright (C) 2006 Free Software Foundation, Inc.\n"
+ "License GPLv2+: GNU GPL version 2 or later "
+ "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+
+ if (with_help)
+ fputs ("\n"
+ "Usage: " PGM " [OPTIONS] NBYTES\n"
+ "Connect to libgcrypt's random number daemon and "
+ "return random numbers"
+ "\n"
+ " --nonce Return weak random suitable for a nonce\n"
+ " --very-strong Return very strong random\n"
+ " --ping Send a ping\n"
+ " --socket NAME Name of sockket to connect to\n"
+ " --hex Return result as a hex dump\n"
+ " --verbose Show what we are doing\n"
+ " --version Print version of the program and exit\n"
+ " --help Display this help and exit\n"
+ BUGREPORT_LINE, stdout );
+
+ exit (0);
+}
+
+static int
+print_usage (void)
+{
+ fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
+ fputs (" (use --help to display options)\n", stderr);
+ exit (1);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ struct sockaddr_un *srvr_addr;
+ socklen_t addrlen;
+ int fd;
+ int rc;
+ unsigned char buffer[300];
+ int nleft, nread;
+ const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
+ int do_ping = 0;
+ int get_nonce = 0;
+ int get_very_strong = 0;
+ int req_nbytes, nbytes, n;
+ int verbose = 0;
+ int fail = 0;
+ int do_hex = 0;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && **argv == '-' && (*argv)[1] == '-')
+ {
+ if (!(*argv)[2])
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ print_version (0);
+ else if (!strcmp (*argv, "--help"))
+ print_version (1);
+ else if (!strcmp (*argv, "--socket") && argc > 1 )
+ {
+ argc--; argv++;
+ socketname = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--nonce"))
+ {
+ argc--; argv++;
+ get_nonce = 1;
+ }
+ else if (!strcmp (*argv, "--very-strong"))
+ {
+ argc--; argv++;
+ get_very_strong = 1;
+ }
+ else if (!strcmp (*argv, "--ping"))
+ {
+ argc--; argv++;
+ do_ping = 1;
+ }
+ else if (!strcmp (*argv, "--hex"))
+ {
+ argc--; argv++;
+ do_hex = 1;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ argc--; argv++;
+ verbose = 1;
+ }
+ else
+ print_usage ();
+ }
+
+
+ if (!argc && do_ping)
+ ; /* This is allowed. */
+ else if (argc != 1)
+ print_usage ();
+ req_nbytes = argc? atoi (*argv) : 0;
+
+ if (req_nbytes < 0)
+ print_usage ();
+
+ /* Create a socket. */
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ logit ("can't create socket: %s", strerror (errno));
+ exit (1);
+ }
+ srvr_addr = malloc (sizeof *srvr_addr);
+ if (!srvr_addr)
+ {
+ logit ("malloc failed: %s", strerror (errno));
+ exit (1);
+ }
+ memset (srvr_addr, 0, sizeof *srvr_addr);
+ srvr_addr->sun_family = AF_UNIX;
+ if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
+ {
+ logit ("socket name `%s' too long", socketname);
+ exit (1);
+ }
+ strcpy (srvr_addr->sun_path, socketname);
+ addrlen = (offsetof (struct sockaddr_un, sun_path)
+ + strlen (srvr_addr->sun_path) + 1);
+ rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
+ if (rc == -1)
+ {
+ logit ("error connecting socket `%s': %s",
+ srvr_addr->sun_path, strerror (errno));
+ close (fd);
+ exit (1);
+ }
+
+ do
+ {
+ nbytes = req_nbytes > 255? 255 : req_nbytes;
+ req_nbytes -= nbytes;
+
+ buffer[0] = 3;
+ if (do_ping)
+ buffer[1] = 0;
+ else if (get_nonce)
+ buffer[1] = 10;
+ else if (get_very_strong)
+ buffer[1] = 12;
+ else
+ buffer[1] = 11;
+ buffer[2] = nbytes;
+ if (writen (fd, buffer, 3))
+ fail = 1;
+ else
+ {
+ for (nleft=2, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ if (nread && buffer[0])
+ {
+ logit ("server returned error code %d", buffer[0]);
+ exit (1);
+ }
+ }
+ if (verbose)
+ logit ("received response with %d bytes of data", buffer[1]);
+ if (buffer[1] < nbytes)
+ {
+ logit ("warning: server returned less bytes than requested");
+ fail = 1;
+ }
+ else if (buffer[1] > nbytes && !do_ping)
+ {
+ logit ("warning: server returned more bytes than requested");
+ fail = 1;
+ }
+ nbytes = buffer[1];
+ if (nbytes > sizeof buffer)
+ {
+ logit ("buffer too short to receive data");
+ exit (1);
+ }
+
+ for (nleft=nbytes, nread=0; nleft > 0; )
+ {
+ do
+ n = read (fd, buffer+nread, nleft);
+ while (n < 0 && errno == EINTR);
+ if (n < 0)
+ {
+ logit ("read error: %s", strerror (errno));
+ exit (1);
+ }
+ nleft -= n;
+ nread += n;
+ }
+
+ if (do_hex)
+ {
+ for (n=0; n < nbytes; n++)
+ {
+ if (!n)
+ ;
+ else if (!(n % 16))
+ putchar ('\n');
+ else
+ putchar (' ');
+ printf ("%02X", buffer[n]);
+ }
+ if (nbytes)
+ putchar ('\n');
+ }
+ else
+ {
+ if (fwrite (buffer, nbytes, 1, stdout) != 1)
+ {
+ logit ("error writing to stdout: %s", strerror (errno));
+ fail = 1;
+ }
+ }
+ }
+ }
+ while (!fail && req_nbytes);
+
+ close (fd);
+ free (srvr_addr);
+ return fail? 1 : 0;
+}
--- /dev/null
+/* global.c - global control functions
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ * 2004, 2005, 2006, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "stdmem.h" /* our own memory allocator */
+#include "secmem.h" /* our own secmem allocator */
+#include "ath.h"
+
+\f
+
+/****************
+ * flag bits: 0 : general cipher debug
+ * 1 : general MPI debug
+ */
+static unsigned int debug_flags;
+
+/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the
+ initialization code switched fips mode on. */
+static int force_fips_mode;
+
+/* Controlled by global_init(). */
+static int any_init_done;
+
+/* A table to map hardware features to a string. */
+static struct
+{
+ unsigned int flag;
+ const char *desc;
+} hwflist[] =
+ {
+ { HWF_PADLOCK_RNG, "padlock-rng" },
+ { HWF_PADLOCK_AES, "padlock-aes" },
+ { HWF_PADLOCK_SHA, "padlock-sha" },
+ { HWF_PADLOCK_MMUL,"padlock-mmul"},
+ { HWF_INTEL_AESNI, "intel-aesni" },
+ { 0, NULL}
+ };
+
+/* A bit vector with the hardware features which shall not be used.
+ This variable must be set prior to any initialization. */
+static unsigned int disabled_hw_features;
+
+
+/* Memory management. */
+
+static gcry_handler_alloc_t alloc_func;
+static gcry_handler_alloc_t alloc_secure_func;
+static gcry_handler_secure_check_t is_secure_func;
+static gcry_handler_realloc_t realloc_func;
+static gcry_handler_free_t free_func;
+static gcry_handler_no_mem_t outofcore_handler;
+static void *outofcore_handler_value;
+static int no_secure_memory;
+
+
+\f
+
+
+/* This is our handmade constructor. It gets called by any function
+ likely to be called at startup. The suggested way for an
+ application to make sure that this has been called is by using
+ gcry_check_version. */
+static void
+global_init (void)
+{
+ gcry_error_t err = 0;
+
+ if (any_init_done)
+ return;
+ any_init_done = 1;
+
+ /* Initialize our portable thread/mutex wrapper. */
+ err = ath_init ();
+ if (err)
+ goto fail;
+
+ /* See whether the system is in FIPS mode. This needs to come as
+ early as possible put after the ATH has been initialized. */
+ _gcry_initialize_fips_mode (force_fips_mode);
+
+ /* Before we do any other initialization we need to test available
+ hardware features. */
+ _gcry_detect_hw_features (disabled_hw_features);
+
+ err = _gcry_cipher_init ();
+ if (err)
+ goto fail;
+ err = _gcry_md_init ();
+ if (err)
+ goto fail;
+ err = _gcry_pk_init ();
+ if (err)
+ goto fail;
+#if 0
+ /* Hmmm, as of now ac_init does nothing. */
+ if ( !fips_mode () )
+ {
+ err = _gcry_ac_init ();
+ if (err)
+ goto fail;
+ }
+#endif
+
+ return;
+
+ fail:
+ BUG ();
+}
+
+
+/* This function is called by the macro fips_is_operational and makes
+ sure that the minimal initialization has been done. This is far
+ from a perfect solution and hides problems with an improper
+ initialization but at least in single-threaded mode it should work
+ reliable.
+
+ The reason we need this is that a lot of applications don't use
+ Libgcrypt properly by not running any initialization code at all.
+ They just call a Libgcrypt function and that is all what they want.
+ Now with the FIPS mode, that has the side effect of entering FIPS
+ mode (for security reasons, FIPS mode is the default if no
+ initialization has been done) and bailing out immediately because
+ the FSM is in the wrong state. If we always run the init code,
+ Libgcrypt can test for FIPS mode and at least if not in FIPS mode,
+ it will behave as before. Note that this on-the-fly initialization
+ is only done for the cryptographic functions subject to FIPS mode
+ and thus not all API calls will do such an initialization. */
+int
+_gcry_global_is_operational (void)
+{
+ if (!any_init_done)
+ {
+#ifdef HAVE_SYSLOG
+ syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+ "missing initialization - please fix the application");
+#endif /*HAVE_SYSLOG*/
+ global_init ();
+ }
+ return _gcry_fips_is_operational ();
+}
+
+
+
+\f
+/* Version number parsing. */
+
+/* This function parses the first portion of the version number S and
+ stores it in *NUMBER. On success, this function returns a pointer
+ into S starting with the first character, which is not part of the
+ initial number portion; on failure, NULL is returned. */
+static const char*
+parse_version_number( const char *s, int *number )
+{
+ int val = 0;
+
+ if( *s == '0' && isdigit(s[1]) )
+ return NULL; /* leading zeros are not allowed */
+ for ( ; isdigit(*s); s++ ) {
+ val *= 10;
+ val += *s - '0';
+ }
+ *number = val;
+ return val < 0? NULL : s;
+}
+
+/* This function breaks up the complete string-representation of the
+ version number S, which is of the following struture: <major
+ number>.<minor number>.<micro number><patch level>. The major,
+ minor and micro number components will be stored in *MAJOR, *MINOR
+ and *MICRO.
+
+ On success, the last component, the patch level, will be returned;
+ in failure, NULL will be returned. */
+
+static const char *
+parse_version_string( const char *s, int *major, int *minor, int *micro )
+{
+ s = parse_version_number( s, major );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, minor );
+ if( !s || *s != '.' )
+ return NULL;
+ s++;
+ s = parse_version_number( s, micro );
+ if( !s )
+ return NULL;
+ return s; /* patchlevel */
+}
+
+/* If REQ_VERSION is non-NULL, check that the version of the library
+ is at minimum the requested one. Returns the string representation
+ of the library version if the condition is satisfied; return NULL
+ if the requested version is newer than that of the library.
+
+ If a NULL is passed to this function, no check is done, but the
+ string representation of the library is simply returned. */
+const char *
+gcry_check_version( const char *req_version )
+{
+ const char *ver = VERSION;
+ int my_major, my_minor, my_micro;
+ int rq_major, rq_minor, rq_micro;
+ const char *my_plvl;
+
+ /* Initialize library. */
+ global_init ();
+
+ if ( !req_version )
+ /* Caller wants our version number. */
+ return ver;
+
+ /* Parse own version number. */
+ my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro );
+ if ( !my_plvl )
+ /* very strange our own version is bogus. Shouldn't we use
+ assert() here and bail out in case this happens? -mo. */
+ return NULL;
+
+ /* Parse requested version number. */
+ if (!parse_version_string (req_version, &rq_major, &rq_minor, &rq_micro))
+ return NULL; /* req version string is invalid, this can happen. */
+
+ /* Compare version numbers. */
+ if ( my_major > rq_major
+ || (my_major == rq_major && my_minor > rq_minor)
+ || (my_major == rq_major && my_minor == rq_minor && my_micro > rq_micro)
+ || (my_major == rq_major && my_minor == rq_minor
+ && my_micro == rq_micro))
+ {
+ return ver;
+ }
+
+ return NULL;
+}
+
+
+static void
+print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
+{
+ unsigned int hwf;
+ int i;
+
+ fnc (fp, "version:%s:\n", VERSION);
+ fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
+ fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS);
+ fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS);
+ fnc (fp, "rnd-mod:"
+#if USE_RNDEGD
+ "egd:"
+#endif
+#if USE_RNDLINUX
+ "linux:"
+#endif
+#if USE_RNDUNIX
+ "unix:"
+#endif
+#if USE_RNDW32
+ "w32:"
+#endif
+ "\n");
+ fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
+ hwf = _gcry_get_hw_features ();
+ fnc (fp, "hwflist:");
+ for (i=0; hwflist[i].desc; i++)
+ if ( (hwf & hwflist[i].flag) )
+ fnc (fp, "%s:", hwflist[i].desc);
+ fnc (fp, "\n");
+ /* We use y/n instead of 1/0 for the simple reason that Emacsen's
+ compile error parser would accidently flag that line when printed
+ during "make check" as an error. */
+ fnc (fp, "fips-mode:%c:%c:\n",
+ fips_mode ()? 'y':'n',
+ _gcry_enforced_fips_mode ()? 'y':'n' );
+}
+
+
+\f
+
+/* Command dispatcher function, acting as general control
+ function. */
+gcry_error_t
+_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
+{
+ static int init_finished = 0;
+ gcry_err_code_t err = 0;
+
+ switch (cmd)
+ {
+ case GCRYCTL_ENABLE_M_GUARD:
+ _gcry_private_enable_m_guard ();
+ break;
+
+ case GCRYCTL_ENABLE_QUICK_RANDOM:
+ _gcry_enable_quick_random_gen ();
+ break;
+
+ case GCRYCTL_FAKED_RANDOM_P:
+ /* Return an error if the RNG is faked one (e.g. enabled by
+ ENABLE_QUICK_RANDOM. */
+ if (_gcry_random_is_faked ())
+ err = GPG_ERR_GENERAL; /* Use as TRUE value. */
+ break;
+
+ case GCRYCTL_DUMP_RANDOM_STATS:
+ _gcry_random_dump_stats ();
+ break;
+
+ case GCRYCTL_DUMP_MEMORY_STATS:
+ /*m_print_stats("[fixme: prefix]");*/
+ break;
+
+ case GCRYCTL_DUMP_SECMEM_STATS:
+ _gcry_secmem_dump_stats ();
+ break;
+
+ case GCRYCTL_DROP_PRIVS:
+ global_init ();
+ _gcry_secmem_init (0);
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM:
+ global_init ();
+ no_secure_memory = 1;
+ break;
+
+ case GCRYCTL_INIT_SECMEM:
+ global_init ();
+ _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
+ if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
+ err = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_TERM_SECMEM:
+ global_init ();
+ _gcry_secmem_term ();
+ break;
+
+ case GCRYCTL_DISABLE_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_NO_WARNING));
+ break;
+
+ case GCRYCTL_SUSPEND_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_RESUME_SECMEM_WARN:
+ _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+ & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
+ break;
+
+ case GCRYCTL_USE_SECURE_RNDPOOL:
+ global_init ();
+ _gcry_secure_random_alloc (); /* Put random number into secure memory. */
+ break;
+
+ case GCRYCTL_SET_RANDOM_SEED_FILE:
+ _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
+ if ( fips_is_operational () )
+ _gcry_update_random_seed_file ();
+ break;
+
+ case GCRYCTL_SET_VERBOSITY:
+ _gcry_set_log_verbosity (va_arg (arg_ptr, int));
+ break;
+
+ case GCRYCTL_SET_DEBUG_FLAGS:
+ debug_flags |= va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_CLEAR_DEBUG_FLAGS:
+ debug_flags &= ~va_arg (arg_ptr, unsigned int);
+ break;
+
+ case GCRYCTL_DISABLE_INTERNAL_LOCKING:
+ /* Not used anymore. */
+ global_init ();
+ break;
+
+ case GCRYCTL_ANY_INITIALIZATION_P:
+ if (any_init_done)
+ err = GPG_ERR_GENERAL;
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED_P:
+ if (init_finished)
+ err = GPG_ERR_GENERAL; /* Yes. */
+ break;
+
+ case GCRYCTL_INITIALIZATION_FINISHED:
+ /* This is a hook which should be used by an application after
+ all initialization has been done and right before any threads
+ are started. It is not really needed but the only way to be
+ really sure that all initialization for thread-safety has
+ been done. */
+ if (! init_finished)
+ {
+ global_init ();
+ /* Do only a basic random initialization, i.e. init the
+ mutexes. */
+ _gcry_random_initialize (0);
+ init_finished = 1;
+ /* Force us into operational state if in FIPS mode. */
+ (void)fips_is_operational ();
+ }
+ break;
+
+ case GCRYCTL_SET_THREAD_CBS:
+ err = ath_install (va_arg (arg_ptr, void *), any_init_done);
+ if (! err)
+ global_init ();
+ break;
+
+ case GCRYCTL_FAST_POLL:
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_random_initialize (1);
+
+ if ( fips_is_operational () )
+ _gcry_fast_random_poll ();
+ break;
+
+ case GCRYCTL_SET_RNDEGD_SOCKET:
+#if USE_RNDEGD
+ err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
+#else
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+#endif
+ break;
+
+ case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
+ _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
+ break;
+
+ case GCRYCTL_USE_RANDOM_DAEMON:
+ /* We need to do make sure that the random pool is really
+ initialized so that the poll function is not a NOP. */
+ _gcry_random_initialize (1);
+ _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
+ break;
+
+ /* This command dumps information pertaining to the
+ configuration of libgcrypt to the given stream. It may be
+ used before the initialization has been finished but not
+ before a gcry_version_check. */
+ case GCRYCTL_PRINT_CONFIG:
+ {
+ FILE *fp = va_arg (arg_ptr, FILE *);
+ print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
+ }
+ break;
+
+ case GCRYCTL_OPERATIONAL_P:
+ /* Returns true if the library is in an operational state. This
+ is always true for non-fips mode. */
+ if (_gcry_fips_test_operational ())
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FIPS_MODE_P:
+ if (fips_mode ()
+ && !_gcry_is_fips_mode_inactive ()
+ && !no_secure_memory)
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ break;
+
+ case GCRYCTL_FORCE_FIPS_MODE:
+ /* Performing this command puts the library into fips mode. If
+ the library has already been initialized into fips mode, a
+ selftest is triggered. It is not possible to put the libraty
+ into fips mode after having passed the initialization. */
+ if (!any_init_done)
+ {
+ /* Not yet intialized at all. Set a flag so that we are put
+ into fips mode during initialization. */
+ force_fips_mode = 1;
+ }
+ else
+ {
+ /* Already initialized. If we are already operational we
+ run a selftest. If not we use the is_operational call to
+ force us into operational state if possible. */
+ if (_gcry_fips_test_error_or_operational ())
+ _gcry_fips_run_selftests (1);
+ if (_gcry_fips_is_operational ())
+ err = GPG_ERR_GENERAL; /* Used as TRUE value */
+ }
+ break;
+
+ case GCRYCTL_SELFTEST:
+ /* Run a selftest. This works in fips mode as well as in
+ standard mode. In contrast to the power-up tests, we use an
+ extended version of the selftests. Returns 0 on success or an
+ error code. */
+ global_init ();
+ err = _gcry_fips_run_selftests (1);
+ break;
+
+#if _GCRY_GCC_VERSION >= 40600
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wswitch"
+#endif
+ case 58: /* Init external random test. */
+ {
+ void **rctx = va_arg (arg_ptr, void **);
+ unsigned int flags = va_arg (arg_ptr, unsigned int);
+ const void *key = va_arg (arg_ptr, const void *);
+ size_t keylen = va_arg (arg_ptr, size_t);
+ const void *seed = va_arg (arg_ptr, const void *);
+ size_t seedlen = va_arg (arg_ptr, size_t);
+ const void *dt = va_arg (arg_ptr, const void *);
+ size_t dtlen = va_arg (arg_ptr, size_t);
+ if (!fips_is_operational ())
+ err = fips_not_operational ();
+ else
+ err = _gcry_random_init_external_test (rctx, flags, key, keylen,
+ seed, seedlen, dt, dtlen);
+ }
+ break;
+ case 59: /* Run external random test. */
+ {
+ void *ctx = va_arg (arg_ptr, void *);
+ void *buffer = va_arg (arg_ptr, void *);
+ size_t buflen = va_arg (arg_ptr, size_t);
+ if (!fips_is_operational ())
+ err = fips_not_operational ();
+ else
+ err = _gcry_random_run_external_test (ctx, buffer, buflen);
+ }
+ break;
+ case 60: /* Deinit external random test. */
+ {
+ void *ctx = va_arg (arg_ptr, void *);
+ _gcry_random_deinit_external_test (ctx);
+ }
+ break;
+ case 61: /* RFU */
+ break;
+ case 62: /* RFU */
+ break;
+#if _GCRY_GCC_VERSION >= 40600
+# pragma GCC diagnostic pop
+#endif
+
+ case GCRYCTL_DISABLE_HWF:
+ {
+ const char *name = va_arg (arg_ptr, const char *);
+ int i;
+
+ for (i=0; hwflist[i].desc; i++)
+ if (!strcmp (hwflist[i].desc, name))
+ {
+ disabled_hw_features |= hwflist[i].flag;
+ break;
+ }
+ if (!hwflist[i].desc)
+ err = GPG_ERR_INV_NAME;
+ }
+ break;
+
+ default:
+ /* A call to make sure that the dummy code is linked in. */
+ _gcry_compat_identification ();
+ err = GPG_ERR_INV_OP;
+ }
+
+ return gcry_error (err);
+}
+
+
+/* Command dispatcher function, acting as general control
+ function. */
+gcry_error_t
+gcry_control (enum gcry_ctl_cmds cmd, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, cmd);
+ err = _gcry_vcontrol (cmd, arg_ptr);
+ va_end(arg_ptr);
+ return err;
+}
+
+
+
+/* Return a pointer to a string containing a description of the error
+ code in the error value ERR. */
+const char *
+gcry_strerror (gcry_error_t err)
+{
+ return gpg_strerror (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+ source in the error value ERR. */
+const char *
+gcry_strsource (gcry_error_t err)
+{
+ return gpg_strsource (err);
+}
+
+/* Retrieve the error code for the system error ERR. This returns
+ GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report
+ this). */
+gcry_err_code_t
+gcry_err_code_from_errno (int err)
+{
+ return gpg_err_code_from_errno (err);
+}
+
+
+/* Retrieve the system error for the error code CODE. This returns 0
+ if CODE is not a system error code. */
+int
+gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return gpg_err_code_from_errno (code);
+}
+
+
+/* Return an error value with the error source SOURCE and the system
+ error ERR. */
+gcry_error_t
+gcry_err_make_from_errno (gpg_err_source_t source, int err)
+{
+ return gpg_err_make_from_errno (source, err);
+}
+
+
+/* Return an error value with the system error ERR. */
+gcry_err_code_t
+gcry_error_from_errno (int err)
+{
+ return gcry_error (gpg_err_code_from_errno (err));
+}
+
+
+/* Set custom allocation handlers. This is in general not useful
+ * because the libgcrypt allocation functions are guaranteed to
+ * provide proper allocation handlers which zeroize memory if needed.
+ * NOTE: All 5 functions should be set. */
+void
+gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
+ gcry_handler_alloc_t new_alloc_secure_func,
+ gcry_handler_secure_check_t new_is_secure_func,
+ gcry_handler_realloc_t new_realloc_func,
+ gcry_handler_free_t new_free_func)
+{
+ global_init ();
+
+ if (fips_mode ())
+ {
+ /* We do not want to enforce the fips mode, but merely set a
+ flag so that the application may check whether it is still in
+ fips mode. */
+ _gcry_inactivate_fips_mode ("custom allocation handler");
+ }
+
+ alloc_func = new_alloc_func;
+ alloc_secure_func = new_alloc_secure_func;
+ is_secure_func = new_is_secure_func;
+ realloc_func = new_realloc_func;
+ free_func = new_free_func;
+}
+
+
+
+/****************
+ * Set an optional handler which is called in case the xmalloc functions
+ * ran out of memory. This handler may do one of these things:
+ * o free some memory and return true, so that the xmalloc function
+ * tries again.
+ * o Do whatever it like and return false, so that the xmalloc functions
+ * use the default fatal error handler.
+ * o Terminate the program and don't return.
+ *
+ * The handler function is called with 3 arguments: The opaque value set with
+ * this function, the requested memory size, and a flag with these bits
+ * currently defined:
+ * bit 0 set = secure memory has been requested.
+ */
+void
+gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
+ void *value )
+{
+ global_init ();
+
+ if (fips_mode () )
+ {
+ log_info ("out of core handler ignored in FIPS mode\n");
+ return;
+ }
+
+ outofcore_handler = f;
+ outofcore_handler_value = value;
+}
+
+/* Return the no_secure_memory flag. */
+static int
+get_no_secure_memory (void)
+{
+ if (!no_secure_memory)
+ return 0;
+ if (_gcry_enforced_fips_mode ())
+ {
+ no_secure_memory = 0;
+ return 0;
+ }
+ return no_secure_memory;
+}
+
+
+static gcry_err_code_t
+do_malloc (size_t n, unsigned int flags, void **mem)
+{
+ gcry_err_code_t err = 0;
+ void *m;
+
+ if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ())
+ {
+ if (alloc_secure_func)
+ m = (*alloc_secure_func) (n);
+ else
+ m = _gcry_private_malloc_secure (n);
+ }
+ else
+ {
+ if (alloc_func)
+ m = (*alloc_func) (n);
+ else
+ m = _gcry_private_malloc (n);
+ }
+
+ if (!m)
+ {
+ /* Make sure that ERRNO has been set in case a user supplied
+ memory handler didn't it correctly. */
+ if (!errno)
+ gpg_err_set_errno (ENOMEM);
+ err = gpg_err_code_from_errno (errno);
+ }
+ else
+ *mem = m;
+
+ return err;
+}
+
+void *
+gcry_malloc (size_t n)
+{
+ void *mem = NULL;
+
+ do_malloc (n, 0, &mem);
+
+ return mem;
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ void *mem = NULL;
+
+ do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem);
+
+ return mem;
+}
+
+int
+gcry_is_secure (const void *a)
+{
+ if (get_no_secure_memory ())
+ return 0;
+ if (is_secure_func)
+ return is_secure_func (a) ;
+ return _gcry_private_is_secure (a);
+}
+
+void
+_gcry_check_heap( const void *a )
+{
+ (void)a;
+
+ /* FIXME: implement this*/
+#if 0
+ if( some_handler )
+ some_handler(a)
+ else
+ _gcry_private_check_heap(a)
+#endif
+}
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ void *p;
+
+ /* To avoid problems with non-standard realloc implementations and
+ our own secmem_realloc, we divert to malloc and free here. */
+ if (!a)
+ return gcry_malloc (n);
+ if (!n)
+ {
+ gcry_free (a);
+ return NULL;
+ }
+
+ if (realloc_func)
+ p = realloc_func (a, n);
+ else
+ p = _gcry_private_realloc (a, n);
+ if (!p && !errno)
+ gpg_err_set_errno (ENOMEM);
+ return p;
+}
+
+void
+gcry_free (void *p)
+{
+ int save_errno;
+
+ if (!p)
+ return;
+
+ /* In case ERRNO is set we better save it so that the free machinery
+ may not accidently change ERRNO. We restore it only if it was
+ already set to comply with the usual C semantic for ERRNO. */
+ save_errno = errno;
+ if (free_func)
+ free_func (p);
+ else
+ _gcry_private_free (p);
+
+ if (save_errno)
+ gpg_err_set_errno (save_errno);
+}
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = gcry_malloc (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+void *
+gcry_calloc_secure (size_t n, size_t m)
+{
+ size_t bytes;
+ void *p;
+
+ bytes = n * m; /* size_t is unsigned so the behavior on overflow is
+ defined. */
+ if (m && bytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+
+ p = gcry_malloc_secure (bytes);
+ if (p)
+ memset (p, 0, bytes);
+ return p;
+}
+
+
+/* Create and return a copy of the null-terminated string STRING. If
+ it is contained in secure memory, the copy will be contained in
+ secure memory as well. In an out-of-memory condition, NULL is
+ returned. */
+char *
+gcry_strdup (const char *string)
+{
+ char *string_cp = NULL;
+ size_t string_n = 0;
+
+ string_n = strlen (string);
+
+ if (gcry_is_secure (string))
+ string_cp = gcry_malloc_secure (string_n + 1);
+ else
+ string_cp = gcry_malloc (string_n + 1);
+
+ if (string_cp)
+ strcpy (string_cp, string);
+
+ return string_cp;
+}
+
+
+void *
+gcry_xmalloc( size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_malloc( n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 0) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL);
+ }
+ }
+ return p;
+}
+
+void *
+gcry_xrealloc( void *a, size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_realloc( a, n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n,
+ gcry_is_secure(a)? 3:2 ) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
+ }
+ }
+ return p;
+}
+
+void *
+gcry_xmalloc_secure( size_t n )
+{
+ void *p;
+
+ while ( !(p = gcry_malloc_secure( n )) )
+ {
+ if ( fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, 1) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ _("out of core in secure memory"));
+ }
+ }
+ return p;
+}
+
+
+void *
+gcry_xcalloc( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = gcry_xmalloc ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+void *
+gcry_xcalloc_secure( size_t n, size_t m )
+{
+ size_t nbytes;
+ void *p;
+
+ nbytes = n * m;
+ if (m && nbytes / m != n)
+ {
+ gpg_err_set_errno (ENOMEM);
+ _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
+ }
+
+ p = gcry_xmalloc_secure ( nbytes );
+ memset ( p, 0, nbytes );
+ return p;
+}
+
+char *
+gcry_xstrdup (const char *string)
+{
+ char *p;
+
+ while ( !(p = gcry_strdup (string)) )
+ {
+ size_t n = strlen (string);
+ int is_sec = !!gcry_is_secure (string);
+
+ if (fips_mode ()
+ || !outofcore_handler
+ || !outofcore_handler (outofcore_handler_value, n, is_sec) )
+ {
+ _gcry_fatal_error (gpg_err_code_from_errno (errno),
+ is_sec? _("out of core in secure memory"):NULL);
+ }
+ }
+
+ return p;
+}
+
+
+int
+_gcry_get_debug_flag (unsigned int mask)
+{
+ if ( fips_mode () )
+ return 0;
+ return (debug_flags & mask);
+}
+
+
+\f
+/* It is often useful to get some feedback of long running operations.
+ This function may be used to register a handler for this.
+ The callback function CB is used as:
+
+ void cb (void *opaque, const char *what, int printchar,
+ int current, int total);
+
+ Where WHAT is a string identifying the the type of the progress
+ output, PRINTCHAR the character usually printed, CURRENT the amount
+ of progress currently done and TOTAL the expected amount of
+ progress. A value of 0 for TOTAL indicates that there is no
+ estimation available.
+
+ Defined values for WHAT:
+
+ "need_entropy" X 0 number-of-bytes-required
+ When running low on entropy
+ "primegen" '\n' 0 0
+ Prime generated
+ '!'
+ Need to refresh the prime pool
+ '<','>'
+ Number of bits adjusted
+ '^'
+ Looking for a generator
+ '.'
+ Fermat tests on 10 candidates failed
+ ':'
+ Restart with a new random value
+ '+'
+ Rabin Miller test passed
+ "pk_elg" '+','-','.','\n' 0 0
+ Only used in debugging mode.
+ "pk_dsa"
+ Only used in debugging mode.
+*/
+void
+gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
+ void *cb_data)
+{
+#if USE_DSA
+ _gcry_register_pk_dsa_progress (cb, cb_data);
+#endif
+#if USE_ELGAMAL
+ _gcry_register_pk_elg_progress (cb, cb_data);
+#endif
+ _gcry_register_primegen_progress (cb, cb_data);
+ _gcry_register_random_progress (cb, cb_data);
+}
--- /dev/null
+/* hmac256.c - Standalone HMAC implementation
+ * Copyright (C) 2003, 2006, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ This is a standalone HMAC-SHA-256 implementation based on the code
+ from ../cipher/sha256.c. It is a second implementation to allow
+ comparing against the standard implementations and to be used for
+ internal consistency checks. It should not be used for sensitive
+ data because no mechanisms to clear the stack etc are used.
+
+ This module may be used standalone and requires only a few
+ standard definitions to be provided in a config.h file.
+
+ Types:
+
+ u32 - unsigned 32 bit type.
+
+ Constants:
+
+ WORDS_BIGENDIAN Defined to 1 on big endian systems.
+ inline If defined, it should yield the keyword used
+ to inline a function.
+ HAVE_U32_TYPEDEF Defined if the u32 type is available.
+ SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int.
+ SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long.
+
+ STANDALONE Compile a test driver similar to the
+ sha1sum tool. This driver uses a self-test
+ identically to the one used by Libcgrypt
+ for testing this included module.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#if defined(__WIN32) && defined(STANDALONE)
+# include <fcntl.h> /* We need setmode(). */
+#endif
+
+/* For a native WindowsCE binary we need to include gpg-error.h to
+ provide a replacement for strerror. In other cases we need a
+ replacement macro for gpg_err_set_errno. */
+#ifdef __MINGW32CE__
+# include <gpg-error.h>
+#else
+# define gpg_err_set_errno(a) (errno = (a))
+#endif
+
+#include "hmac256.h"
+
+
+
+#ifndef HAVE_U32_TYPEDEF
+# undef u32 /* Undef a possible macro with that name. */
+# if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+# elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+# else
+# error no typedef for u32
+# endif
+# define HAVE_U32_TYPEDEF
+#endif
+
+
+
+
+/* The context used by this module. */
+struct hmac256_context
+{
+ u32 h0, h1, h2, h3, h4, h5, h6, h7;
+ u32 nblocks;
+ int count;
+ int finalized:1;
+ int use_hmac:1;
+ unsigned char buf[64];
+ unsigned char opad[64];
+};
+
+
+/* Rotate a 32 bit word. */
+#if defined(__GNUC__) && defined(__i386__)
+static inline u32
+ror(u32 x, int n)
+{
+ __asm__("rorl %%cl,%0"
+ :"=r" (x)
+ :"0" (x),"c" (n));
+ return x;
+}
+#else
+#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+#endif
+
+#define my_wipememory2(_ptr,_set,_len) do { \
+ volatile char *_vptr=(volatile char *)(_ptr); \
+ size_t _vlen=(_len); \
+ while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+ } while(0)
+#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len)
+
+
+
+\f
+/*
+ The SHA-256 core: Transform the message X which consists of 16
+ 32-bit-words. See FIPS 180-2 for details.
+ */
+static void
+transform (hmac256_context_t hd, const void *data_arg)
+{
+ const unsigned char *data = data_arg;
+
+#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
+#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
+#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
+#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
+#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
+#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
+#define R(a,b,c,d,e,f,g,h,k,w) do \
+ { \
+ t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
+ t2 = Sum0((a)) + Maj((a),(b),(c)); \
+ h = g; \
+ g = f; \
+ f = e; \
+ e = d + t1; \
+ d = c; \
+ c = b; \
+ b = a; \
+ a = t1 + t2; \
+ } while (0)
+
+ static const u32 K[64] =
+ {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+ 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+ 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+ 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+ 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+ 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+
+ u32 a, b, c, d, e, f, g, h, t1, t2;
+ u32 x[16];
+ u32 w[64];
+ int i;
+
+ a = hd->h0;
+ b = hd->h1;
+ c = hd->h2;
+ d = hd->h3;
+ e = hd->h4;
+ f = hd->h5;
+ g = hd->h6;
+ h = hd->h7;
+
+#ifdef WORDS_BIGENDIAN
+ memcpy (x, data, 64);
+#else /*!WORDS_BIGENDIAN*/
+ {
+ unsigned char *p2;
+
+ for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 )
+ {
+ p2[3] = *data++;
+ p2[2] = *data++;
+ p2[1] = *data++;
+ p2[0] = *data++;
+ }
+ }
+#endif /*!WORDS_BIGENDIAN*/
+
+ for (i=0; i < 16; i++)
+ w[i] = x[i];
+ for (; i < 64; i++)
+ w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
+
+ for (i=0; i < 64; i++)
+ R(a,b,c,d,e,f,g,h,K[i],w[i]);
+
+ hd->h0 += a;
+ hd->h1 += b;
+ hd->h2 += c;
+ hd->h3 += d;
+ hd->h4 += e;
+ hd->h5 += f;
+ hd->h6 += g;
+ hd->h7 += h;
+}
+#undef Cho
+#undef Maj
+#undef Sum0
+#undef Sum1
+#undef S0
+#undef S1
+#undef R
+
+
+/* Finalize the current SHA256 calculation. */
+static void
+finalize (hmac256_context_t hd)
+{
+ u32 t, msb, lsb;
+ unsigned char *p;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+
+ t = hd->nblocks;
+ /* Multiply by 64 to make a byte count. */
+ lsb = t << 6;
+ msb = t >> 26;
+ /* Add the count. */
+ t = lsb;
+ if ((lsb += hd->count) < t)
+ msb++;
+ /* Multiply by 8 to make a bit count. */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 29;
+
+ if (hd->count < 56)
+ { /* Enough room. */
+ hd->buf[hd->count++] = 0x80; /* pad */
+ while (hd->count < 56)
+ hd->buf[hd->count++] = 0; /* pad */
+ }
+ else
+ { /* Need one extra block. */
+ hd->buf[hd->count++] = 0x80; /* pad character */
+ while (hd->count < 64)
+ hd->buf[hd->count++] = 0;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */;
+ memset (hd->buf, 0, 56 ); /* Zero out next next block. */
+ }
+ /* Append the 64 bit count. */
+ hd->buf[56] = msb >> 24;
+ hd->buf[57] = msb >> 16;
+ hd->buf[58] = msb >> 8;
+ hd->buf[59] = msb;
+ hd->buf[60] = lsb >> 24;
+ hd->buf[61] = lsb >> 16;
+ hd->buf[62] = lsb >> 8;
+ hd->buf[63] = lsb;
+ transform (hd, hd->buf);
+
+ /* Store the digest into hd->buf. */
+ p = hd->buf;
+#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
+ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
+ X(0);
+ X(1);
+ X(2);
+ X(3);
+ X(4);
+ X(5);
+ X(6);
+ X(7);
+#undef X
+ hd->finalized = 1;
+}
+
+
+
+/* Create a new context. On error NULL is returned and errno is set
+ appropriately. If KEY is given the function computes HMAC using
+ this key; with KEY given as NULL, a plain SHA-256 digest is
+ computed. */
+hmac256_context_t
+_gcry_hmac256_new (const void *key, size_t keylen)
+{
+ hmac256_context_t hd;
+
+ hd = malloc (sizeof *hd);
+ if (!hd)
+ return NULL;
+
+ hd->h0 = 0x6a09e667;
+ hd->h1 = 0xbb67ae85;
+ hd->h2 = 0x3c6ef372;
+ hd->h3 = 0xa54ff53a;
+ hd->h4 = 0x510e527f;
+ hd->h5 = 0x9b05688c;
+ hd->h6 = 0x1f83d9ab;
+ hd->h7 = 0x5be0cd19;
+ hd->nblocks = 0;
+ hd->count = 0;
+ hd->finalized = 0;
+ hd->use_hmac = 0;
+
+ if (key)
+ {
+ int i;
+ unsigned char ipad[64];
+
+ memset (ipad, 0, 64);
+ memset (hd->opad, 0, 64);
+ if (keylen <= 64)
+ {
+ memcpy (ipad, key, keylen);
+ memcpy (hd->opad, key, keylen);
+ }
+ else
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ {
+ free (hd);
+ return NULL;
+ }
+ _gcry_hmac256_update (tmphd, key, keylen);
+ finalize (tmphd);
+ memcpy (ipad, tmphd->buf, 32);
+ memcpy (hd->opad, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ for (i=0; i < 64; i++)
+ {
+ ipad[i] ^= 0x36;
+ hd->opad[i] ^= 0x5c;
+ }
+ hd->use_hmac = 1;
+ _gcry_hmac256_update (hd, ipad, 64);
+ my_wipememory (ipad, 64);
+ }
+
+ return hd;
+}
+
+/* Release a context created by _gcry_hmac256_new. CTX may be NULL
+ in which case the function does nothing. */
+void
+_gcry_hmac256_release (hmac256_context_t ctx)
+{
+ if (ctx)
+ {
+ /* Note: We need to take care not to modify errno. */
+ if (ctx->use_hmac)
+ my_wipememory (ctx->opad, 64);
+ free (ctx);
+ }
+}
+
+
+/* Update the message digest with the contents of BUFFER containing
+ LENGTH bytes. */
+void
+_gcry_hmac256_update (hmac256_context_t hd,
+ const void *buffer, size_t length)
+{
+ const unsigned char *inbuf = buffer;
+
+ if (hd->finalized)
+ return; /* Silently ignore a finalized context. */
+
+ if (hd->count == 64)
+ {
+ /* Flush the buffer. */
+ transform (hd, hd->buf);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if (!inbuf)
+ return; /* Only flushing was requested. */
+ if (hd->count)
+ {
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+ _gcry_hmac256_update (hd, NULL, 0); /* Flush. */
+ if (!length)
+ return;
+ }
+
+
+ while (length >= 64)
+ {
+ transform (hd, inbuf);
+ hd->count = 0;
+ hd->nblocks++;
+ length -= 64;
+ inbuf += 64;
+ }
+ for (; length && hd->count < 64; length--)
+ hd->buf[hd->count++] = *inbuf++;
+}
+
+
+/* Finalize an operation and return the digest. If R_DLEN is not NULL
+ the length of the digest will be stored at that address. The
+ returned value is valid as long as the context exists. On error
+ NULL is returned. */
+const void *
+_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen)
+{
+ finalize (hd);
+ if (hd->use_hmac)
+ {
+ hmac256_context_t tmphd;
+
+ tmphd = _gcry_hmac256_new (NULL, 0);
+ if (!tmphd)
+ {
+ free (hd);
+ return NULL;
+ }
+ _gcry_hmac256_update (tmphd, hd->opad, 64);
+ _gcry_hmac256_update (tmphd, hd->buf, 32);
+ finalize (tmphd);
+ memcpy (hd->buf, tmphd->buf, 32);
+ _gcry_hmac256_release (tmphd);
+ }
+ if (r_dlen)
+ *r_dlen = 32;
+ return (void*)hd->buf;
+}
+
+
+/* Convenience function to compute the HMAC-SHA256 of one file. The
+ user needs to provide a buffer RESULT of at least 32 bytes, he
+ needs to put the size of the buffer into RESULTSIZE and the
+ FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new.
+ On success the function returns the valid length of the result
+ buffer (which will be 32) or -1 on error. On error ERRNO is set
+ appropriate. */
+int
+_gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen)
+{
+ FILE *fp;
+ hmac256_context_t hd;
+ size_t buffer_size, nread, digestlen;
+ char *buffer;
+ const unsigned char *digest;
+
+ fp = fopen (filename, "rb");
+ if (!fp)
+ return -1;
+
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fclose (fp);
+ return -1;
+ }
+
+ buffer_size = 32768;
+ buffer = malloc (buffer_size);
+ if (!buffer)
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ while ( (nread = fread (buffer, 1, buffer_size, fp)))
+ _gcry_hmac256_update (hd, buffer, nread);
+
+ free (buffer);
+
+ if (ferror (fp))
+ {
+ fclose (fp);
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &digestlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hd);
+ return -1;
+ }
+
+ if (digestlen > resultsize)
+ {
+ _gcry_hmac256_release (hd);
+ gpg_err_set_errno (EINVAL);
+ return -1;
+ }
+ memcpy (result, digest, digestlen);
+ _gcry_hmac256_release (hd);
+
+ return digestlen;
+}
+
+
+
+#ifdef STANDALONE
+static int
+selftest (void)
+{
+ static struct
+ {
+ const char * const desc;
+ const char * const data;
+ const char * const key;
+ const unsigned char expect[32];
+ } tv[] =
+ {
+ { "data-28 key-4",
+ "what do ya want for nothing?",
+ "Jefe",
+ { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
+ 0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
+ 0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+ 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
+
+ { "data-9 key-20",
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b",
+ { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
+
+ { "data-50 key-20",
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa",
+ { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
+ 0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
+ 0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+ 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
+
+ { "data-50 key-26",
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
+ 0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
+ 0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+ 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
+
+ { "data-54 key-131",
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
+ 0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
+ 0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+ 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
+
+ { "data-152 key-131",
+ "This is a test using a larger than block-size key and a larger "
+ "than block-size data. The key needs to be hashed before being "
+ "used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
+ 0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
+ 0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+ 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
+
+ { NULL }
+ };
+ int tvidx;
+
+ for (tvidx=0; tv[tvidx].desc; tvidx++)
+ {
+ hmac256_context_t hmachd;
+ const unsigned char *digest;
+ size_t dlen;
+
+ hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
+ if (!hmachd)
+ return -1;
+ _gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
+ digest = _gcry_hmac256_finalize (hmachd, &dlen);
+ if (!digest)
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ if (dlen != sizeof (tv[tvidx].expect)
+ || memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect)))
+ {
+ _gcry_hmac256_release (hmachd);
+ return -1;
+ }
+ _gcry_hmac256_release (hmachd);
+ }
+
+ return 0; /* Succeeded. */
+}
+
+
+int
+main (int argc, char **argv)
+{
+ const char *pgm;
+ int last_argc = -1;
+ const char *key;
+ size_t keylen;
+ FILE *fp;
+ hmac256_context_t hd;
+ const unsigned char *digest;
+ char buffer[4096];
+ size_t n, dlen, idx;
+ int use_stdin = 0;
+ int use_binary = 0;
+
+ assert (sizeof (u32) == 4);
+#ifdef __WIN32
+ setmode (fileno (stdin), O_BINARY);
+#endif
+
+ if (argc)
+ {
+ pgm = strrchr (*argv, '/');
+ if (pgm)
+ pgm++;
+ else
+ pgm = *argv;
+ argc--; argv++;
+ }
+ else
+ pgm = "?";
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs ("hmac256 (Libgcrypt) " VERSION "\n"
+ "Copyright (C) 2008 Free Software Foundation, Inc.\n"
+ "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+ "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
+ "This is free software: you are free to change and "
+ "redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--binary"))
+ {
+ argc--; argv++;
+ use_binary = 1;
+ }
+ }
+
+ if (argc < 1)
+ {
+ fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm);
+ exit (1);
+ }
+
+#ifdef __WIN32
+ if (use_binary)
+ setmode (fileno (stdout), O_BINARY);
+#endif
+
+ key = *argv;
+ argc--, argv++;
+ keylen = strlen (key);
+ use_stdin = !argc;
+
+ if (selftest ())
+ {
+ fprintf (stderr, "%s: fatal error: self-test failed\n", pgm);
+ exit (2);
+ }
+
+ for (; argc || use_stdin; argv++, argc--)
+ {
+ const char *fname = use_stdin? "-" : *argv;
+ fp = use_stdin? stdin : fopen (fname, "rb");
+ if (!fp)
+ {
+ fprintf (stderr, "%s: can't open `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ hd = _gcry_hmac256_new (key, keylen);
+ if (!hd)
+ {
+ fprintf (stderr, "%s: can't allocate context: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ while ( (n = fread (buffer, 1, sizeof buffer, fp)))
+ _gcry_hmac256_update (hd, buffer, n);
+ if (ferror (fp))
+ {
+ fprintf (stderr, "%s: error reading `%s': %s\n",
+ pgm, fname, strerror (errno));
+ exit (1);
+ }
+ if (!use_stdin)
+ fclose (fp);
+
+ digest = _gcry_hmac256_finalize (hd, &dlen);
+ if (!digest)
+ {
+ fprintf (stderr, "%s: error computing HMAC: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ if (use_binary)
+ {
+ if (fwrite (digest, dlen, 1, stdout) != 1)
+ {
+ fprintf (stderr, "%s: error writing output: %s\n",
+ pgm, strerror (errno));
+ exit (1);
+ }
+ }
+ else
+ {
+ for (idx=0; idx < dlen; idx++)
+ printf ("%02x", digest[idx]);
+ _gcry_hmac256_release (hd);
+ if (use_stdin)
+ {
+ putchar ('\n');
+ break;
+ }
+ printf (" %s\n", fname);
+ }
+ }
+
+ return 0;
+}
+#endif /*STANDALONE*/
+
+
+/*
+Local Variables:
+compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c"
+End:
+*/
--- /dev/null
+/* hmac256.h - Declarations for _gcry_hmac256
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HMAC256_H
+#define HMAC256_H
+
+
+struct hmac256_context;
+typedef struct hmac256_context *hmac256_context_t;
+
+hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen);
+void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len);
+const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen);
+void _gcry_hmac256_release (hmac256_context_t hd);
+
+int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
+ const void *key, size_t keylen);
+
+
+#endif /*HMAC256_H*/
--- /dev/null
+/* hwfeatures.c - Detect hardware features.
+ * Copyright (C) 2007, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+
+/* A bit vector describing the hardware features currently
+ available. */
+static unsigned int hw_features;
+
+
+/* Return a bit vector describing the available hardware features.
+ The HWF_ constants are used to test for them. */
+unsigned int
+_gcry_get_hw_features (void)
+{
+ return hw_features;
+}
+
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+static void
+detect_ia32_gnuc (void)
+{
+ /* The code here is only useful for the PadLock engine thus we don't
+ build it if that support has been disabled. */
+ int has_cpuid = 0;
+ char vendor_id[12+1];
+
+ /* Detect the CPUID feature by testing some undefined behaviour (16
+ vs 32 bit pushf/popf). */
+ asm volatile
+ ("pushf\n\t" /* Copy flags to EAX. */
+ "popl %%eax\n\t"
+ "movl %%eax, %%ecx\n\t" /* Save flags into ECX. */
+ "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */
+ "pushl %%eax\n\t"
+ "popf\n\t"
+ "pushf\n\t" /* Copy changed flags again to EAX. */
+ "popl %%eax\n\t"
+ "pushl %%ecx\n\t" /* Restore flags from ECX. */
+ "popf\n\t"
+ "xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */
+ "jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */
+ "movl $1, %0\n" /* Worked. true -> HAS_CPUID. */
+ ".Lno_cpuid%=:\n\t"
+ : "+r" (has_cpuid)
+ :
+ : "%eax", "%ecx", "cc"
+ );
+
+ if (!has_cpuid)
+ return; /* No way. */
+
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "xorl %%eax, %%eax\n\t" /* 0 -> EAX. */
+ "cpuid\n\t" /* Get vendor ID. */
+ "movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */
+ "movl %%edx, 4(%0)\n\t"
+ "movl %%ecx, 8(%0)\n\t"
+ "popl %%ebx\n"
+ :
+ : "S" (&vendor_id[0])
+ : "%eax", "%ecx", "%edx", "cc"
+ );
+ vendor_id[12] = 0;
+
+ if (0)
+ ; /* Just to make "else if" and ifdef macros look pretty. */
+#ifdef ENABLE_PADLOCK_SUPPORT
+ else if (!strcmp (vendor_id, "CentaurHauls"))
+ {
+ /* This is a VIA CPU. Check what PadLock features we have. */
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */
+ "cpuid\n\t" /* feature flags. */
+ "popl %%ebx\n\t" /* Restore GOT register. */
+ "cmpl $0xC0000001, %%eax\n\t"
+ "jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */
+
+ "pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $0xC0000001, %%eax\n\t" /* Ask for the extended */
+ "cpuid\n\t" /* feature flags. */
+ "popl %%ebx\n\t" /* Restore GOT register. */
+
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */
+ "cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */
+ "jnz .Lno_rng%=\n\t"
+ "orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */
+
+ ".Lno_rng%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */
+ "cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */
+ "jnz .Lno_ace%=\n\t"
+ "orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */
+
+ ".Lno_ace%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */
+ "cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */
+ "jnz .Lno_phe%=\n\t"
+ "orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */
+
+ ".Lno_phe%=:\n\t"
+ "movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
+ "andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */
+ "cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */
+ "jnz .Lready%=\n\t"
+ "orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */
+
+ ".Lready%=:\n"
+ : "+r" (hw_features)
+ :
+ : "%eax", "%edx", "cc"
+ );
+ }
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+ else if (!strcmp (vendor_id, "GenuineIntel"))
+ {
+ /* This is an Intel CPU. */
+ asm volatile
+ ("pushl %%ebx\n\t" /* Save GOT register. */
+ "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */
+ "cpuid\n"
+ "popl %%ebx\n\t" /* Restore GOT register. */
+ "testl $0x02000000, %%ecx\n\t" /* Test bit 25. */
+ "jz .Lno_aes%=\n\t" /* No AES support. */
+ "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */
+
+ ".Lno_aes%=:\n"
+ : "+r" (hw_features)
+ :
+ : "%eax", "%ecx", "%edx", "cc"
+ );
+ }
+ else if (!strcmp (vendor_id, "AuthenticAMD"))
+ {
+ /* This is an AMD CPU. */
+
+ }
+}
+#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */
+
+
+/* Detect the available hardware features. This function is called
+ once right at startup and we assume that no other threads are
+ running. */
+void
+_gcry_detect_hw_features (unsigned int disabled_features)
+{
+ hw_features = 0;
+
+ if (fips_mode ())
+ return; /* Hardware support is not to be evaluated. */
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4
+#ifdef __GNUC__
+ detect_ia32_gnuc ();
+#endif
+#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8
+#ifdef __GNUC__
+#endif
+#endif
+
+ hw_features &= ~disabled_features;
+}
--- /dev/null
+#!/bin/sh
+# Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# File: @configure_input@
+
+# General.
+prefix="@prefix@"
+exec_prefix="@exec_prefix@"
+version="@VERSION@"
+includedir="@includedir@"
+libdir="@libdir@"
+gpg_error_libs="@GPG_ERROR_LIBS@"
+gpg_error_cflags="@GPG_ERROR_CFLAGS@"
+
+# libgcrypt values.
+libs="@LIBGCRYPT_CONFIG_LIBS@"
+cflags="@LIBGCRYPT_CONFIG_CFLAGS@"
+
+# API info
+api_version="@LIBGCRYPT_CONFIG_API_VERSION@"
+
+# Configured for host
+my_host="@LIBGCRYPT_CONFIG_HOST@"
+
+# Misc information.
+symmetric_ciphers="@LIBGCRYPT_CIPHERS@"
+asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@"
+digests="@LIBGCRYPT_DIGESTS@"
+
+# State variables.
+echo_libs=no
+echo_cflags=no
+echo_prefix=no
+echo_algorithms=no
+echo_exec_prefix=no
+echo_version=no
+echo_api_version=no
+echo_host=no
+
+# Prints usage information.
+usage()
+{
+ cat <<EOF
+Usage: $0 [OPTIONS]
+Options:
+ [--prefix]
+ [--exec-prefix]
+ [--version]
+ [--api-version]
+ [--libs]
+ [--cflags]
+ [--algorithms]
+ [--host]
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ # Nothing to do.
+ usage 1 1>&2
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+ # Set up `optarg'.
+ --*=*)
+ optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
+ ;;
+ *)
+ optarg=""
+ ;;
+ esac
+
+ case $1 in
+ --thread=*)
+ echo "$0: --thread option obsolete: use the thread callback interface" 1>&2
+ exit 1
+ ;;
+ --prefix=*)
+ # For compatibility reasons with old M4 macros, we ignore
+ # setting of prefix.
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --version)
+ echo_version=yes
+ ;;
+ --api-version)
+ echo_api_version=yes
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ --algorithms)
+ echo_algorithms=yes
+ ;;
+ --host)
+ echo_host=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+if test "$echo_prefix" = "yes"; then
+ echo "$prefix"
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo "$exec_prefix"
+fi
+
+if test "$echo_cflags" = "yes"; then
+ includes=""
+ cflags_final="$cflags"
+
+ # Set up `includes'.
+ if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then
+ includes="-I$includedir"
+ fi
+ # Set up `cflags_final'.
+ cflags_final="$cflags_final $gpg_error_cflags"
+
+ tmp=""
+ for i in $includes $cflags_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_libs" = "yes"; then
+ libdirs=""
+ libs_final="$libs"
+
+ # Set up `libdirs'.
+ if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then
+ libdirs="-L$libdir"
+ fi
+
+ # Set up `libs_final'.
+ libs_final="$libs_final $gpg_error_libs"
+
+ tmp=""
+ for i in $libdirs $libs_final; do
+ if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
+ tmp="$tmp $i"
+ fi
+ done
+ echo $tmp
+fi
+
+if test "$echo_version" = "yes"; then
+ echo "$version"
+fi
+
+if test "$echo_api_version" = "yes"; then
+ echo "$api_version"
+fi
+
+if test "$echo_host" = "yes"; then
+ echo "$my_host"
+fi
+
+if test "$echo_algorithms" = "yes"; then
+ echo "Symmetric cipher algorithms: $symmetric_ciphers"
+ echo "Public-key cipher algorithms: $asymmetric_ciphers"
+ echo "Message digest algorithms: $digests"
+fi
--- /dev/null
+;; libgcrypt.defs - Exported symbols for W32
+;; Copyright (C) 2003, 2007 Free Software Foundation, Inc.
+;;
+;; This file is part of Libgcrypt.
+;;
+;; Libgcrypt is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU Lesser General Public License as
+;; published by the Free Software Foundation; either version 2.1 of
+;; the License, or (at your option) any later version.
+;;
+;; Libgcrypt 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 Lesser General Public License for more details.
+;;
+;; You should have received a copy of the GNU Lesser General Public
+;; License along with this program; if not, write to the Free Software
+;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+;;
+
+;; Note: This file should be updated manually and the ordinals shall
+;; never be changed. Also check libgcrypt.vers and visibility.h.
+
+
+EXPORTS
+ gcry_check_version @1
+ gcry_control @2
+
+ gcry_malloc @3
+ gcry_calloc @4
+ gcry_malloc_secure @5
+ gcry_calloc_secure @6
+ gcry_realloc @7
+ gcry_strdup @8
+ gcry_xmalloc @9
+ gcry_xcalloc @10
+ gcry_xmalloc_secure @11
+ gcry_xcalloc_secure @12
+ gcry_xrealloc @13
+ gcry_xstrdup @14
+ gcry_is_secure @15
+ gcry_free @16
+
+ gcry_set_progress_handler @17
+ gcry_set_allocation_handler @18
+ gcry_set_outofcore_handler @19
+ gcry_set_fatalerror_handler @20
+ gcry_set_log_handler @21
+ gcry_set_gettext_handler @22
+
+ gcry_strerror @23
+ gcry_strsource @24
+ gcry_err_code_from_errno @25
+ gcry_err_code_to_errno @26
+ gcry_err_make_from_errno @27
+ gcry_error_from_errno @28
+
+ gcry_sexp_new @29
+ gcry_sexp_create @30
+ gcry_sexp_sscan @31
+ gcry_sexp_build @32
+ gcry_sexp_build_array @33
+ gcry_sexp_release @34
+ gcry_sexp_canon_len @35
+ gcry_sexp_sprint @36
+ gcry_sexp_dump @37
+ gcry_sexp_cons @38
+ gcry_sexp_alist @39
+ gcry_sexp_vlist @40
+ gcry_sexp_append @41
+ gcry_sexp_prepend @42
+ gcry_sexp_find_token @43
+ gcry_sexp_length @44
+ gcry_sexp_nth @45
+ gcry_sexp_car @46
+ gcry_sexp_cdr @47
+ gcry_sexp_cadr @48
+ gcry_sexp_nth_data @49
+ gcry_sexp_nth_mpi @50
+
+ gcry_mpi_new @51
+ gcry_mpi_snew @52
+ gcry_mpi_release @53
+ gcry_mpi_copy @54
+ gcry_mpi_set @55
+ gcry_mpi_set_ui @56
+ gcry_mpi_swap @57
+ gcry_mpi_cmp @58
+ gcry_mpi_cmp_ui @59
+ gcry_mpi_scan @60
+ gcry_mpi_print @61
+ gcry_mpi_aprint @62
+ gcry_mpi_dump @63
+ gcry_mpi_add @64
+ gcry_mpi_add_ui @65
+ gcry_mpi_addm @66
+ gcry_mpi_sub @67
+ gcry_mpi_sub_ui @68
+ gcry_mpi_subm @69
+ gcry_mpi_mul @70
+ gcry_mpi_mul_ui @71
+ gcry_mpi_mulm @72
+ gcry_mpi_mul_2exp @73
+ gcry_mpi_div @74
+ gcry_mpi_mod @75
+ gcry_mpi_powm @76
+ gcry_mpi_gcd @77
+ gcry_mpi_invm @78
+ gcry_mpi_get_nbits @79
+ gcry_mpi_test_bit @80
+ gcry_mpi_set_bit @81
+ gcry_mpi_clear_bit @82
+ gcry_mpi_set_highbit @83
+ gcry_mpi_clear_highbit @84
+ gcry_mpi_rshift @85
+ gcry_mpi_set_opaque @86
+ gcry_mpi_get_opaque @87
+ gcry_mpi_set_flag @88
+ gcry_mpi_clear_flag @89
+ gcry_mpi_get_flag @90
+
+
+ gcry_cipher_open @92
+ gcry_cipher_close @93
+ gcry_cipher_ctl @94
+ gcry_cipher_info @95
+ gcry_cipher_algo_info @96
+ gcry_cipher_algo_name @97
+ gcry_cipher_map_name @98
+ gcry_cipher_mode_from_oid @99
+ gcry_cipher_encrypt @100
+ gcry_cipher_decrypt @101
+ gcry_cipher_get_algo_keylen @102
+ gcry_cipher_get_algo_blklen @103
+ gcry_cipher_list @104
+
+ gcry_pk_encrypt @105
+ gcry_pk_decrypt @106
+ gcry_pk_sign @107
+ gcry_pk_verify @108
+ gcry_pk_testkey @109
+ gcry_pk_genkey @110
+ gcry_pk_ctl @111
+ gcry_pk_algo_info @112
+ gcry_pk_algo_name @113
+ gcry_pk_map_name @114
+ gcry_pk_get_nbits @115
+ gcry_pk_get_keygrip @116
+ gcry_pk_list @117
+
+ gcry_ac_data_new @118
+ gcry_ac_data_destroy @119
+ gcry_ac_data_set @120
+ gcry_ac_data_copy @121
+ gcry_ac_data_length @122
+ gcry_ac_data_get_name @123
+ gcry_ac_data_get_index @124
+ gcry_ac_data_clear @125
+ gcry_ac_open @126
+ gcry_ac_close @127
+ gcry_ac_key_init @128
+ gcry_ac_key_pair_generate @129
+ gcry_ac_key_pair_extract @130
+ gcry_ac_key_data_get @131
+ gcry_ac_key_test @132
+ gcry_ac_key_get_nbits @133
+ gcry_ac_key_get_grip @134
+ gcry_ac_key_destroy @135
+ gcry_ac_key_pair_destroy @136
+ gcry_ac_data_encrypt @137
+ gcry_ac_data_decrypt @138
+ gcry_ac_data_sign @139
+ gcry_ac_data_verify @140
+ gcry_ac_id_to_name @141
+ gcry_ac_name_to_id @142
+
+ gcry_md_open @143
+ gcry_md_close @144
+ gcry_md_enable @145
+ gcry_md_copy @146
+ gcry_md_reset @147
+ gcry_md_ctl @148
+ gcry_md_write @149
+ gcry_md_read @150
+ gcry_md_hash_buffer @151
+ gcry_md_get_algo @152
+ gcry_md_get_algo_dlen @153
+ gcry_md_is_enabled @154
+ gcry_md_is_secure @155
+ gcry_md_info @156
+ gcry_md_algo_info @157
+ gcry_md_algo_name @158
+ gcry_md_map_name @159
+ gcry_md_setkey @160
+ gcry_md_list @161
+
+ gcry_randomize @162
+ gcry_random_add_bytes @163
+ gcry_random_bytes @164
+ gcry_random_bytes_secure @165
+ gcry_mpi_randomize @166
+
+ gcry_prime_generate @167
+ gcry_prime_group_generator @168
+ gcry_prime_release_factors @169
+ gcry_prime_check @170
+
+ gcry_create_nonce @171
+
+ gcry_md_debug @172
+
+ gcry_cipher_register @173
+ gcry_cipher_unregister @174
+ gcry_md_register @175
+ gcry_md_unregister @176
+ gcry_pk_register @177
+ gcry_pk_unregister @178
+
+ gcry_ac_data_from_sexp @179
+ gcry_ac_data_to_sexp @180
+ gcry_ac_io_init @181
+ gcry_ac_io_init_va @182
+ gcry_ac_data_encrypt_scheme @183
+ gcry_ac_data_decrypt_scheme @184
+ gcry_ac_data_sign_scheme @185
+ gcry_ac_data_verify_scheme @186
+
+ gcry_sexp_nth_string @187
+
+ gcry_cipher_setkey @188
+ gcry_cipher_setiv @189
+ gcry_cipher_setctr @190
+
+ gcry_mpi_lshift @191
+
+ gcry_pk_get_curve @192
+ gcry_pk_get_param @193
+
+ gcry_kdf_derive @194
--- /dev/null
+dnl Autoconf macros for libgcrypt
+dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+dnl
+dnl This file is free software; as a special exception the author gives
+dnl unlimited permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+dnl This file is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+
+dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
+dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
+dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
+dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
+dnl with the API version to also check the API compatibility. Example:
+dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
+dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
+dnl this features allows to prevent build against newer versions of libgcrypt
+dnl with a changed API.
+dnl
+AC_DEFUN([AM_PATH_LIBGCRYPT],
+[ AC_ARG_WITH(libgcrypt-prefix,
+ AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
+ [prefix where LIBGCRYPT is installed (optional)]),
+ libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
+ if test x$libgcrypt_config_prefix != x ; then
+ if test x${LIBGCRYPT_CONFIG+set} != xset ; then
+ LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
+ fi
+ fi
+
+ AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
+ tmp=ifelse([$1], ,1:1.2.0,$1)
+ if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
+ req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
+ min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
+ else
+ req_libgcrypt_api=0
+ min_libgcrypt_version="$tmp"
+ fi
+
+ AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
+ ok=no
+ if test "$LIBGCRYPT_CONFIG" != "no" ; then
+ req_major=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
+ req_minor=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
+ req_micro=`echo $min_libgcrypt_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
+ libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
+ major=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
+ minor=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
+ micro=`echo $libgcrypt_config_version | \
+ sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
+ if test "$major" -gt "$req_major"; then
+ ok=yes
+ else
+ if test "$major" -eq "$req_major"; then
+ if test "$minor" -gt "$req_minor"; then
+ ok=yes
+ else
+ if test "$minor" -eq "$req_minor"; then
+ if test "$micro" -ge "$req_micro"; then
+ ok=yes
+ fi
+ fi
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ AC_MSG_RESULT([yes ($libgcrypt_config_version)])
+ else
+ AC_MSG_RESULT(no)
+ fi
+ if test $ok = yes; then
+ # If we have a recent libgcrypt, we should also check that the
+ # API is compatible
+ if test "$req_libgcrypt_api" -gt 0 ; then
+ tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
+ if test "$tmp" -gt 0 ; then
+ AC_MSG_CHECKING([LIBGCRYPT API version])
+ if test "$req_libgcrypt_api" -eq "$tmp" ; then
+ AC_MSG_RESULT([okay])
+ else
+ ok=no
+ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
+ fi
+ fi
+ fi
+ fi
+ if test $ok = yes; then
+ LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
+ LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
+ ifelse([$2], , :, [$2])
+ if test x"$host" != x ; then
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ if test x"$libgcrypt_config_host" != xnone ; then
+ if test x"$libgcrypt_config_host" != x"$host" ; then
+ AC_MSG_WARN([[
+***
+*** The config script $LIBGCRYPT_CONFIG was
+*** built for $libgcrypt_config_host and thus may not match the
+*** used host $host.
+*** You may want to use the configure option --with-libgcrypt-prefix
+*** to specify a matching config script.
+***]])
+ fi
+ fi
+ fi
+ else
+ LIBGCRYPT_CFLAGS=""
+ LIBGCRYPT_LIBS=""
+ ifelse([$3], , :, [$3])
+ fi
+ AC_SUBST(LIBGCRYPT_CFLAGS)
+ AC_SUBST(LIBGCRYPT_LIBS)
+])
--- /dev/null
+# libgcrypt.vers - What symbols to export -*- std -*-
+# Copyright (C) 2002, 2004, 2008 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser general Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+# NOTE: When adding new functions, please make sure to add them to
+# visibility.h and libgcrypt.def as well.
+
+GCRYPT_1.2 {
+ global:
+ gcry_check_version; gcry_control;
+ gcry_set_allocation_handler; gcry_set_fatalerror_handler;
+ gcry_set_gettext_handler; gcry_set_log_handler;
+ gcry_set_outofcore_handler; gcry_set_progress_handler;
+
+ gcry_err_code_from_errno; gcry_err_code_to_errno;
+ gcry_err_make_from_errno; gcry_error_from_errno;
+ gcry_strerror; gcry_strsource;
+
+ gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc;
+ gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure;
+ gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc;
+ gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup;
+
+ gcry_md_algo_info; gcry_md_algo_name; gcry_md_close;
+ gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
+ gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
+ gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
+ gcry_md_list; gcry_md_map_name; gcry_md_open; gcry_md_read;
+ gcry_md_register; gcry_md_reset; gcry_md_setkey;
+ gcry_md_unregister; gcry_md_write; gcry_md_debug;
+
+ gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
+ gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
+ gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
+ gcry_cipher_info; gcry_cipher_list; gcry_cipher_map_name;
+ gcry_cipher_mode_from_oid; gcry_cipher_open;
+ gcry_cipher_register; gcry_cipher_unregister;
+ gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
+
+ gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
+ gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
+ gcry_pk_get_keygrip; gcry_pk_get_nbits; gcry_pk_list;
+ gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
+ gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify;
+ gcry_pk_get_curve; gcry_pk_get_param;
+
+ gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy;
+ gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set;
+ gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open;
+ gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate;
+ gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test;
+ gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy;
+ gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt;
+ gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name;
+ gcry_ac_name_to_id; gcry_ac_list; gcry_ac_data_encode;
+ gcry_ac_data_decode; gcry_ac_mpi_to_os; gcry_ac_mpi_to_os_alloc;
+ gcry_ac_os_to_mpi; gcry_ac_data_encrypt_scheme;
+ gcry_ac_data_decrypt_scheme;
+ gcry_ac_data_sign_scheme; gcry_ac_data_verify_scheme;
+ gcry_ac_data_to_sexp; gcry_ac_data_from_sexp;
+ gcry_ac_io_init; gcry_ac_io_init_va;
+
+ gcry_kdf_derive;
+
+ gcry_prime_check; gcry_prime_generate;
+ gcry_prime_group_generator; gcry_prime_release_factors;
+
+ gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure;
+ gcry_randomize; gcry_create_nonce;
+
+ gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build;
+ gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len;
+ gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create;
+ gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length;
+ gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data;
+ gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release;
+ gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist;
+ gcry_sexp_nth_string;
+
+ gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint;
+ gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit;
+ gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div;
+ gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits;
+ gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul;
+ gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
+ gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
+ gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
+ gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque;
+ gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
+ gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
+ gcry_mpi_lshift;
+
+ local:
+ *;
+
+};
--- /dev/null
+/* misc.c
+ * Copyright (C) 1999, 2001, 2002, 2003, 2007,
+ * 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "secmem.h"
+
+static int verbosity_level = 0;
+
+static void (*fatal_error_handler)(void*,int, const char*) = NULL;
+static void *fatal_error_handler_value = 0;
+static void (*log_handler)(void*,int, const char*, va_list) = NULL;
+static void *log_handler_value = 0;
+
+static const char *(*user_gettext_handler)( const char * ) = NULL;
+
+void
+gcry_set_gettext_handler( const char *(*f)(const char*) )
+{
+ user_gettext_handler = f;
+}
+
+
+const char *
+_gcry_gettext( const char *key )
+{
+ if( user_gettext_handler )
+ return user_gettext_handler( key );
+ /* FIXME: switch the domain to gnupg and restore later */
+ return key;
+}
+
+void
+gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
+{
+ fatal_error_handler_value = value;
+ fatal_error_handler = fnc;
+}
+
+static void
+write2stderr( const char *s )
+{
+ /* Dummy variable to silence gcc warning. */
+ int res = write( 2, s, strlen(s) );
+ (void) res;
+}
+
+/*
+ * This function is called for fatal errors. A caller might want to
+ * set his own handler because this function simply calls abort().
+ */
+void
+_gcry_fatal_error (int rc, const char *text)
+{
+ if ( !text ) /* get a default text */
+ text = gpg_strerror (rc);
+
+ if (fatal_error_handler && !fips_mode () )
+ fatal_error_handler (fatal_error_handler_value, rc, text);
+
+ fips_signal_fatal_error (text);
+ write2stderr("\nFatal error: ");
+ write2stderr(text);
+ write2stderr("\n");
+ _gcry_secmem_term ();
+ abort ();
+}
+
+void
+gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
+ void *opaque )
+{
+ log_handler = f;
+ log_handler_value = opaque;
+}
+
+void
+_gcry_set_log_verbosity( int level )
+{
+ verbosity_level = level;
+}
+
+int
+_gcry_log_verbosity( int level )
+{
+ return verbosity_level >= level;
+}
+
+/****************
+ * This is our log function which prints all log messages to stderr or
+ * using the function defined with gcry_set_log_handler().
+ */
+static void
+_gcry_logv( int level, const char *fmt, va_list arg_ptr )
+{
+ if (log_handler)
+ log_handler (log_handler_value, level, fmt, arg_ptr);
+ else
+ {
+ switch (level)
+ {
+ case GCRY_LOG_CONT: break;
+ case GCRY_LOG_INFO: break;
+ case GCRY_LOG_WARN: break;
+ case GCRY_LOG_ERROR: break;
+ case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
+ case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break;
+ case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
+ default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
+ }
+ vfprintf(stderr,fmt,arg_ptr) ;
+ }
+
+ if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
+ {
+ fips_signal_fatal_error ("internal error (fatal or bug)");
+ _gcry_secmem_term ();
+ abort ();
+ }
+}
+
+
+void
+_gcry_log( int level, const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( level, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
+void
+_gcry_bug( const char *file, int line, const char *func )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ ("... this is a bug (%s:%d:%s)\n"), file, line, func );
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line,
+ const char *func)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func );
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#else
+void
+_gcry_bug( const char *file, int line )
+{
+ _gcry_log( GCRY_LOG_BUG,
+ _("you found a bug ... (%s:%d)\n"), file, line);
+ abort(); /* never called, but it makes the compiler happy */
+}
+void
+_gcry_assert_failed (const char *expr, const char *file, int line)
+{
+ _gcry_log (GCRY_LOG_BUG,
+ ("Assertion `%s' failed (%s:%d)\n"), expr, file, line);
+ abort(); /* Never called, but it makes the compiler happy. */
+}
+#endif
+
+void
+_gcry_log_info( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+int
+_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
+{
+ va_list arg_ptr;
+
+ (void)fp;
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
+ va_end(arg_ptr);
+ return 0;
+}
+
+void
+_gcry_log_error( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_fatal( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_bug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+ abort(); /* never called, but it makes the compiler happy */
+}
+
+void
+_gcry_log_debug( const char *fmt, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
+ va_end(arg_ptr);
+}
+
+
+void
+_gcry_log_printf (const char *fmt, ...)
+{
+ va_list arg_ptr;
+
+ if (fmt)
+ {
+ va_start( arg_ptr, fmt ) ;
+ _gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
+ va_end(arg_ptr);
+ }
+}
+
+/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
+ dump, with TEXT an empty string, print a trailing linefeed,
+ otherwise print an entire debug line. */
+void
+_gcry_log_printhex (const char *text, const void *buffer, size_t length)
+{
+ if (text && *text)
+ log_debug ("%s ", text);
+ if (length)
+ {
+ const unsigned char *p = buffer;
+ log_printf ("%02X", *p);
+ for (length--, p++; length--; p++)
+ log_printf (" %02X", *p);
+ }
+ if (text)
+ log_printf ("\n");
+}
+
+
+void
+_gcry_burn_stack (int bytes)
+{
+ char buf[64];
+
+ wipememory (buf, sizeof buf);
+ bytes -= sizeof buf;
+ if (bytes > 0)
+ _gcry_burn_stack (bytes);
+}
--- /dev/null
+/* missing-string.c - missing string utilities
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001,
+ * 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "g10lib.h"
+
+
+#ifndef HAVE_STPCPY
+char *
+stpcpy(char *a,const char *b)
+{
+ while( *b )
+ *a++ = *b++;
+ *a = 0;
+
+ return (char*)a;
+}
+#endif
+
+
+#ifndef HAVE_STRCASECMP
+int
+strcasecmp( const char *a, const char *b )
+{
+ for( ; *a && *b; a++, b++ ) {
+ if( *a != *b && toupper(*a) != toupper(*b) )
+ break;
+ }
+ return *(const byte*)a - *(const byte*)b;
+}
+#endif
--- /dev/null
+/* module.c - Module management for libgcrypt.
+ * Copyright (C) 2003, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <errno.h>
+#include "g10lib.h"
+
+/* Please match these numbers with the allocated algorithm
+ numbers. */
+#define MODULE_ID_MIN 600
+#define MODULE_ID_LAST 65500
+#define MODULE_ID_USER GCRY_MODULE_ID_USER
+#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST
+
+#if MODULE_ID_MIN >= MODULE_ID_USER
+#error Need to implement a different search strategy
+#endif
+
+/* Internal function. Generate a new, unique module ID for a module
+ that should be inserted into the module chain starting at
+ MODULES. */
+static gcry_err_code_t
+_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
+{
+ unsigned int mod_id;
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t module;
+
+ /* Search for unused ID. */
+ for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++)
+ {
+ if (mod_id == MODULE_ID_USER)
+ {
+ mod_id = MODULE_ID_USER_LAST;
+ continue;
+ }
+
+ /* Search for a module with the current ID. */
+ for (module = modules; module; module = module->next)
+ if (mod_id == module->mod_id)
+ break;
+
+ if (! module)
+ /* None found -> the ID is available for use. */
+ break;
+ }
+
+ if (mod_id < MODULE_ID_LAST)
+ /* Done. */
+ *id_new = mod_id;
+ else
+ /* No free ID found. */
+ err = GPG_ERR_INTERNAL;
+
+ return err;
+}
+
+/* Add a module specification to the list ENTRIES. The new module has
+ it's use-counter set to one. */
+gcry_err_code_t
+_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
+ void *spec, void *extraspec, gcry_module_t *module)
+{
+ gcry_err_code_t err = 0;
+ gcry_module_t entry;
+
+ if (! mod_id)
+ err = _gcry_module_id_new (*entries, &mod_id);
+
+ if (! err)
+ {
+ entry = gcry_malloc (sizeof (struct gcry_module));
+ if (! entry)
+ err = gpg_err_code_from_errno (errno);
+ }
+
+ if (! err)
+ {
+ /* Fill new module entry. */
+ entry->flags = 0;
+ entry->counter = 1;
+ entry->spec = spec;
+ entry->extraspec = extraspec;
+ entry->mod_id = mod_id;
+
+ /* Link it into the list. */
+ entry->next = *entries;
+ entry->prevp = entries;
+ if (*entries)
+ (*entries)->prevp = &entry->next;
+ *entries = entry;
+
+ /* And give it to the caller. */
+ if (module)
+ *module = entry;
+ }
+ return err;
+}
+
+/* Internal function. Unlink CIPHER_ENTRY from the list of registered
+ ciphers and destroy it. */
+static void
+_gcry_module_drop (gcry_module_t entry)
+{
+ *entry->prevp = entry->next;
+ if (entry->next)
+ entry->next->prevp = entry->prevp;
+
+ gcry_free (entry);
+}
+
+/* Lookup a module specification by it's ID. After a successful
+ lookup, the module has it's resource counter incremented. */
+gcry_module_t
+_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
+{
+ gcry_module_t entry;
+
+ for (entry = entries; entry; entry = entry->next)
+ if (entry->mod_id == mod_id)
+ {
+ entry->counter++;
+ break;
+ }
+
+ return entry;
+}
+
+/* Lookup a module specification. After a successful lookup, the
+ module has it's resource counter incremented. FUNC is a function
+ provided by the caller, which is responsible for identifying the
+ wanted module. */
+gcry_module_t
+_gcry_module_lookup (gcry_module_t entries, void *data,
+ gcry_module_lookup_t func)
+{
+ gcry_module_t entry;
+
+ for (entry = entries; entry; entry = entry->next)
+ if ((*func) (entry->spec, data))
+ {
+ entry->counter++;
+ break;
+ }
+
+ return entry;
+}
+
+/* Release a module. In case the use-counter reaches zero, destroy
+ the module. Passing MODULE as NULL is a dummy operation (similar
+ to free()). */
+void
+_gcry_module_release (gcry_module_t module)
+{
+ if (module && ! --module->counter)
+ _gcry_module_drop (module);
+}
+
+/* Add a reference to a module. */
+void
+_gcry_module_use (gcry_module_t module)
+{
+ ++module->counter;
+}
+
+/* If LIST is zero, write the number of modules identified by MODULES
+ to LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_err_code_t
+_gcry_module_list (gcry_module_t modules,
+ int *list, int *list_length)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ gcry_module_t module;
+ int length, i;
+
+ for (module = modules, length = 0; module; module = module->next, length++);
+
+ if (list)
+ {
+ if (length > *list_length)
+ length = *list_length;
+
+ for (module = modules, i = 0; i < length; module = module->next, i++)
+ list[i] = module->mod_id;
+
+ if (length < *list_length)
+ *list_length = length;
+ }
+ else
+ *list_length = length;
+
+ return err;
+}
--- /dev/null
+/* mpi.h - Multi Precision Integers
+ * Copyright (C) 1994, 1996, 1998,
+ * 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Note: This code is heavily based on the GNU MP Library.
+ * Actually it's the same code with only minor changes in the
+ * way the data is stored; this is to support the abstraction
+ * of an optional secure memory allocation which may be used
+ * to avoid revealing of sensitive data due to paging etc.
+ */
+
+#ifndef G10_MPI_H
+#define G10_MPI_H
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "types.h"
+#include "../mpi/mpi-asm-defs.h"
+
+#include "g10lib.h"
+
+#ifndef _GCRYPT_IN_LIBGCRYPT
+#error this file should only be used inside libgcrypt
+#endif
+
+#ifndef BITS_PER_MPI_LIMB
+#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
+ typedef unsigned int mpi_limb_t;
+ typedef signed int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
+ typedef unsigned long int mpi_limb_t;
+ typedef signed long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
+ typedef unsigned long long int mpi_limb_t;
+ typedef signed long long int mpi_limb_signed_t;
+#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
+ typedef unsigned short int mpi_limb_t;
+ typedef signed short int mpi_limb_signed_t;
+#else
+#error BYTES_PER_MPI_LIMB does not match any C type
+#endif
+#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
+#endif /*BITS_PER_MPI_LIMB*/
+
+#define DBG_MPI _gcry_get_debug_flag( 2 );
+
+struct gcry_mpi
+{
+ int alloced; /* Array size (# of allocated limbs). */
+ int nlimbs; /* Number of valid limbs. */
+ int sign; /* Indicates a negative number and is also used
+ for opaque MPIs to store the length. */
+ unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
+ /* Bit 2: the limb is a pointer to some m_alloced data.*/
+ mpi_limb_t *d; /* Array with the limbs */
+};
+
+#define MPI_NULL NULL
+
+#define mpi_get_nlimbs(a) ((a)->nlimbs)
+#define mpi_is_neg(a) ((a)->sign)
+
+/*-- mpiutil.c --*/
+
+#ifdef M_DEBUG
+# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
+# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
+# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) )
+# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
+# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) )
+ gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
+ void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info );
+ void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info );
+ gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info );
+#else
+# define mpi_alloc(n) _gcry_mpi_alloc((n) )
+# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
+# define mpi_free(a) _gcry_mpi_free((a) )
+# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
+# define mpi_copy(a) _gcry_mpi_copy((a))
+ gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
+ void _gcry_mpi_free( gcry_mpi_t a );
+ void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs );
+ gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
+#endif
+
+#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
+#define mpi_is_secure(a) ((a) && ((a)->flags&1))
+#define mpi_clear(a) _gcry_mpi_clear ((a))
+#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a))
+#define mpi_set(a,b) _gcry_mpi_set ((a),(b))
+#define mpi_set_ui(a,b) _gcry_mpi_set_ui ((a),(b))
+#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b))
+#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
+#define mpi_m_check(a) _gcry_mpi_m_check ((a))
+#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
+#define mpi_new(n) _gcry_mpi_new ((n))
+#define mpi_snew(n) _gcry_mpi_snew ((n))
+
+void _gcry_mpi_clear( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
+gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
+gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
+void _gcry_mpi_m_check( gcry_mpi_t a );
+void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
+gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
+
+/*-- mpicoder.c --*/
+void _gcry_log_mpidump( const char *text, gcry_mpi_t a );
+u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
+byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
+byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
+void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
+ unsigned int nbytes, int sign );
+
+#define log_mpidump _gcry_log_mpidump
+
+/*-- mpi-add.c --*/
+#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
+#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
+#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
+#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
+#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
+#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
+
+
+/*-- mpi-mul.c --*/
+#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
+#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
+#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
+#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
+
+
+/*-- mpi-div.c --*/
+#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c))
+#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c))
+#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c))
+#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c))
+#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d))
+#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
+#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b))
+
+ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor );
+void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
+void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
+void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
+int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
+
+
+/*-- mpi-mod.c --*/
+#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m))
+#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f))
+#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c))
+#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c))
+#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c))
+
+void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+
+/* Context used with Barrett reduction. */
+struct barrett_ctx_s;
+typedef struct barrett_ctx_s *mpi_barrett_t;
+
+mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
+void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
+void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
+void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
+ mpi_barrett_t ctx);
+
+
+
+/*-- mpi-gcd.c --*/
+
+/*-- mpi-mpow.c --*/
+#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
+void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
+
+/*-- mpi-cmp.c --*/
+#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
+#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b))
+int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
+int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
+
+/*-- mpi-scan.c --*/
+#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
+int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
+void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
+unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
+
+/*-- mpi-bit.c --*/
+#define mpi_normalize(a) _gcry_mpi_normalize ((a))
+#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
+#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
+#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
+#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
+#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
+#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
+#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
+#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
+
+void _gcry_mpi_normalize( gcry_mpi_t a );
+
+/*-- mpi-inv.c --*/
+#define mpi_invm(a,b,c) _gcry_mpi_invm ((a),(b),(c))
+
+/*-- ec.c --*/
+
+/* Object to represent a point in projective coordinates. */
+struct mpi_point_s;
+typedef struct mpi_point_s mpi_point_t;
+struct mpi_point_s
+{
+ gcry_mpi_t x;
+ gcry_mpi_t y;
+ gcry_mpi_t z;
+};
+
+/* Context used with elliptic curve functions. */
+struct mpi_ec_ctx_s;
+typedef struct mpi_ec_ctx_s *mpi_ec_t;
+
+void _gcry_mpi_ec_point_init (mpi_point_t *p);
+void _gcry_mpi_ec_point_free (mpi_point_t *p);
+mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
+void _gcry_mpi_ec_free (mpi_ec_t ctx);
+int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_dup_point (mpi_point_t *result,
+ mpi_point_t *point, mpi_ec_t ctx);
+void _gcry_mpi_ec_add_points (mpi_point_t *result,
+ mpi_point_t *p1, mpi_point_t *p2,
+ mpi_ec_t ctx);
+void _gcry_mpi_ec_mul_point (mpi_point_t *result,
+ gcry_mpi_t scalar, mpi_point_t *point,
+ mpi_ec_t ctx);
+
+
+
+#endif /*G10_MPI_H*/
--- /dev/null
+/* secmem.c - memory allocation from a secure heap
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ * 2003, 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stddef.h>
+
+#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#ifdef USE_CAPABILITIES
+#include <sys/capability.h>
+#endif
+#endif
+
+#include "ath.h"
+#include "g10lib.h"
+#include "secmem.h"
+
+#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+#define MINIMUM_POOL_SIZE 16384
+#define STANDARD_POOL_SIZE 32768
+#define DEFAULT_PAGE_SIZE 4096
+
+typedef struct memblock
+{
+ unsigned size; /* Size of the memory available to the
+ user. */
+ int flags; /* See below. */
+ PROPERLY_ALIGNED_TYPE aligned;
+} memblock_t;
+
+/* This flag specifies that the memory block is in use. */
+#define MB_FLAG_ACTIVE (1 << 0)
+
+/* The pool of secure memory. */
+static void *pool;
+
+/* Size of POOL in bytes. */
+static size_t pool_size;
+
+/* True, if the memory pool is ready for use. May be checked in an
+ atexit function. */
+static volatile int pool_okay;
+
+/* True, if the memory pool is mmapped. */
+static volatile int pool_is_mmapped;
+
+/* FIXME? */
+static int disable_secmem;
+static int show_warning;
+static int not_locked;
+static int no_warning;
+static int suspend_warning;
+
+/* Stats. */
+static unsigned int cur_alloced, cur_blocks;
+
+/* Lock protecting accesses to the memory pool. */
+static ath_mutex_t secmem_lock;
+
+/* Convenient macros. */
+#define SECMEM_LOCK ath_mutex_lock (&secmem_lock)
+#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock)
+
+/* The size of the memblock structure; this does not include the
+ memory that is available to the user. */
+#define BLOCK_HEAD_SIZE \
+ offsetof (memblock_t, aligned)
+
+/* Convert an address into the according memory block structure. */
+#define ADDR_TO_BLOCK(addr) \
+ (memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE)
+
+/* Check whether P points into the pool. */
+static int
+ptr_into_pool_p (const void *p)
+{
+ /* We need to convert pointers to addresses. This is required by
+ C-99 6.5.8 to avoid undefined behaviour. Using size_t is at
+ least only implementation defined. See also
+ http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
+ */
+ size_t p_addr = (size_t)p;
+ size_t pool_addr = (size_t)pool;
+
+ return p_addr >= pool_addr && p_addr < pool_addr+pool_size;
+}
+
+/* Update the stats. */
+static void
+stats_update (size_t add, size_t sub)
+{
+ if (add)
+ {
+ cur_alloced += add;
+ cur_blocks++;
+ }
+ if (sub)
+ {
+ cur_alloced -= sub;
+ cur_blocks--;
+ }
+}
+
+/* Return the block following MB or NULL, if MB is the last block. */
+static memblock_t *
+mb_get_next (memblock_t *mb)
+{
+ memblock_t *mb_next;
+
+ mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
+
+ if (! ptr_into_pool_p (mb_next))
+ mb_next = NULL;
+
+ return mb_next;
+}
+
+/* Return the block preceding MB or NULL, if MB is the first
+ block. */
+static memblock_t *
+mb_get_prev (memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ if (mb == pool)
+ mb_prev = NULL;
+ else
+ {
+ mb_prev = (memblock_t *) pool;
+ while (1)
+ {
+ mb_next = mb_get_next (mb_prev);
+ if (mb_next == mb)
+ break;
+ else
+ mb_prev = mb_next;
+ }
+ }
+
+ return mb_prev;
+}
+
+/* If the preceding block of MB and/or the following block of MB
+ exist and are not active, merge them to form a bigger block. */
+static void
+mb_merge (memblock_t *mb)
+{
+ memblock_t *mb_prev, *mb_next;
+
+ mb_prev = mb_get_prev (mb);
+ mb_next = mb_get_next (mb);
+
+ if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
+ {
+ mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
+ mb = mb_prev;
+ }
+ if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
+ mb->size += BLOCK_HEAD_SIZE + mb_next->size;
+}
+
+/* Return a new block, which can hold SIZE bytes. */
+static memblock_t *
+mb_get_new (memblock_t *block, size_t size)
+{
+ memblock_t *mb, *mb_split;
+
+ for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb))
+ if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
+ {
+ /* Found a free block. */
+ mb->flags |= MB_FLAG_ACTIVE;
+
+ if (mb->size - size > BLOCK_HEAD_SIZE)
+ {
+ /* Split block. */
+
+ mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size);
+ mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
+ mb_split->flags = 0;
+
+ mb->size = size;
+
+ mb_merge (mb_split);
+
+ }
+
+ break;
+ }
+
+ if (! ptr_into_pool_p (mb))
+ {
+ gpg_err_set_errno (ENOMEM);
+ mb = NULL;
+ }
+
+ return mb;
+}
+
+/* Print a warning message. */
+static void
+print_warn (void)
+{
+ if (!no_warning)
+ log_info (_("Warning: using insecure memory!\n"));
+}
+
+/* Lock the memory pages into core and drop privileges. */
+static void
+lock_pool (void *p, size_t n)
+{
+#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
+ int err;
+
+ cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+ cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
+
+ if (err)
+ {
+ if (errno != EPERM
+#ifdef EAGAIN /* OpenBSD returns this */
+ && errno != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented) */
+ && errno != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && errno != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined(HAVE_MLOCK)
+ uid_t uid;
+ int err;
+
+ uid = getuid ();
+
+#ifdef HAVE_BROKEN_MLOCK
+ /* Under HP/UX mlock segfaults if called by non-root. Note, we have
+ noch checked whether mlock does really work under AIX where we
+ also detected a broken nlock. Note further, that using plock ()
+ is not a good idea under AIX. */
+ if (uid)
+ {
+ errno = EPERM;
+ err = errno;
+ }
+ else
+ {
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+ }
+#else /* !HAVE_BROKEN_MLOCK */
+ err = mlock (p, n);
+ if (err && errno)
+ err = errno;
+#endif /* !HAVE_BROKEN_MLOCK */
+
+ if (uid && ! geteuid ())
+ {
+ /* check that we really dropped the privs.
+ * Note: setuid(0) should always fail */
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to reset uid: %s\n", strerror (errno));
+ }
+
+ if (err)
+ {
+ if (errno != EPERM
+#ifdef EAGAIN /* OpenBSD returns this. */
+ && errno != EAGAIN
+#endif
+#ifdef ENOSYS /* Some SCOs return this (function not implemented). */
+ && errno != ENOSYS
+#endif
+#ifdef ENOMEM /* Linux might return this. */
+ && errno != ENOMEM
+#endif
+ )
+ log_error ("can't lock memory: %s\n", strerror (err));
+ show_warning = 1;
+ not_locked = 1;
+ }
+
+#elif defined ( __QNX__ )
+ /* QNX does not page at all, so the whole secure memory stuff does
+ * not make much sense. However it is still of use because it
+ * wipes out the memory on a free().
+ * Therefore it is sufficient to suppress the warning. */
+ (void)p;
+ (void)n;
+#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
+ /* It does not make sense to print such a warning, given the fact that
+ * this whole Windows !@#$% and their user base are inherently insecure. */
+ (void)p;
+ (void)n;
+#elif defined (__riscos__)
+ /* No virtual memory on RISC OS, so no pages are swapped to disc,
+ * besides we don't have mmap, so we don't use it! ;-)
+ * But don't complain, as explained above. */
+ (void)p;
+ (void)n;
+#else
+ (void)p;
+ (void)n;
+ log_info ("Please note that you don't have secure memory on this system\n");
+#endif
+}
+
+/* Initialize POOL. */
+static void
+init_pool (size_t n)
+{
+ size_t pgsize;
+ long int pgsize_val;
+ memblock_t *mb;
+
+ pool_size = n;
+
+ if (disable_secmem)
+ log_bug ("secure memory is disabled");
+
+#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
+ pgsize_val = sysconf (_SC_PAGESIZE);
+#elif defined(HAVE_GETPAGESIZE)
+ pgsize_val = getpagesize ();
+#else
+ pgsize_val = -1;
+#endif
+ pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
+
+
+#if HAVE_MMAP
+ pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
+#ifdef MAP_ANONYMOUS
+ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+#else /* map /dev/zero instead */
+ {
+ int fd;
+
+ fd = open ("/dev/zero", O_RDWR);
+ if (fd == -1)
+ {
+ log_error ("can't open /dev/zero: %s\n", strerror (errno));
+ pool = (void *) -1;
+ }
+ else
+ {
+ pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+ close (fd);
+ }
+ }
+#endif
+ if (pool == (void *) -1)
+ log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
+ (unsigned) pool_size, strerror (errno));
+ else
+ {
+ pool_is_mmapped = 1;
+ pool_okay = 1;
+ }
+
+#endif
+ if (!pool_okay)
+ {
+ pool = malloc (pool_size);
+ if (!pool)
+ log_fatal ("can't allocate memory pool of %u bytes\n",
+ (unsigned) pool_size);
+ else
+ pool_okay = 1;
+ }
+
+ /* Initialize first memory block. */
+ mb = (memblock_t *) pool;
+ mb->size = pool_size;
+ mb->flags = 0;
+}
+
+void
+_gcry_secmem_set_flags (unsigned flags)
+{
+ int was_susp;
+
+ SECMEM_LOCK;
+
+ was_susp = suspend_warning;
+ no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
+ suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+
+ /* and now issue the warning if it is not longer suspended */
+ if (was_susp && !suspend_warning && show_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ SECMEM_UNLOCK;
+}
+
+unsigned int
+_gcry_secmem_get_flags (void)
+{
+ unsigned flags;
+
+ SECMEM_LOCK;
+
+ flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
+ flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
+ flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+
+ SECMEM_UNLOCK;
+
+ return flags;
+}
+
+
+/* See _gcry_secmem_init. This function is expected to be called with
+ the secmem lock held. */
+static void
+secmem_init (size_t n)
+{
+ if (!n)
+ {
+#ifdef USE_CAPABILITIES
+ /* drop all capabilities */
+ cap_set_proc (cap_from_text ("all-eip"));
+
+#elif !defined(HAVE_DOSISH_SYSTEM)
+ uid_t uid;
+
+ disable_secmem = 1;
+ uid = getuid ();
+ if (uid != geteuid ())
+ {
+ if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+ log_fatal ("failed to drop setuid\n");
+ }
+#endif
+ }
+ else
+ {
+ if (n < MINIMUM_POOL_SIZE)
+ n = MINIMUM_POOL_SIZE;
+ if (! pool_okay)
+ {
+ init_pool (n);
+ lock_pool (pool, n);
+ }
+ else
+ log_error ("Oops, secure memory pool already initialized\n");
+ }
+}
+
+
+
+/* Initialize the secure memory system. If running with the necessary
+ privileges, the secure memory pool will be locked into the core in
+ order to prevent page-outs of the data. Furthermore allocated
+ secure memory will be wiped out when released. */
+void
+_gcry_secmem_init (size_t n)
+{
+ SECMEM_LOCK;
+
+ secmem_init (n);
+
+ SECMEM_UNLOCK;
+}
+
+
+static void *
+_gcry_secmem_malloc_internal (size_t size)
+{
+ memblock_t *mb;
+
+ if (!pool_okay)
+ {
+ /* Try to initialize the pool if the user forgot about it. */
+ secmem_init (STANDARD_POOL_SIZE);
+ if (!pool_okay)
+ {
+ log_info (_("operation is not possible without "
+ "initialized secure memory\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ }
+ if (not_locked && fips_mode ())
+ {
+ log_info (_("secure memory pool is not locked while in FIPS mode\n"));
+ gpg_err_set_errno (ENOMEM);
+ return NULL;
+ }
+ if (show_warning && !suspend_warning)
+ {
+ show_warning = 0;
+ print_warn ();
+ }
+
+ /* Blocks are always a multiple of 32. */
+ size = ((size + 31) / 32) * 32;
+
+ mb = mb_get_new ((memblock_t *) pool, size);
+ if (mb)
+ stats_update (size, 0);
+
+ return mb ? &mb->aligned.c : NULL;
+}
+
+void *
+_gcry_secmem_malloc (size_t size)
+{
+ void *p;
+
+ SECMEM_LOCK;
+ p = _gcry_secmem_malloc_internal (size);
+ SECMEM_UNLOCK;
+
+ return p;
+}
+
+static void
+_gcry_secmem_free_internal (void *a)
+{
+ memblock_t *mb;
+ int size;
+
+ if (!a)
+ return;
+
+ mb = ADDR_TO_BLOCK (a);
+ size = mb->size;
+
+ /* This does not make much sense: probably this memory is held in the
+ * cache. We do it anyway: */
+#define MB_WIPE_OUT(byte) \
+ wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
+
+ MB_WIPE_OUT (0xff);
+ MB_WIPE_OUT (0xaa);
+ MB_WIPE_OUT (0x55);
+ MB_WIPE_OUT (0x00);
+
+ stats_update (0, size);
+
+ mb->flags &= ~MB_FLAG_ACTIVE;
+
+ /* Update stats. */
+
+ mb_merge (mb);
+}
+
+/* Wipe out and release memory. */
+void
+_gcry_secmem_free (void *a)
+{
+ SECMEM_LOCK;
+ _gcry_secmem_free_internal (a);
+ SECMEM_UNLOCK;
+}
+
+/* Realloc memory. */
+void *
+_gcry_secmem_realloc (void *p, size_t newsize)
+{
+ memblock_t *mb;
+ size_t size;
+ void *a;
+
+ SECMEM_LOCK;
+
+ mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c));
+ size = mb->size;
+ if (newsize < size)
+ {
+ /* It is easier to not shrink the memory. */
+ a = p;
+ }
+ else
+ {
+ a = _gcry_secmem_malloc_internal (newsize);
+ if (a)
+ {
+ memcpy (a, p, size);
+ memset ((char *) a + size, 0, newsize - size);
+ _gcry_secmem_free_internal (p);
+ }
+ }
+
+ SECMEM_UNLOCK;
+
+ return a;
+}
+
+
+/* Return true if P points into the secure memory area. */
+int
+_gcry_private_is_secure (const void *p)
+{
+ return pool_okay && ptr_into_pool_p (p);
+}
+
+
+/****************
+ * Warning: This code might be called by an interrupt handler
+ * and frankly, there should really be such a handler,
+ * to make sure that the memory is wiped out.
+ * We hope that the OS wipes out mlocked memory after
+ * receiving a SIGKILL - it really should do so, otherwise
+ * there is no chance to get the secure memory cleaned.
+ */
+void
+_gcry_secmem_term ()
+{
+ if (!pool_okay)
+ return;
+
+ wipememory2 (pool, 0xff, pool_size);
+ wipememory2 (pool, 0xaa, pool_size);
+ wipememory2 (pool, 0x55, pool_size);
+ wipememory2 (pool, 0x00, pool_size);
+#if HAVE_MMAP
+ if (pool_is_mmapped)
+ munmap (pool, pool_size);
+#endif
+ pool = NULL;
+ pool_okay = 0;
+ pool_size = 0;
+ not_locked = 0;
+}
+
+
+void
+_gcry_secmem_dump_stats ()
+{
+#if 1
+ SECMEM_LOCK;
+
+ if (pool_okay)
+ log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
+ cur_alloced, (unsigned long)pool_size, cur_blocks);
+ SECMEM_UNLOCK;
+#else
+ memblock_t *mb;
+ int i;
+
+ SECMEM_LOCK;
+
+ for (i = 0, mb = (memblock_t *) pool;
+ ptr_into_pool_p (mb);
+ mb = mb_get_next (mb), i++)
+ log_info ("SECMEM: [%s] block: %i; size: %i\n",
+ (mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
+ i,
+ mb->size);
+ SECMEM_UNLOCK;
+#endif
+}
--- /dev/null
+/* secmem.h - internal definitions for secmem
+ * Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_SECMEM_H
+#define G10_SECMEM_H 1
+
+void _gcry_secmem_init (size_t npool);
+void _gcry_secmem_term (void);
+void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_secmem_realloc (void *a, size_t newsize);
+void _gcry_secmem_free (void *a);
+void _gcry_secmem_dump_stats (void);
+void _gcry_secmem_set_flags (unsigned flags);
+unsigned _gcry_secmem_get_flags(void);
+int _gcry_private_is_secure (const void *p);
+
+/* Flags for _gcry_secmem_{set,get}_flags. */
+#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0)
+#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
+#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2)
+
+#endif /* G10_SECMEM_H */
--- /dev/null
+/* sexp.c - S-Expression handling
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003,
+ * 2004, 2006, 2007, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define GCRYPT_NO_MPI_MACROS 1
+#include "g10lib.h"
+
+typedef struct gcry_sexp *NODE;
+typedef unsigned short DATALEN;
+
+struct gcry_sexp
+{
+ byte d[1];
+};
+
+#define ST_STOP 0
+#define ST_DATA 1 /* datalen follows */
+#define ST_HINT 2 /* datalen follows */
+#define ST_OPEN 3
+#define ST_CLOSE 4
+
+/* the atoi macros assume that the buffer has only valid digits */
+#define atoi_1(p) (*(p) - '0' )
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+#define TOKEN_SPECIALS "-./_:*+="
+
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr);
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...);
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+#undef whitespacep
+static GPG_ERR_INLINE int
+whitespacep (const char *p)
+{
+ switch (*p)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+
+#if 0
+static void
+dump_mpi( gcry_mpi_t a )
+{
+ char buffer[1000];
+ size_t n = 1000;
+
+ if( !a )
+ fputs("[no MPI]", stderr );
+ else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
+ fputs("[MPI too large to print]", stderr );
+ else
+ fputs( buffer, stderr );
+}
+#endif
+
+static void
+dump_string (const byte *p, size_t n, int delim )
+{
+ for (; n; n--, p++ )
+ {
+ if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
+ {
+ if( *p == '\n' )
+ log_printf ("\\n");
+ else if( *p == '\r' )
+ log_printf ("\\r");
+ else if( *p == '\f' )
+ log_printf ("\\f");
+ else if( *p == '\v' )
+ log_printf ("\\v");
+ else if( *p == '\b' )
+ log_printf ("\\b");
+ else if( !*p )
+ log_printf ("\\0");
+ else
+ log_printf ("\\x%02x", *p );
+ }
+ else
+ log_printf ("%c", *p);
+ }
+}
+
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ const byte *p;
+ int indent = 0;
+ int type;
+
+ if (!a)
+ {
+ log_printf ( "[nil]\n");
+ return;
+ }
+
+ p = a->d;
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ log_printf ("%*s[open]\n", 2*indent, "");
+ indent++;
+ break;
+ case ST_CLOSE:
+ if( indent )
+ indent--;
+ log_printf ("%*s[close]\n", 2*indent, "");
+ break;
+ case ST_DATA: {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ log_printf ("%*s[data=\"", 2*indent, "" );
+ dump_string (p, n, '\"' );
+ log_printf ("\"]\n");
+ p += n;
+ }
+ break;
+ default:
+ log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
+ break;
+ }
+ }
+}
+
+/****************
+ * Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list.
+ */
+static gcry_sexp_t
+normalize ( gcry_sexp_t list )
+{
+ unsigned char *p;
+
+ if ( !list )
+ return NULL;
+ p = list->d;
+ if ( *p == ST_STOP )
+ {
+ /* this is "" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+ if ( *p == ST_OPEN && p[1] == ST_CLOSE )
+ {
+ /* this is "()" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+
+ return list;
+}
+
+/* Create a new S-expression object by reading LENGTH bytes from
+ BUFFER, assuming it is canonical encoded or autodetected encoding
+ when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of
+ the buffer is transferred to the newly created object. FREEFNC
+ should be the freefnc used to release BUFFER; there is no guarantee
+ at which point this function is called; most likey you want to use
+ free() or gcry_free().
+
+ Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
+ BUFFER points to a valid canonical encoded S-expression. A LENGTH
+ of 0 and AUTODETECT 1 indicates that buffer points to a
+ null-terminated string.
+
+ This function returns 0 and and the pointer to the new object in
+ RETSEXP or an error code in which case RETSEXP is set to NULL. */
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
+ int autodetect, void (*freefnc)(void*) )
+{
+ gcry_error_t errcode;
+ gcry_sexp_t se;
+
+ if (!retsexp)
+ return gcry_error (GPG_ERR_INV_ARG);
+ *retsexp = NULL;
+ if (autodetect < 0 || autodetect > 1 || !buffer)
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ if (!length && !autodetect)
+ { /* What a brave caller to assume that there is really a canonical
+ encoded S-expression in buffer */
+ length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+ if (!length)
+ return errcode;
+ }
+ else if (!length && autodetect)
+ { /* buffer is a string */
+ length = strlen ((char *)buffer);
+ }
+
+ errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL);
+ if (errcode)
+ return errcode;
+
+ *retsexp = se;
+ if (freefnc)
+ {
+ /* For now we release the buffer immediately. As soon as we
+ have changed the internal represenation of S-expression to
+ the canoncial format - which has the advantage of faster
+ parsing - we will use this function as a closure in our
+ GCRYSEXP object and use the BUFFER directly. */
+ freefnc (buffer);
+ }
+ return gcry_error (GPG_ERR_NO_ERROR);
+}
+
+/* Same as gcry_sexp_create but don't transfer ownership */
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
+ int autodetect)
+{
+ return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+}
+
+
+/****************
+ * Release resource of the given SEXP object.
+ */
+void
+gcry_sexp_release( gcry_sexp_t sexp )
+{
+ if (sexp)
+ {
+ if (gcry_is_secure (sexp))
+ {
+ /* Extra paranoid wiping. */
+ const byte *p = sexp->d;
+ int type;
+
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ break;
+ case ST_CLOSE:
+ break;
+ case ST_DATA:
+ {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ p += n;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ wipememory (sexp->d, p - sexp->d);
+ }
+ gcry_free ( sexp );
+ }
+}
+
+
+/****************
+ * Make a pair from lists a and b, don't use a or b later on.
+ * Special behaviour: If one is a single element list we put the
+ * element straight into the new pair.
+ */
+gcry_sexp_t
+gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
+{
+ (void)a;
+ (void)b;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Make a list from all items in the array the end of the array is marked
+ * with a NULL.
+ */
+gcry_sexp_t
+gcry_sexp_alist( const gcry_sexp_t *array )
+{
+ (void)array;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+/****************
+ * Make a list from all items, the end of list is indicated by a NULL
+ */
+gcry_sexp_t
+gcry_sexp_vlist( const gcry_sexp_t a, ... )
+{
+ (void)a;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Append n to the list a
+ * Returns: a new ist (which maybe a)
+ */
+gcry_sexp_t
+gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+
+/****************
+ * Locate token in a list. The token must be the car of a sublist.
+ * Returns: A new list with this sublist or NULL if not found.
+ */
+gcry_sexp_t
+gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
+{
+ const byte *p;
+ DATALEN n;
+
+ if ( !list )
+ return NULL;
+
+ if ( !toklen )
+ toklen = strlen(tok);
+
+ p = list->d;
+ while ( *p != ST_STOP )
+ {
+ if ( *p == ST_OPEN && p[1] == ST_DATA )
+ {
+ const byte *head = p;
+
+ p += 2;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ if ( n == toklen && !memcmp( p, tok, toklen ) )
+ { /* found it */
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 1;
+
+ /* Look for the end of the list. */
+ for ( p += n; level; p++ )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--; /* Compensate for later increment. */
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ BUG ();
+ }
+ }
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ {
+ /* No way to return an error code, so we can only
+ return Not Found. */
+ return NULL;
+ }
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ return normalize ( newlist );
+ }
+ p += n;
+ }
+ else if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n ); p += sizeof n;
+ p += n;
+ }
+ else
+ p++;
+ }
+ return NULL;
+}
+
+/****************
+ * Return the length of the given list
+ */
+int
+gcry_sexp_length( const gcry_sexp_t list )
+{
+ const byte *p;
+ DATALEN n;
+ int type;
+ int length = 0;
+ int level = 0;
+
+ if ( !list )
+ return 0;
+
+ p = list->d;
+ while ( (type=*p) != ST_STOP ) {
+ p++;
+ if ( type == ST_DATA ) {
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n + n;
+ if ( level == 1 )
+ length++;
+ }
+ else if ( type == ST_OPEN ) {
+ if ( level == 1 )
+ length++;
+ level++;
+ }
+ else if ( type == ST_CLOSE ) {
+ level--;
+ }
+ }
+ return length;
+}
+
+
+/* Return the internal lengths offset of LIST. That is the size of
+ the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+ the corresponding ST_CLOSE inclusive. */
+static size_t
+get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
+{
+ const unsigned char *p;
+ DATALEN n;
+ int type;
+ int level = 0;
+
+ *r_off = 0;
+ if (list)
+ {
+ p = list->d;
+ while ( (type=*p) != ST_STOP )
+ {
+ p++;
+ if (type == ST_DATA)
+ {
+ memcpy (&n, p, sizeof n);
+ p += sizeof n + n;
+ }
+ else if (type == ST_OPEN)
+ {
+ if (!level)
+ *r_off = (p-1) - list->d;
+ level++;
+ }
+ else if ( type == ST_CLOSE )
+ {
+ level--;
+ if (!level)
+ return p - list->d;
+ }
+ }
+ }
+ return 0; /* Not a proper list. */
+}
+
+
+
+/* Extract the CAR of the given list. May return NULL for bad lists
+ or memory failure. */
+gcry_sexp_t
+gcry_sexp_nth( const gcry_sexp_t list, int number )
+{
+ const byte *p;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( number > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, p, sizeof n ); p += sizeof n;
+ newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, p, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else if ( *p == ST_OPEN ) {
+ const byte *head = p;
+
+ level = 1;
+ do {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ BUG ();
+ }
+ } while ( level );
+ n = p + 1 - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else
+ newlist = NULL;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_car( const gcry_sexp_t list )
+{
+ return gcry_sexp_nth ( list, 0 );
+}
+
+
+/* Helper to get data from the car. The returned value is valid as
+ long as the list is not modified. */
+static const char *
+sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ const byte *p;
+ DATALEN n;
+ int level = 0;
+
+ *datalen = 0;
+ if ( !list )
+ return NULL;
+
+ p = list->d;
+ if ( *p == ST_OPEN )
+ p++; /* Yep, a list. */
+ else if (number)
+ return NULL; /* Not a list but N > 0 requested. */
+
+ /* Skip over N elements. */
+ while ( number > 0 )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ return NULL;
+ }
+ p++;
+ }
+
+ /* If this is data, return it. */
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ *datalen = n;
+ return (const char*)p + sizeof n;
+ }
+
+ return NULL;
+}
+
+
+/* Get data from the car. The returned value is valid as long as the
+ list is not modified. */
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+{
+ return sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get a string from the car. The returned value is a malloced string
+ and needs to be freed by the caller. */
+char *
+gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s || n < 1 || (n+1) < 1)
+ return NULL;
+ buf = gcry_malloc (n+1);
+ if (!buf)
+ return NULL;
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ return buf;
+}
+
+/*
+ * Get a MPI from the car
+ */
+gcry_mpi_t
+gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
+{
+ const char *s;
+ size_t n;
+ gcry_mpi_t a;
+
+ if ( !mpifmt )
+ mpifmt = GCRYMPI_FMT_STD;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s)
+ return NULL;
+
+ if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
+ return NULL;
+
+ return a;
+}
+
+
+/****************
+ * Get the CDR
+ */
+gcry_sexp_t
+gcry_sexp_cdr( const gcry_sexp_t list )
+{
+ const byte *p;
+ const byte *head;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+ int skip = 1;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( skip > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ head = p;
+ level = 0;
+ do {
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ p++;
+ } while ( level );
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n + 2 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ *d++ = ST_OPEN;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_CLOSE;
+ *d++ = ST_STOP;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr ( const gcry_sexp_t list )
+{
+ gcry_sexp_t a, b;
+
+ a = gcry_sexp_cdr ( list );
+ b = gcry_sexp_car ( a );
+ gcry_sexp_release ( a );
+ return b;
+}
+
+
+
+static int
+hextobyte( const byte *s )
+{
+ int c=0;
+
+ if( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c = 16 * (10 + *s - 'a');
+ }
+ s++;
+ if( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c += 10 + *s - 'a';
+ }
+ return c;
+}
+
+struct make_space_ctx {
+ gcry_sexp_t sexp;
+ size_t allocated;
+ byte *pos;
+};
+
+static gpg_err_code_t
+make_space ( struct make_space_ctx *c, size_t n )
+{
+ size_t used = c->pos - c->sexp->d;
+
+ if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
+ {
+ gcry_sexp_t newsexp;
+ byte *newhead;
+ size_t newsize;
+
+ newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
+ if (newsize <= c->allocated)
+ return GPG_ERR_TOO_LARGE;
+ newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
+ if (!newsexp)
+ return gpg_err_code_from_errno (errno);
+ c->allocated = newsize;
+ newhead = newsexp->d;
+ c->pos = newhead + used;
+ c->sexp = newsexp;
+ }
+ return 0;
+}
+
+
+/* Unquote STRING of LENGTH and store it into BUF. The surrounding
+ quotes are must already be removed from STRING. We assume that the
+ quoted string is syntacillay correct. */
+static size_t
+unquote_string (const char *string, size_t length, unsigned char *buf)
+{
+ int esc = 0;
+ const unsigned char *s = (const unsigned char*)string;
+ unsigned char *d = buf;
+ size_t n = length;
+
+ for (; n; n--, s++)
+ {
+ if (esc)
+ {
+ switch (*s)
+ {
+ case 'b': *d++ = '\b'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'r': *d++ = '\r'; break;
+ case '"': *d++ = '\"'; break;
+ case '\'': *d++ = '\''; break;
+ case '\\': *d++ = '\\'; break;
+
+ case '\r': /* ignore CR[,LF] */
+ if (n>1 && s[1] == '\n')
+ {
+ s++; n--;
+ }
+ break;
+
+ case '\n': /* ignore LF[,CR] */
+ if (n>1 && s[1] == '\r')
+ {
+ s++; n--;
+ }
+ break;
+
+ case 'x': /* hex value */
+ if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
+ {
+ s++; n--;
+ *d++ = xtoi_2 (s);
+ s++; n--;
+ }
+ break;
+
+ default:
+ if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
+ {
+ *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
+ s += 2;
+ n -= 2;
+ }
+ break;
+ }
+ esc = 0;
+ }
+ else if( *s == '\\' )
+ esc = 1;
+ else
+ *d++ = *s;
+ }
+
+ return d - buf;
+}
+
+/****************
+ * Scan the provided buffer and return the S expression in our internal
+ * format. Returns a newly allocated expression. If erroff is not NULL and
+ * a parsing error has occurred, the offset into buffer will be returned.
+ * If ARGFLAG is true, the function supports some printf like
+ * expressions.
+ * These are:
+ * %m - MPI
+ * %s - string (no autoswitch to secure allocation)
+ * %d - integer stored as string (no autoswitch to secure allocation)
+ * %b - memory buffer; this takes _two_ arguments: an integer with the
+ * length of the buffer and a pointer to the buffer.
+ * %S - Copy an gcry_sexp_t here. The S-expression needs to be a
+ * regular one, starting with a parenthesis.
+ * (no autoswitch to secure allocation)
+ * all other format elements are currently not defined and return an error.
+ * this includes the "%%" sequence becauce the percent sign is not an
+ * allowed character.
+ * FIXME: We should find a way to store the secure-MPIs not in the string
+ * but as reference to somewhere - this can help us to save huge amounts
+ * of secure memory. The problem is, that if only one element is secure, all
+ * other elements are automagicaly copied to secure memory too, so the most
+ * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
+ * regardless whether it is needed or not.
+ */
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr)
+{
+ gcry_err_code_t err = 0;
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ const char *p;
+ size_t n;
+ const char *digptr = NULL;
+ const char *quoted = NULL;
+ const char *tokenp = NULL;
+ const char *hexfmt = NULL;
+ const char *base64 = NULL;
+ const char *disphint = NULL;
+ const char *percent = NULL;
+ int hexcount = 0;
+ int quoted_esc = 0;
+ int datalen = 0;
+ size_t dummy_erroff;
+ struct make_space_ctx c;
+ int arg_counter = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+
+ /* Depending on whether ARG_LIST is non-zero or not, this macro gives
+ us the next argument, either from the variable argument list as
+ specified by ARG_PTR or from the argument array ARG_LIST. */
+#define ARG_NEXT(storage, type) \
+ do \
+ { \
+ if (!arg_list) \
+ storage = va_arg (arg_ptr, type); \
+ else \
+ storage = *((type *) (arg_list[arg_counter++])); \
+ } \
+ while (0)
+
+ /* The MAKE_SPACE macro is used before each store operation to
+ ensure that the buffer is large enough. It requires a global
+ context named C and jumps out to the label LEAVE on error! It
+ also sets ERROFF using the variables BUFFER and P. */
+#define MAKE_SPACE(n) do { \
+ gpg_err_code_t _ms_err = make_space (&c, (n)); \
+ if (_ms_err) \
+ { \
+ err = _ms_err; \
+ *erroff = p - buffer; \
+ goto leave; \
+ } \
+ } while (0)
+
+ /* The STORE_LEN macro is used to store the length N at buffer P. */
+#define STORE_LEN(p,n) do { \
+ DATALEN ashort = (n); \
+ memcpy ( (p), &ashort, sizeof(ashort) ); \
+ (p) += sizeof (ashort); \
+ } while (0)
+
+ /* We assume that the internal representation takes less memory than
+ the provided one. However, we add space for one extra datalen so
+ that the code which does the ST_CLOSE can use MAKE_SPACE */
+ c.allocated = length + sizeof(DATALEN);
+ if (buffer && length && gcry_is_secure (buffer))
+ c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
+ else
+ c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
+ if (!c.sexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ *erroff = 0;
+ goto leave;
+ }
+ c.pos = c.sexp->d;
+
+ for (p = buffer, n = length; n; p++, n--)
+ {
+ if (tokenp && !hexfmt)
+ {
+ if (strchr (tokenchars, *p))
+ continue;
+ else
+ {
+ datalen = p - tokenp;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, tokenp, datalen);
+ c.pos += datalen;
+ tokenp = NULL;
+ }
+ }
+
+ if (quoted)
+ {
+ if (quoted_esc)
+ {
+ switch (*p)
+ {
+ case 'b': case 't': case 'v': case 'n': case 'f':
+ case 'r': case '"': case '\'': case '\\':
+ quoted_esc = 0;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ if (!((n > 2)
+ && (p[1] >= '0') && (p[1] <= '7')
+ && (p[2] >= '0') && (p[2] <= '7')))
+ {
+ *erroff = p - buffer;
+ /* Invalid octal value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case 'x':
+ if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
+ {
+ *erroff = p - buffer;
+ /* Invalid hex value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case '\r':
+ /* ignore CR[,LF] */
+ if (n && (p[1] == '\n'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ case '\n':
+ /* ignore LF[,CR] */
+ if (n && (p[1] == '\r'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ default:
+ *erroff = p - buffer;
+ /* Invalid quoted string escape. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ }
+ else if (*p == '\\')
+ quoted_esc = 1;
+ else if (*p == '\"')
+ {
+ /* Keep it easy - we know that the unquoted string will
+ never be larger. */
+ unsigned char *save;
+ size_t len;
+
+ quoted++; /* Skip leading quote. */
+ MAKE_SPACE (p - quoted);
+ *c.pos++ = ST_DATA;
+ save = c.pos;
+ STORE_LEN (c.pos, 0); /* Will be fixed up later. */
+ len = unquote_string (quoted, p - quoted, c.pos);
+ c.pos += len;
+ STORE_LEN (save, len);
+ quoted = NULL;
+ }
+ }
+ else if (hexfmt)
+ {
+ if (isxdigit (*p))
+ hexcount++;
+ else if (*p == '#')
+ {
+ if ((hexcount & 1))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
+ goto leave;
+ }
+
+ datalen = hexcount / 2;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ for (hexfmt++; hexfmt < p; hexfmt++)
+ {
+ if (whitespacep (hexfmt))
+ continue;
+ *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
+ hexfmt++;
+ }
+ hexfmt = NULL;
+ }
+ else if (!whitespacep (p))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_HEX_CHAR;
+ goto leave;
+ }
+ }
+ else if (base64)
+ {
+ if (*p == '|')
+ base64 = NULL;
+ }
+ else if (digptr)
+ {
+ if (digitp (p))
+ ;
+ else if (*p == ':')
+ {
+ datalen = atoi (digptr); /* FIXME: check for overflow. */
+ digptr = NULL;
+ if (datalen > n - 1)
+ {
+ *erroff = p - buffer;
+ /* Buffer too short. */
+ err = GPG_ERR_SEXP_STRING_TOO_LONG;
+ goto leave;
+ }
+ /* Make a new list entry. */
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, p + 1, datalen);
+ c.pos += datalen;
+ n -= datalen;
+ p += datalen;
+ }
+ else if (*p == '\"')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ base64 = p;
+ }
+ else
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ }
+ else if (percent)
+ {
+ if (*p == 'm' || *p == 'M')
+ {
+ /* Insert an MPI. */
+ gcry_mpi_t m;
+ size_t nm = 0;
+ int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
+
+ ARG_NEXT (m, gcry_mpi_t);
+
+ if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
+ {
+ void *mp;
+ unsigned int nbits;
+
+ mp = gcry_mpi_get_opaque (m, &nbits);
+ nm = (nbits+7)/8;
+ if (mp && nm)
+ {
+ MAKE_SPACE (nm);
+ if (!gcry_is_secure (c.sexp->d)
+ && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ memcpy (c.pos, mp, nm);
+ c.pos += nm;
+ }
+ }
+ else
+ {
+ if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
+ BUG ();
+
+ MAKE_SPACE (nm);
+ if (!gcry_is_secure (c.sexp->d)
+ && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
+ BUG ();
+ c.pos += nm;
+ }
+ }
+ else if (*p == 's')
+ {
+ /* Insert an string. */
+ const char *astr;
+ size_t alen;
+
+ ARG_NEXT (astr, const char *);
+ alen = strlen (astr);
+
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'b')
+ {
+ /* Insert a memory buffer. */
+ const char *astr;
+ int alen;
+
+ ARG_NEXT (alen, int);
+ ARG_NEXT (astr, const char *);
+
+ MAKE_SPACE (alen);
+ if (alen
+ && !gcry_is_secure (c.sexp->d)
+ && gcry_is_secure (astr))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'd')
+ {
+ /* Insert an integer as string. */
+ int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, int);
+ sprintf (buf, "%d", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'u')
+ {
+ /* Insert an unsigned integer as string. */
+ unsigned int aint;
+ size_t alen;
+ char buf[35];
+
+ ARG_NEXT (aint, unsigned int);
+ sprintf (buf, "%u", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'S')
+ {
+ /* Insert a gcry_sexp_t. */
+ gcry_sexp_t asexp;
+ size_t alen, aoff;
+
+ ARG_NEXT (asexp, gcry_sexp_t);
+ alen = get_internal_buffer (asexp, &aoff);
+ if (alen)
+ {
+ MAKE_SPACE (alen);
+ memcpy (c.pos, asexp->d + aoff, alen);
+ c.pos += alen;
+ }
+ }
+ else
+ {
+ *erroff = p - buffer;
+ /* Invalid format specifier. */
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ percent = NULL;
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_OPEN;
+ level++;
+ }
+ else if (*p == ')')
+ {
+ /* Walk up. */
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_CLOSE;
+ level--;
+ }
+ else if (*p == '\"')
+ {
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ base64 = p;
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_NESTED_DH;
+ goto leave;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if (!disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p))
+ {
+ if (*p == '0')
+ {
+ /* A length may not begin with zero. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ZERO_PREFIX;
+ goto leave;
+ }
+ digptr = p;
+ }
+ else if (strchr (tokenchars, *p))
+ tokenp = p;
+ else if (whitespacep (p))
+ ;
+ else if (*p == '{')
+ {
+ /* fixme: handle rescanning: we can do this by saving our
+ current state and start over at p+1 -- Hmmm. At this
+ point here we are in a well defined state, so we don't
+ need to save it. Great. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (strchr ("&\\", *p))
+ {
+ /* Reserved punctuation. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (argflag && (*p == '%'))
+ percent = p;
+ else
+ {
+ /* Bad or unavailable. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_CHARACTER;
+ goto leave;
+ }
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_STOP;
+
+ if (level && !err)
+ err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+
+ leave:
+ if (err)
+ {
+ /* Error -> deallocate. */
+ if (c.sexp)
+ {
+ /* Extra paranoid wipe on error. */
+ if (gcry_is_secure (c.sexp))
+ wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
+ gcry_free (c.sexp);
+ }
+ /* This might be expected by existing code... */
+ *retsexp = NULL;
+ }
+ else
+ *retsexp = normalize (c.sexp);
+
+ return gcry_error (err);
+#undef MAKE_SPACE
+#undef STORE_LEN
+}
+
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, arg_list);
+ rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
+ arg_list, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr)
+{
+ return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+}
+
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
+}
+
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
+}
+
+\f
+/* Figure out a suitable encoding for BUFFER of LENGTH.
+ Returns: 0 = Binary
+ 1 = String possible
+ 2 = Token possible
+*/
+static int
+suitable_encoding (const unsigned char *buffer, size_t length)
+{
+ const unsigned char *s;
+ int maybe_token = 1;
+
+ if (!length)
+ return 1;
+
+ for (s=buffer; length; s++, length--)
+ {
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
+ && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
+ return 0; /*binary*/
+ if ( maybe_token
+ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
+ maybe_token = 0;
+ }
+ s = buffer;
+ if ( maybe_token && !digitp (s) )
+ return 2;
+ return 1;
+}
+
+
+static int
+convert_to_hex (const unsigned char *src, size_t len, char *dest)
+{
+ int i;
+
+ if (dest)
+ {
+ *dest++ = '#';
+ for (i=0; i < len; i++, dest += 2 )
+ sprintf (dest, "%02X", src[i]);
+ *dest++ = '#';
+ }
+ return len*2+2;
+}
+
+static int
+convert_to_string (const unsigned char *s, size_t len, char *dest)
+{
+ if (dest)
+ {
+ char *p = dest;
+ *p++ = '\"';
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b': *p++ = '\\'; *p++ = 'b'; break;
+ case '\t': *p++ = '\\'; *p++ = 't'; break;
+ case '\v': *p++ = '\\'; *p++ = 'v'; break;
+ case '\n': *p++ = '\\'; *p++ = 'n'; break;
+ case '\f': *p++ = '\\'; *p++ = 'f'; break;
+ case '\r': *p++ = '\\'; *p++ = 'r'; break;
+ case '\"': *p++ = '\\'; *p++ = '\"'; break;
+ case '\'': *p++ = '\\'; *p++ = '\''; break;
+ case '\\': *p++ = '\\'; *p++ = '\\'; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ {
+ sprintf (p, "\\x%02x", *s);
+ p += 4;
+ }
+ else
+ *p++ = *s;
+ }
+ }
+ *p++ = '\"';
+ return p - dest;
+ }
+ else
+ {
+ int count = 2;
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b':
+ case '\t':
+ case '\v':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\"':
+ case '\'':
+ case '\\': count += 2; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ count += 4;
+ else
+ count++;
+ }
+ }
+ return count;
+ }
+}
+
+
+
+static int
+convert_to_token (const unsigned char *src, size_t len, char *dest)
+{
+ if (dest)
+ memcpy (dest, src, len);
+ return len;
+}
+
+
+/****************
+ * Print SEXP to buffer using the MODE. Returns the length of the
+ * SEXP in buffer or 0 if the buffer is too short (We have at least an
+ * empty list consisting of 2 bytes). If a buffer of NULL is provided,
+ * the required length is returned.
+ */
+size_t
+gcry_sexp_sprint (const gcry_sexp_t list, int mode,
+ void *buffer, size_t maxlength )
+{
+ static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
+ const unsigned char *s;
+ char *d;
+ DATALEN n;
+ char numbuf[20];
+ size_t len = 0;
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ len++;
+ len += indent;
+ }
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ *d++ = '(';
+ }
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = ')';
+ }
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
+ {
+ len++;
+ len += indent;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy ( &n, s, sizeof n ); s += sizeof n;
+ if (mode == GCRYSEXP_FMT_ADVANCED)
+ {
+ int type;
+ size_t nn;
+
+ switch ( (type=suitable_encoding (s, n)))
+ {
+ case 1: nn = convert_to_string (s, n, NULL); break;
+ case 2: nn = convert_to_token (s, n, NULL); break;
+ default: nn = convert_to_hex (s, n, NULL); break;
+ }
+ len += nn;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ switch (type)
+ {
+ case 1: convert_to_string (s, n, d); break;
+ case 2: convert_to_token (s, n, d); break;
+ default: convert_to_hex (s, n, d); break;
+ }
+ d += nn;
+ }
+ if (s[n] != ST_CLOSE)
+ {
+ len++;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = ' ';
+ }
+ }
+ }
+ else
+ {
+ sprintf (numbuf, "%u:", (unsigned int)n );
+ len += strlen (numbuf) + n;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ d = stpcpy ( d, numbuf );
+ memcpy ( d, s, n ); d += n;
+ }
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ len++;
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = '\n';
+ }
+ }
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = 0; /* for convenience we make a C string */
+ }
+ else
+ len++; /* we need one byte more for this */
+
+ return len;
+}
+
+
+/* Scan a canonical encoded buffer with implicit length values and
+ return the actual length this S-expression uses. For a valid S-Exp
+ it should never return 0. If LENGTH is not zero, the maximum
+ length to scan is given - this can be used for syntax checks of
+ data passed from outside. errorcode and erroff may both be passed as
+ NULL. */
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ const unsigned char *p;
+ const unsigned char *disphint = NULL;
+ unsigned int datalen = 0;
+ size_t dummy_erroff;
+ gcry_error_t dummy_errcode;
+ size_t count = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+ if (!errcode)
+ errcode = &dummy_errcode;
+
+ *errcode = gcry_error (GPG_ERR_NO_ERROR);
+ *erroff = 0;
+ if (!buffer)
+ return 0;
+ if (*buffer != '(')
+ {
+ *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
+ return 0;
+ }
+
+ for (p=buffer; ; p++, count++ )
+ {
+ if (length && count >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+
+ if (datalen)
+ {
+ if (*p == ':')
+ {
+ if (length && (count+datalen) >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+ count += datalen;
+ p += datalen;
+ datalen = 0;
+ }
+ else if (digitp(p))
+ datalen = datalen*10 + atoi_1(p);
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
+ return 0;
+ }
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ level++;
+ }
+ else if (*p == ')')
+ { /* walk up */
+ if (!level)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
+ return 0;
+ }
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ if (!--level)
+ return ++count; /* ready */
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
+ return 0;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if ( !disphint )
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p) )
+ {
+ if (*p == '0')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
+ return 0;
+ }
+ datalen = atoi_1 (p);
+ }
+ else if (*p == '&' || *p == '\\')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
+ return 0;
+ }
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
+ return 0;
+ }
+ }
+}
--- /dev/null
+/* stdmem.c - private memory allocator
+ * Copyright (C) 1998, 2000, 2002, 2005, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Description of the layered memory management in Libgcrypt:
+ *
+ * [User]
+ * |
+ * |
+ * \ /
+ * global.c: [MM entrance points] -----> [user callbacks]
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [non-secure handlers] [secure handlers]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * stdmem.c: [ memory guard ]
+ *
+ * | |
+ * | |
+ * \ / \ /
+ *
+ * libc: [ MM functions ] secmem.c: [ secure MM functions]
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "stdmem.h"
+#include "secmem.h"
+
+\f
+
+#define MAGIC_NOR_BYTE 0x55
+#define MAGIC_SEC_BYTE 0xcc
+#define MAGIC_END_BYTE 0xaa
+
+#if SIZEOF_UNSIGNED_LONG == 8
+#define EXTRA_ALIGN 4
+#else
+#define EXTRA_ALIGN 0
+#endif
+
+
+static int use_m_guard = 0;
+
+/****************
+ * Warning: Never use this function after any of the functions
+ * here have been used.
+ */
+void
+_gcry_private_enable_m_guard (void)
+{
+ use_m_guard = 1;
+}
+
+
+/*
+ * Allocate memory of size n.
+ * Return NULL if we are out of memory.
+ */
+void *
+_gcry_private_malloc (size_t n)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - we better return
+ an error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if ( !(p = malloc (n + EXTRA_ALIGN+5)) )
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return malloc( n );
+ }
+}
+
+
+/*
+ * Allocate memory of size N from the secure memory pool. Return NULL
+ * if we are out of memory.
+ */
+void *
+_gcry_private_malloc_secure (size_t n)
+{
+ if (!n)
+ {
+ gpg_err_set_errno (EINVAL);
+ return NULL; /* Allocating 0 bytes is undefined - better return an
+ error to detect such coding errors. */
+ }
+
+ if (use_m_guard)
+ {
+ char *p;
+
+ if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) )
+ return NULL;
+ ((byte*)p)[EXTRA_ALIGN+0] = n;
+ ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
+ ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
+ ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
+ p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
+ return p+EXTRA_ALIGN+4;
+ }
+ else
+ {
+ return _gcry_secmem_malloc( n );
+ }
+}
+
+
+/*
+ * Realloc and clear the old space
+ * Return NULL if there is not enough memory.
+ */
+void *
+_gcry_private_realloc ( void *a, size_t n )
+{
+ if (use_m_guard)
+ {
+ unsigned char *p = a;
+ char *b;
+ size_t len;
+
+ if (!a)
+ return _gcry_private_malloc(n);
+
+ _gcry_private_check_heap(p);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if( len >= n ) /* We don't shrink for now. */
+ return a;
+ if (p[-1] == MAGIC_SEC_BYTE)
+ b = _gcry_private_malloc_secure(n);
+ else
+ b = _gcry_private_malloc(n);
+ if (!b)
+ return NULL;
+ memcpy (b, a, len);
+ memset (b+len, 0, n-len);
+ _gcry_private_free (p);
+ return b;
+ }
+ else if ( _gcry_private_is_secure(a) )
+ {
+ return _gcry_secmem_realloc( a, n );
+ }
+ else
+ {
+ return realloc( a, n );
+ }
+}
+
+
+void
+_gcry_private_check_heap (const void *a)
+{
+ if (use_m_guard)
+ {
+ const byte *p = a;
+ size_t len;
+
+ if (!p)
+ return;
+
+ if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
+ _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
+ len = p[-4];
+ len |= p[-3] << 8;
+ len |= p[-2] << 16;
+ if ( p[len] != MAGIC_END_BYTE )
+ _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
+ }
+}
+
+
+/*
+ * Free a memory block allocated by this or the secmem module
+ */
+void
+_gcry_private_free (void *a)
+{
+ unsigned char *p = a;
+
+ if (!p)
+ return;
+ if (use_m_guard )
+ {
+ _gcry_private_check_heap(p);
+ if ( _gcry_private_is_secure(a) )
+ _gcry_secmem_free(p-EXTRA_ALIGN-4);
+ else
+ {
+ free(p-EXTRA_ALIGN-4);
+ }
+ }
+ else if ( _gcry_private_is_secure(a) )
+ _gcry_secmem_free(p);
+ else
+ free(p);
+}
--- /dev/null
+/* stdmem.h - internal definitions for stdmem
+ * Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef G10_STDMEM_H
+#define G10_STDMEM_H 1
+
+void _gcry_private_enable_m_guard(void);
+
+void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_private_realloc (void *a, size_t n);
+void _gcry_private_check_heap (const void *a);
+void _gcry_private_free (void *a);
+
+#endif /* G10_STDMEM_H */
--- /dev/null
+/* types.h - some common typedefs
+ * Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GCRYPT_TYPES_H
+#define GCRYPT_TYPES_H
+
+
+/* The AC_CHECK_SIZEOF() in configure fails for some machines.
+ * we provide some fallback values here */
+#if !SIZEOF_UNSIGNED_SHORT
+#undef SIZEOF_UNSIGNED_SHORT
+#define SIZEOF_UNSIGNED_SHORT 2
+#endif
+#if !SIZEOF_UNSIGNED_INT
+#undef SIZEOF_UNSIGNED_INT
+#define SIZEOF_UNSIGNED_INT 4
+#endif
+#if !SIZEOF_UNSIGNED_LONG
+#undef SIZEOF_UNSIGNED_LONG
+#define SIZEOF_UNSIGNED_LONG 4
+#endif
+
+
+#include <sys/types.h>
+
+
+#ifndef HAVE_BYTE_TYPEDEF
+#undef byte /* maybe there is a macro with this name */
+/* Windows typedefs byte in the rpc headers. Avoid warning about
+ double definition. */
+#if !(defined(_WIN32) && defined(cbNDRContext))
+ typedef unsigned char byte;
+#endif
+#define HAVE_BYTE_TYPEDEF
+#endif
+
+#ifndef HAVE_USHORT_TYPEDEF
+#undef ushort /* maybe there is a macro with this name */
+ typedef unsigned short ushort;
+#define HAVE_USHORT_TYPEDEF
+#endif
+
+#ifndef HAVE_ULONG_TYPEDEF
+#undef ulong /* maybe there is a macro with this name */
+ typedef unsigned long ulong;
+#define HAVE_ULONG_TYPEDEF
+#endif
+
+#ifndef HAVE_U16_TYPEDEF
+#undef u16 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 2
+ typedef unsigned int u16;
+#elif SIZEOF_UNSIGNED_SHORT == 2
+ typedef unsigned short u16;
+#else
+#error no typedef for u16
+#endif
+#define HAVE_U16_TYPEDEF
+#endif
+
+#ifndef HAVE_U32_TYPEDEF
+#undef u32 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 4
+ typedef unsigned int u32;
+#elif SIZEOF_UNSIGNED_LONG == 4
+ typedef unsigned long u32;
+#else
+#error no typedef for u32
+#endif
+#define HAVE_U32_TYPEDEF
+#endif
+
+/****************
+ * Warning: Some systems segfault when this u64 typedef and
+ * the dummy code in cipher/md.c is not available. Examples are
+ * Solaris and IRIX.
+ */
+#ifndef HAVE_U64_TYPEDEF
+#undef u64 /* maybe there is a macro with this name */
+#if SIZEOF_UNSIGNED_INT == 8
+ typedef unsigned int u64;
+#define U64_C(c) (c ## U)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG == 8
+ typedef unsigned long u64;
+#define U64_C(c) (c ## UL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UNSIGNED_LONG_LONG == 8
+ typedef unsigned long long u64;
+#define U64_C(c) (c ## ULL)
+#define HAVE_U64_TYPEDEF
+#elif SIZEOF_UINT64_T == 8
+ typedef uint64_t u64;
+#define U64_C(c) (UINT64_C(c))
+#define HAVE_U64_TYPEDEF
+#endif
+#endif
+
+typedef union {
+ int a;
+ short b;
+ char c[1];
+ long d;
+#ifdef HAVE_U64_TYPEDEF
+ u64 e;
+#endif
+ float f;
+ double g;
+} PROPERLY_ALIGNED_TYPE;
+
+#endif /*GCRYPT_TYPES_H*/
--- /dev/null
+/* versioninfo.rc.in - for libgcrypt
+ * Copyright (C) 2005, 2006 g10 Code GmbH
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* This file is processed by configure to create versioninfo.rc */
+
+#line __LINE__ "versioninfo.rc.in"
+
+#include <afxres.h>
+
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
+ PRODUCTVERSION @BUILD_FILEVERSION@
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x21L
+#else
+ FILEFLAGS 0x20L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0"
+ VALUE "CompanyName", "g10 Code GmbH\0"
+ VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
+ VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
+ VALUE "InternalName", "libgcrypt\0"
+ VALUE "LegalCopyright", "Copyright © 2011 Free Software Foundation, Inc.\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "libgcrypt.dll\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "libgcrypt\0"
+ VALUE "ProductVersion", "@VERSION@\0"
+ VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0"
+ END
+ END
+END
--- /dev/null
+/* visibility.c - Wrapper for all public functions.
+ * Copyright (C) 2007, 2008, 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <stdarg.h>
+
+#define _GCRY_INCLUDED_BY_VISIBILITY_C
+#include "g10lib.h"
+#include "cipher-proto.h"
+
+
+
+const char *
+gcry_strerror (gcry_error_t err)
+{
+ return _gcry_strerror (err);
+}
+
+const char *
+gcry_strsource (gcry_error_t err)
+{
+ return _gcry_strsource (err);
+}
+
+gcry_err_code_t
+gcry_err_code_from_errno (int err)
+{
+ return _gcry_err_code_from_errno (err);
+}
+
+int
+gcry_err_code_to_errno (gcry_err_code_t code)
+{
+ return _gcry_err_code_to_errno (code);
+}
+
+gcry_error_t
+gcry_err_make_from_errno (gcry_err_source_t source, int err)
+{
+ return _gcry_err_make_from_errno (source, err);
+}
+
+gcry_err_code_t
+gcry_error_from_errno (int err)
+{
+ return _gcry_error_from_errno (err);
+}
+
+const char *
+gcry_check_version (const char *req_version)
+{
+ return _gcry_check_version (req_version);
+}
+
+gcry_error_t
+gcry_control (enum gcry_ctl_cmds cmd, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, cmd);
+ err = _gcry_vcontrol (cmd, arg_ptr);
+ va_end(arg_ptr);
+ return err;
+}
+
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp,
+ const void *buffer, size_t length,
+ int autodetect)
+{
+ return _gcry_sexp_new (retsexp, buffer, length, autodetect);
+}
+
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp,
+ void *buffer, size_t length,
+ int autodetect, void (*freefnc) (void *))
+{
+ return _gcry_sexp_create (retsexp, buffer, length,
+ autodetect, freefnc);
+}
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return _gcry_sexp_sscan (retsexp, erroff, buffer, length);
+}
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, ...)
+{
+ gcry_error_t err;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr);
+ va_end (arg_ptr);
+ return err;
+}
+
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return _gcry_sexp_build_array (retsexp, erroff, format, arg_list);
+}
+
+void
+gcry_sexp_release (gcry_sexp_t sexp)
+{
+ _gcry_sexp_release (sexp);
+}
+
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ return _gcry_sexp_canon_len (buffer, length, erroff, errcode);
+}
+
+size_t
+gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength)
+{
+ return _gcry_sexp_sprint (sexp, mode, buffer, maxlength);
+}
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ _gcry_sexp_dump (a);
+}
+
+gcry_sexp_t
+gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b)
+{
+ return _gcry_sexp_cons (a, b);
+}
+
+gcry_sexp_t
+gcry_sexp_alist (const gcry_sexp_t *array)
+{
+ return _gcry_sexp_alist (array);
+}
+
+gcry_sexp_t
+gcry_sexp_vlist (const gcry_sexp_t a, ...)
+{
+ /* This is not yet implemented in sexp.c. */
+ (void)a;
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_append (a, n);
+}
+
+gcry_sexp_t
+gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n)
+{
+ return _gcry_sexp_prepend (a, n);
+}
+
+
+gcry_sexp_t
+gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen)
+{
+ return _gcry_sexp_find_token (list, tok, toklen);
+}
+
+int
+gcry_sexp_length (const gcry_sexp_t list)
+{
+ return _gcry_sexp_length (list);
+}
+
+gcry_sexp_t
+gcry_sexp_nth (const gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth (list, number);
+}
+
+gcry_sexp_t
+gcry_sexp_car (const gcry_sexp_t list)
+{
+ return _gcry_sexp_car (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cdr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cdr (list);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr (const gcry_sexp_t list)
+{
+ return _gcry_sexp_cadr (list);
+}
+
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ return _gcry_sexp_nth_data (list, number, datalen);
+}
+
+char *
+gcry_sexp_nth_string (gcry_sexp_t list, int number)
+{
+ return _gcry_sexp_nth_string (list, number);
+}
+
+gcry_mpi_t
+gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
+{
+ return _gcry_sexp_nth_mpi (list, number, mpifmt);
+}
+
+gcry_mpi_t
+gcry_mpi_new (unsigned int nbits)
+{
+ return _gcry_mpi_new (nbits);
+}
+
+gcry_mpi_t
+gcry_mpi_snew (unsigned int nbits)
+{
+ return _gcry_mpi_snew (nbits);
+}
+
+void
+gcry_mpi_release (gcry_mpi_t a)
+{
+ _gcry_mpi_release (a);
+}
+
+gcry_mpi_t
+gcry_mpi_copy (const gcry_mpi_t a)
+{
+ return _gcry_mpi_copy (a);
+}
+
+gcry_mpi_t
+gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u)
+{
+ return _gcry_mpi_set (w, u);
+}
+
+gcry_mpi_t
+gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
+{
+ return _gcry_mpi_set_ui (w, u);
+}
+
+void
+gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
+{
+ _gcry_mpi_swap (a, b);
+}
+
+int
+gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v)
+{
+ return _gcry_mpi_cmp (u, v);
+}
+
+int
+gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v)
+{
+ return _gcry_mpi_cmp_ui (u, v);
+}
+
+gcry_error_t
+gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+ const void *buffer, size_t buflen,
+ size_t *nscanned)
+{
+ return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned);
+}
+
+gcry_error_t
+gcry_mpi_print (enum gcry_mpi_format format,
+ unsigned char *buffer, size_t buflen,
+ size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return _gcry_mpi_print (format, buffer, buflen, nwritten, a);
+}
+
+gcry_error_t
+gcry_mpi_aprint (enum gcry_mpi_format format,
+ unsigned char **buffer, size_t *nwritten,
+ const gcry_mpi_t a)
+{
+ return _gcry_mpi_aprint (format, buffer, nwritten, a);
+}
+
+void
+gcry_mpi_dump (const gcry_mpi_t a)
+{
+ _gcry_mpi_dump (a);
+}
+
+void
+gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_add (w, u, v);
+}
+
+void
+gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v)
+{
+ _gcry_mpi_add_ui (w, u, v);
+}
+
+void
+gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_addm (w, u, v, m);
+}
+
+void
+gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_sub (w, u, v);
+}
+
+void
+gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_sub_ui (w, u, v);
+}
+
+void
+gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_subm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+{
+ _gcry_mpi_mul (w, u, v);
+}
+
+void
+gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+{
+ _gcry_mpi_mul_ui (w, u, v);
+}
+
+void
+gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+{
+ _gcry_mpi_mulm (w, u, v, m);
+}
+
+void
+gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+{
+ _gcry_mpi_mul_2exp (w, u, cnt);
+}
+
+void
+gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+ gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+{
+ _gcry_mpi_div (q, r, dividend, divisor, round);
+}
+
+void
+gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor)
+{
+ _gcry_mpi_mod (r, dividend, divisor);
+}
+
+void
+gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
+ const gcry_mpi_t m)
+{
+ _gcry_mpi_powm (w, b, e, m);
+}
+
+int
+gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b)
+{
+ return _gcry_mpi_gcd (g, a, b);
+}
+
+int
+gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m)
+{
+ return _gcry_mpi_invm (x, a, m);
+}
+
+
+unsigned int
+gcry_mpi_get_nbits (gcry_mpi_t a)
+{
+ return _gcry_mpi_get_nbits (a);
+}
+
+int
+gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n)
+{
+ return _gcry_mpi_test_bit (a, n);
+}
+
+void
+gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_bit (a, n);
+}
+
+void
+gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_bit (a, n);
+}
+
+void
+gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_set_highbit (a, n);
+}
+
+void
+gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_clear_highbit (a, n);
+}
+
+void
+gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_rshift (x, a, n);
+}
+
+void
+gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n)
+{
+ _gcry_mpi_lshift (x, a, n);
+}
+
+gcry_mpi_t
+gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
+{
+ return _gcry_mpi_set_opaque (a, p, nbits);
+}
+
+void *
+gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
+{
+ return _gcry_mpi_get_opaque (a, nbits);
+}
+
+void
+gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_set_flag (a, flag);
+}
+
+void
+gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ _gcry_mpi_clear_flag (a, flag);
+}
+
+int
+gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
+{
+ return _gcry_mpi_get_flag (a, flag);
+}
+
+gcry_error_t
+gcry_cipher_open (gcry_cipher_hd_t *handle,
+ int algo, int mode, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *handle = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_cipher_open (handle, algo, mode, flags);
+}
+
+void
+gcry_cipher_close (gcry_cipher_hd_t h)
+{
+ _gcry_cipher_close (h);
+}
+
+gcry_error_t
+gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setkey (hd, key, keylen);
+}
+
+gcry_error_t
+gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setiv (hd, iv, ivlen);
+}
+
+gpg_error_t
+gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_setctr (hd, ctr, ctrlen);
+}
+
+
+gcry_error_t
+gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_ctl (h, cmd, buffer, buflen);
+}
+
+gcry_error_t
+gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ return _gcry_cipher_info (h, what, buffer, nbytes);
+}
+
+gcry_error_t
+gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_cipher_algo_name (int algorithm)
+{
+ return _gcry_cipher_algo_name (algorithm);
+}
+
+int
+gcry_cipher_map_name (const char *name)
+{
+ return _gcry_cipher_map_name (name);
+}
+
+int
+gcry_cipher_mode_from_oid (const char *string)
+{
+ return _gcry_cipher_mode_from_oid (string);
+}
+
+gcry_error_t
+gcry_cipher_encrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ {
+ /* Make sure that the plaintext will never make it to OUT. */
+ if (out)
+ memset (out, 0x42, outsize);
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_cipher_encrypt (h, out, outsize, in, inlen);
+}
+
+gcry_error_t
+gcry_cipher_decrypt (gcry_cipher_hd_t h,
+ void *out, size_t outsize,
+ const void *in, size_t inlen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_cipher_decrypt (h, out, outsize, in, inlen);
+}
+
+size_t
+gcry_cipher_get_algo_keylen (int algo)
+{
+ return _gcry_cipher_get_algo_keylen (algo);
+}
+
+size_t
+gcry_cipher_get_algo_blklen (int algo)
+{
+ return _gcry_cipher_get_algo_blklen (algo);
+}
+
+gcry_error_t
+gcry_cipher_list (int *list, int *list_length)
+{
+ return _gcry_cipher_list (list, list_length);
+}
+
+gcry_error_t
+gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_encrypt (result, data, pkey);
+}
+
+gcry_error_t
+gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_decrypt (result, data, skey);
+}
+
+gcry_error_t
+gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
+{
+ if (!fips_is_operational ())
+ {
+ *result = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_sign (result, data, skey);
+}
+
+gcry_error_t
+gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_pk_verify (sigval, data, pkey);
+}
+
+gcry_error_t
+gcry_pk_testkey (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_pk_testkey (key);
+}
+
+gcry_error_t
+gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+{
+ if (!fips_is_operational ())
+ {
+ *r_key = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_pk_genkey (r_key, s_parms);
+}
+
+gcry_error_t
+gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+{
+ return _gcry_pk_ctl (cmd, buffer, buflen);
+}
+
+gcry_error_t
+gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_pk_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_pk_algo_name (int algorithm)
+{
+ return _gcry_pk_algo_name (algorithm);
+}
+
+int
+gcry_pk_map_name (const char *name)
+{
+ return _gcry_pk_map_name (name);
+}
+
+unsigned int
+gcry_pk_get_nbits (gcry_sexp_t key)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_pk_get_nbits (key);
+}
+
+unsigned char *
+gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_keygrip (key, array);
+}
+
+const char *
+gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_curve (key, iterator, r_nbits);
+}
+
+gcry_sexp_t
+gcry_pk_get_param (int algo, const char *name)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return NULL;
+ }
+ return _gcry_pk_get_param (algo, name);
+}
+
+gcry_error_t
+gcry_pk_list (int *list, int *list_length)
+{
+ return _gcry_pk_list (list, list_length);
+}
+
+gcry_error_t
+gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+{
+ if (!fips_is_operational ())
+ {
+ *h = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+
+ return _gcry_md_open (h, algo, flags);
+}
+
+void
+gcry_md_close (gcry_md_hd_t hd)
+{
+ _gcry_md_close (hd);
+}
+
+gcry_error_t
+gcry_md_enable (gcry_md_hd_t hd, int algo)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_enable (hd, algo);
+}
+
+gcry_error_t
+gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd)
+{
+ if (!fips_is_operational ())
+ {
+ *bhd = NULL;
+ return gpg_error (fips_not_operational ());
+ }
+ return _gcry_md_copy (bhd, ahd);
+}
+
+void
+gcry_md_reset (gcry_md_hd_t hd)
+{
+ _gcry_md_reset (hd);
+}
+
+gcry_error_t
+gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_ctl (hd, cmd, buffer, buflen);
+}
+
+void
+gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return;
+ }
+ _gcry_md_write (hd, buffer, length);
+}
+
+unsigned char *
+gcry_md_read (gcry_md_hd_t hd, int algo)
+{
+ return _gcry_md_read (hd, algo);
+}
+
+void
+gcry_md_hash_buffer (int algo, void *digest,
+ const void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("called in non-operational state");
+ }
+ _gcry_md_hash_buffer (algo, digest, buffer, length);
+}
+
+int
+gcry_md_get_algo (gcry_md_hd_t hd)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_error ("used in non-operational state");
+ return 0;
+ }
+ return _gcry_md_get_algo (hd);
+}
+
+unsigned int
+gcry_md_get_algo_dlen (int algo)
+{
+ return _gcry_md_get_algo_dlen (algo);
+}
+
+int
+gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ return 0;
+ }
+
+ return _gcry_md_is_enabled (a, algo);
+}
+
+int
+gcry_md_is_secure (gcry_md_hd_t a)
+{
+ return _gcry_md_is_secure (a);
+}
+
+gcry_error_t
+gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+
+ return _gcry_md_info (h, what, buffer, nbytes);
+}
+
+gcry_error_t
+gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+ return _gcry_md_algo_info (algo, what, buffer, nbytes);
+}
+
+const char *
+gcry_md_algo_name (int algo)
+{
+ return _gcry_md_algo_name (algo);
+}
+
+int
+gcry_md_map_name (const char* name)
+{
+ return _gcry_md_map_name (name);
+}
+
+gcry_error_t
+gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_md_setkey (hd, key, keylen);
+}
+
+void
+gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+{
+ _gcry_md_debug (hd, suffix);
+}
+
+gcry_error_t
+gcry_md_list (int *list, int *list_length)
+{
+ return _gcry_md_list (list, list_length);
+}
+
+gcry_error_t
+gcry_ac_data_new (gcry_ac_data_t *data)
+{
+ return _gcry_ac_data_new (data);
+}
+
+void
+gcry_ac_data_destroy (gcry_ac_data_t data)
+{
+ _gcry_ac_data_destroy (data);
+}
+
+gcry_error_t
+gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
+{
+ return _gcry_ac_data_copy (data_cp, data);
+}
+
+unsigned int
+gcry_ac_data_length (gcry_ac_data_t data)
+{
+ return _gcry_ac_data_length (data);
+}
+
+void
+gcry_ac_data_clear (gcry_ac_data_t data)
+{
+ _gcry_ac_data_clear (data);
+}
+
+gcry_error_t
+gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+{
+ return _gcry_ac_data_set (data, flags, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+{
+ return _gcry_ac_data_get_name (data, flags, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx, const char **name, gcry_mpi_t *mpi)
+{
+ return _gcry_ac_data_get_index (data, flags, idx, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+{
+ return _gcry_ac_data_to_sexp (data, sexp, identifiers);
+}
+
+gcry_error_t
+gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers)
+{
+ return _gcry_ac_data_from_sexp (data, sexp, identifiers);
+}
+
+void
+gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, type);
+ _gcry_ac_io_init_va (ac_io, mode, type, arg_ptr);
+ va_end (arg_ptr);
+}
+
+void
+gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap)
+{
+ _gcry_ac_io_init_va (ac_io, mode, type, ap);
+}
+
+gcry_error_t
+gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+{
+ return _gcry_ac_open (handle, algorithm, flags);
+}
+
+void
+gcry_ac_close (gcry_ac_handle_t handle)
+{
+ _gcry_ac_close (handle);
+}
+
+gcry_error_t
+gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+{
+ return _gcry_ac_key_init (key, handle, type, data);
+}
+
+gcry_error_t
+gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **miscdata)
+{
+ return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata);
+}
+
+gcry_ac_key_t
+gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which)
+{
+ return _gcry_ac_key_pair_extract (keypair, which);
+}
+
+gcry_ac_data_t
+gcry_ac_key_data_get (gcry_ac_key_t key)
+{
+ return _gcry_ac_key_data_get (key);
+}
+
+gcry_error_t
+gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+{
+ return _gcry_ac_key_test (handle, key);
+}
+
+gcry_error_t
+gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+{
+ return _gcry_ac_key_get_nbits (handle, key, nbits);
+}
+
+gcry_error_t
+gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip)
+{
+ return _gcry_ac_key_get_grip (handle, key, key_grip);
+}
+
+void
+gcry_ac_key_destroy (gcry_ac_key_t key)
+{
+ _gcry_ac_key_destroy (key);
+}
+
+void
+gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+{
+ _gcry_ac_key_pair_destroy (key_pair);
+}
+
+gcry_error_t
+gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options,
+ gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
+{
+ return _gcry_ac_data_encode (method, flags, options, io_read, io_write);
+}
+
+gcry_error_t
+gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options,
+ gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
+{
+ return _gcry_ac_data_decode (method, flags, options, io_read, io_write);
+}
+
+gcry_error_t
+gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+{
+ return _gcry_ac_data_encrypt (handle, flags, key,
+ data_plain, data_encrypted);
+}
+
+gcry_error_t
+gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+{
+ return _gcry_ac_data_decrypt (handle, flags, key,
+ data_plain, data_encrypted);
+}
+
+gcry_error_t
+gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+{
+ return _gcry_ac_data_sign (handle, key, data, data_signature);
+}
+
+gcry_error_t
+gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+{
+ return _gcry_ac_data_verify (handle, key, data, data_signature);
+}
+
+gcry_error_t
+gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+{
+ return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key,
+ io_message, io_cipher);
+}
+
+gcry_error_t
+gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+{
+ return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key,
+ io_cipher, io_message);
+}
+
+gcry_error_t
+gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key,
+ io_message, io_signature);
+}
+
+gcry_error_t
+gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key,
+ io_message, io_signature);
+}
+
+gcry_error_t
+gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
+{
+ /* This function is deprecated. We implement it in terms of the
+ suggested replacement. */
+ const char *tmp = _gcry_pk_algo_name (algorithm);
+ if (!*tmp)
+ return gcry_error (GPG_ERR_PUBKEY_ALGO);
+ *name = tmp;
+ return 0;
+}
+
+gcry_error_t
+gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
+{
+ /* This function is deprecated. We implement it in terms of the
+ suggested replacement. */
+ int algo = _gcry_pk_map_name (name);
+ if (!algo)
+ return gcry_error (GPG_ERR_PUBKEY_ALGO);
+ *algorithm = algo;
+ return 0;
+}
+
+gpg_error_t
+gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+}
+
+void
+gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_randomize (buffer, length, level);
+}
+
+gcry_error_t
+gcry_random_add_bytes (const void *buffer, size_t length, int quality)
+{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ return _gcry_random_add_bytes (buffer, length, quality);
+}
+
+void *
+gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes (nbytes,level);
+}
+
+void *
+gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+
+ return _gcry_random_bytes_secure (nbytes, level);
+}
+
+void
+gcry_mpi_randomize (gcry_mpi_t w,
+ unsigned int nbits, enum gcry_random_level level)
+{
+ _gcry_mpi_randomize (w, nbits, level);
+}
+
+void
+gcry_create_nonce (void *buffer, size_t length)
+{
+ if (!fips_is_operational ())
+ {
+ (void)fips_not_operational ();
+ fips_signal_fatal_error ("called in non-operational state");
+ fips_noreturn ();
+ }
+ _gcry_create_nonce (buffer, length);
+}
+
+gcry_error_t
+gcry_prime_generate (gcry_mpi_t *prime,
+ unsigned int prime_bits,
+ unsigned int factor_bits,
+ gcry_mpi_t **factors,
+ gcry_prime_check_func_t cb_func,
+ void *cb_arg,
+ gcry_random_level_t random_level,
+ unsigned int flags)
+{
+ return _gcry_prime_generate (prime, prime_bits, factor_bits, factors,
+ cb_func, cb_arg, random_level, flags);
+}
+
+gcry_error_t
+gcry_prime_group_generator (gcry_mpi_t *r_g,
+ gcry_mpi_t prime, gcry_mpi_t *factors,
+ gcry_mpi_t start_g)
+{
+ return _gcry_prime_group_generator (r_g, prime, factors, start_g);
+}
+
+void
+gcry_prime_release_factors (gcry_mpi_t *factors)
+{
+ _gcry_prime_release_factors (factors);
+}
+
+gcry_error_t
+gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+{
+ return _gcry_prime_check (x, flags);
+}
+
+void
+gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data)
+{
+ _gcry_set_progress_handler (cb, cb_data);
+}
+
+void
+gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc,
+ gcry_handler_alloc_t func_alloc_secure,
+ gcry_handler_secure_check_t func_secure_check,
+ gcry_handler_realloc_t func_realloc,
+ gcry_handler_free_t func_free)
+{
+ _gcry_set_allocation_handler (func_alloc, func_alloc_secure,
+ func_secure_check, func_realloc, func_free);
+}
+
+void
+gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque)
+{
+ _gcry_set_outofcore_handler (h, opaque);
+}
+
+void
+gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque)
+{
+ _gcry_set_fatalerror_handler (fnc, opaque);
+}
+
+void
+gcry_set_log_handler (gcry_handler_log_t f, void *opaque)
+{
+ _gcry_set_log_handler (f, opaque);
+}
+
+void
+gcry_set_gettext_handler (const char *(*f)(const char*))
+{
+ _gcry_set_gettext_handler (f);
+}
+
+void *
+gcry_malloc (size_t n)
+{
+ return _gcry_malloc (n);
+}
+
+void *
+gcry_calloc (size_t n, size_t m)
+{
+ return _gcry_calloc (n, m);
+}
+
+void *
+gcry_malloc_secure (size_t n)
+{
+ return _gcry_malloc_secure (n);
+}
+
+void *
+gcry_calloc_secure (size_t n, size_t m)
+{
+ return _gcry_calloc_secure (n,m);
+}
+
+void *
+gcry_realloc (void *a, size_t n)
+{
+ return _gcry_realloc (a, n);
+}
+
+char *
+gcry_strdup (const char *string)
+{
+ return _gcry_strdup (string);
+}
+
+void *
+gcry_xmalloc (size_t n)
+{
+ return _gcry_xmalloc (n);
+}
+
+void *
+gcry_xcalloc (size_t n, size_t m)
+{
+ return _gcry_xcalloc (n, m);
+}
+
+void *
+gcry_xmalloc_secure (size_t n)
+{
+ return _gcry_xmalloc_secure (n);
+}
+
+void *
+gcry_xcalloc_secure (size_t n, size_t m)
+{
+ return _gcry_xcalloc_secure (n, m);
+}
+
+void *
+gcry_xrealloc (void *a, size_t n)
+{
+ return _gcry_xrealloc (a, n);
+}
+
+char *
+gcry_xstrdup (const char *a)
+{
+ return _gcry_xstrdup (a);
+}
+
+void
+gcry_free (void *a)
+{
+ _gcry_free (a);
+}
+
+int
+gcry_is_secure (const void *a)
+{
+ return _gcry_is_secure (a);
+}
+
+
+gcry_error_t
+gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_cipher_register (cipher, NULL, algorithm_id, module);
+}
+
+void
+gcry_cipher_unregister (gcry_module_t module)
+{
+ _gcry_cipher_unregister (module);
+}
+
+gcry_error_t
+gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_pk_register (pubkey, NULL, algorithm_id, module);
+}
+
+void
+gcry_pk_unregister (gcry_module_t module)
+{
+ _gcry_pk_unregister (module);
+}
+
+gcry_error_t
+gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_md_register (digest, NULL, algorithm_id, module);
+}
+
+void
+gcry_md_unregister (gcry_module_t module)
+{
+ _gcry_md_unregister (module);
+}
--- /dev/null
+/* visibility.h - Set visibility attribute
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GCRY_VISIBILITY_H
+#define GCRY_VISIBILITY_H
+
+/* Redefine all public symbols with an underscore unless we already
+ use the underscore prefixed version internally. */
+#define gcry_check_version _gcry_check_version
+#define gcry_control _gcry_control
+
+#define gcry_set_allocation_handler _gcry_set_allocation_handler
+#define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler
+#define gcry_set_gettext_handler _gcry_set_gettext_handler
+#define gcry_set_log_handler _gcry_set_log_handler
+#define gcry_set_outofcore_handler _gcry_set_outofcore_handler
+#define gcry_set_progress_handler _gcry_set_progress_handler
+#define gcry_err_code_from_errno _gcry_err_code_from_errno
+#define gcry_err_code_to_errno _gcry_err_code_to_errno
+#define gcry_err_make_from_errno _gcry_err_make_from_errno
+#define gcry_error_from_errno _gcry_error_from_errno
+#define gcry_strerror _gcry_strerror
+#define gcry_strsource _gcry_strsource
+
+#define gcry_free _gcry_free
+#define gcry_malloc _gcry_malloc
+#define gcry_malloc_secure _gcry_malloc_secure
+#define gcry_calloc _gcry_calloc
+#define gcry_calloc_secure _gcry_calloc_secure
+#define gcry_realloc _gcry_realloc
+#define gcry_strdup _gcry_strdup
+#define gcry_is_secure _gcry_is_secure
+#define gcry_xcalloc _gcry_xcalloc
+#define gcry_xcalloc_secure _gcry_xcalloc_secure
+#define gcry_xmalloc _gcry_xmalloc
+#define gcry_xmalloc_secure _gcry_xmalloc_secure
+#define gcry_xrealloc _gcry_xrealloc
+#define gcry_xstrdup _gcry_xstrdup
+
+#define gcry_md_algo_info _gcry_md_algo_info
+#define gcry_md_algo_name _gcry_md_algo_name
+#define gcry_md_close _gcry_md_close
+#define gcry_md_copy _gcry_md_copy
+#define gcry_md_ctl _gcry_md_ctl
+#define gcry_md_enable _gcry_md_enable
+#define gcry_md_get _gcry_md_get
+#define gcry_md_get_algo _gcry_md_get_algo
+#define gcry_md_get_algo_dlen _gcry_md_get_algo_dlen
+#define gcry_md_hash_buffer _gcry_md_hash_buffer
+#define gcry_md_info _gcry_md_info
+#define gcry_md_is_enabled _gcry_md_is_enabled
+#define gcry_md_is_secure _gcry_md_is_secure
+#define gcry_md_list _gcry_md_list
+#define gcry_md_map_name _gcry_md_map_name
+#define gcry_md_open _gcry_md_open
+#define gcry_md_read _gcry_md_read
+/* gcry_md_register and _gcry_md_register differ. */
+#define gcry_md_unregister _gcry_md_unregister
+#define gcry_md_reset _gcry_md_reset
+#define gcry_md_setkey _gcry_md_setkey
+#define gcry_md_write _gcry_md_write
+#define gcry_md_debug _gcry_md_debug
+
+#define gcry_cipher_algo_info _gcry_cipher_algo_info
+#define gcry_cipher_algo_name _gcry_cipher_algo_name
+#define gcry_cipher_close _gcry_cipher_close
+#define gcry_cipher_setkey _gcry_cipher_setkey
+#define gcry_cipher_setiv _gcry_cipher_setiv
+#define gcry_cipher_setctr _gcry_cipher_setctr
+#define gcry_cipher_ctl _gcry_cipher_ctl
+#define gcry_cipher_decrypt _gcry_cipher_decrypt
+#define gcry_cipher_encrypt _gcry_cipher_encrypt
+#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen
+#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen
+#define gcry_cipher_info _gcry_cipher_info
+#define gcry_cipher_list _gcry_cipher_list
+#define gcry_cipher_map_name _gcry_cipher_map_name
+#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid
+#define gcry_cipher_open _gcry_cipher_open
+/* gcry_cipher_register and _gcry_cipher_register differ. */
+#define gcry_cipher_unregister _gcry_cipher_unregister
+
+#define gcry_pk_algo_info _gcry_pk_algo_info
+#define gcry_pk_algo_name _gcry_pk_algo_name
+#define gcry_pk_ctl _gcry_pk_ctl
+#define gcry_pk_decrypt _gcry_pk_decrypt
+#define gcry_pk_encrypt _gcry_pk_encrypt
+#define gcry_pk_genkey _gcry_pk_genkey
+#define gcry_pk_get_keygrip _gcry_pk_get_keygrip
+#define gcry_pk_get_curve _gcry_pk_get_curve
+#define gcry_pk_get_param _gcry_pk_get_param
+#define gcry_pk_get_nbits _gcry_pk_get_nbits
+#define gcry_pk_list _gcry_pk_list
+#define gcry_pk_map_name _gcry_pk_map_name
+/* gcry_pk_register and _gcry_pk_register differ. */
+#define gcry_pk_unregister _gcry_pk_unregister
+#define gcry_pk_sign _gcry_pk_sign
+#define gcry_pk_testkey _gcry_pk_testkey
+#define gcry_pk_verify _gcry_pk_verify
+
+#define gcry_ac_data_new _gcry_ac_data_new
+#define gcry_ac_data_destroy _gcry_ac_data_destroy
+#define gcry_ac_data_copy _gcry_ac_data_copy
+#define gcry_ac_data_length _gcry_ac_data_length
+#define gcry_ac_data_clear _gcry_ac_data_clear
+#define gcry_ac_data_set _gcry_ac_data_set
+#define gcry_ac_data_get_name _gcry_ac_data_get_name
+#define gcry_ac_data_get_index _gcry_ac_data_get_index
+#define gcry_ac_open _gcry_ac_open
+#define gcry_ac_close _gcry_ac_close
+#define gcry_ac_key_init _gcry_ac_key_init
+#define gcry_ac_key_pair_generate _gcry_ac_key_pair_generate
+#define gcry_ac_key_pair_extract _gcry_ac_key_pair_extract
+#define gcry_ac_key_data_get _gcry_ac_key_data_get
+#define gcry_ac_key_test _gcry_ac_key_test
+#define gcry_ac_key_get_nbits _gcry_ac_key_get_nbits
+#define gcry_ac_key_get_grip _gcry_ac_key_get_grip
+#define gcry_ac_key_destroy _gcry_ac_key_destroy
+#define gcry_ac_key_pair_destroy _gcry_ac_key_pair_destroy
+#define gcry_ac_data_encrypt _gcry_ac_data_encrypt
+#define gcry_ac_data_decrypt _gcry_ac_data_decrypt
+#define gcry_ac_data_sign _gcry_ac_data_sign
+#define gcry_ac_data_verify _gcry_ac_data_verify
+#define gcry_ac_id_to_name _gcry_ac_id_to_name
+#define gcry_ac_name_to_id _gcry_ac_name_to_id
+#define gcry_ac_data_encode _gcry_ac_data_encode
+#define gcry_ac_data_decode _gcry_ac_data_decode
+#define gcry_ac_mpi_to_os _gcry_ac_mpi_to_os
+#define gcry_ac_mpi_to_os_alloc _gcry_ac_mpi_to_os_alloc
+#define gcry_ac_os_to_mpi _gcry_ac_os_to_mpi
+#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme
+#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme
+#define gcry_ac_data_sign_scheme _gcry_ac_data_sign_scheme
+#define gcry_ac_data_verify_scheme _gcry_ac_data_verify_scheme
+#define gcry_ac_data_to_sexp _gcry_ac_data_to_sexp
+#define gcry_ac_data_from_sexp _gcry_ac_data_from_sexp
+#define gcry_ac_io_init _gcry_ac_io_init
+#define gcry_ac_io_init_va _gcry_ac_io_init_va
+
+#define gcry_kdf_derive _gcry_kdf_derive
+
+#define gcry_prime_check _gcry_prime_check
+#define gcry_prime_generate _gcry_prime_generate
+#define gcry_prime_group_generator _gcry_prime_group_generator
+#define gcry_prime_release_factors _gcry_prime_release_factors
+
+#define gcry_random_add_bytes _gcry_random_add_bytes
+#define gcry_random_bytes _gcry_random_bytes
+#define gcry_random_bytes_secure _gcry_random_bytes_secure
+#define gcry_randomize _gcry_randomize
+#define gcry_create_nonce _gcry_create_nonce
+
+#define gcry_sexp_alist _gcry_sexp_alist
+#define gcry_sexp_append _gcry_sexp_append
+#define gcry_sexp_build _gcry_sexp_build
+#define gcry_sexp_build_array _gcry_sexp_build_array
+#define gcry_sexp_cadr _gcry_sexp_cadr
+#define gcry_sexp_canon_len _gcry_sexp_canon_len
+#define gcry_sexp_car _gcry_sexp_car
+#define gcry_sexp_cdr _gcry_sexp_cdr
+#define gcry_sexp_cons _gcry_sexp_cons
+#define gcry_sexp_create _gcry_sexp_create
+#define gcry_sexp_dump _gcry_sexp_dump
+#define gcry_sexp_find_token _gcry_sexp_find_token
+#define gcry_sexp_length _gcry_sexp_length
+#define gcry_sexp_new _gcry_sexp_new
+#define gcry_sexp_nth _gcry_sexp_nth
+#define gcry_sexp_nth_data _gcry_sexp_nth_data
+#define gcry_sexp_nth_mpi _gcry_sexp_nth_mpi
+#define gcry_sexp_prepend _gcry_sexp_prepend
+#define gcry_sexp_release _gcry_sexp_release
+#define gcry_sexp_sprint _gcry_sexp_sprint
+#define gcry_sexp_sscan _gcry_sexp_sscan
+#define gcry_sexp_vlist _gcry_sexp_vlist
+#define gcry_sexp_nth_string _gcry_sexp_nth_string
+
+#define gcry_mpi_add _gcry_mpi_add
+#define gcry_mpi_add_ui _gcry_mpi_add_ui
+#define gcry_mpi_addm _gcry_mpi_addm
+#define gcry_mpi_aprint _gcry_mpi_aprint
+#define gcry_mpi_clear_bit _gcry_mpi_clear_bit
+#define gcry_mpi_clear_flag _gcry_mpi_clear_flag
+#define gcry_mpi_clear_highbit _gcry_mpi_clear_highbit
+#define gcry_mpi_cmp _gcry_mpi_cmp
+#define gcry_mpi_cmp_ui _gcry_mpi_cmp_ui
+#define gcry_mpi_copy _gcry_mpi_copy
+#define gcry_mpi_div _gcry_mpi_div
+#define gcry_mpi_dump _gcry_mpi_dump
+#define gcry_mpi_gcd _gcry_mpi_gcd
+#define gcry_mpi_get_flag _gcry_mpi_get_flag
+#define gcry_mpi_get_nbits _gcry_mpi_get_nbits
+#define gcry_mpi_get_opaque _gcry_mpi_get_opaque
+#define gcry_mpi_invm _gcry_mpi_invm
+#define gcry_mpi_mod _gcry_mpi_mod
+#define gcry_mpi_mul _gcry_mpi_mul
+#define gcry_mpi_mul_2exp _gcry_mpi_mul_2exp
+#define gcry_mpi_mul_ui _gcry_mpi_mul_ui
+#define gcry_mpi_mulm _gcry_mpi_mulm
+#define gcry_mpi_new _gcry_mpi_new
+#define gcry_mpi_powm _gcry_mpi_powm
+#define gcry_mpi_print _gcry_mpi_print
+#define gcry_mpi_randomize _gcry_mpi_randomize
+#define gcry_mpi_release _gcry_mpi_release
+#define gcry_mpi_rshift _gcry_mpi_rshift
+#define gcry_mpi_lshift _gcry_mpi_lshift
+#define gcry_mpi_scan _gcry_mpi_scan
+#define gcry_mpi_set _gcry_mpi_set
+#define gcry_mpi_set_bit _gcry_mpi_set_bit
+#define gcry_mpi_set_flag _gcry_mpi_set_flag
+#define gcry_mpi_set_highbit _gcry_mpi_set_highbit
+#define gcry_mpi_set_opaque _gcry_mpi_set_opaque
+#define gcry_mpi_set_ui _gcry_mpi_set_ui
+#define gcry_mpi_snew _gcry_mpi_snew
+#define gcry_mpi_sub _gcry_mpi_sub
+#define gcry_mpi_sub_ui _gcry_mpi_sub_ui
+#define gcry_mpi_subm _gcry_mpi_subm
+#define gcry_mpi_swap _gcry_mpi_swap
+#define gcry_mpi_test_bit _gcry_mpi_test_bit
+
+
+/* Include the main header here so that public symbols are mapped to
+ the internal underscored ones. */
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+ /* We need to redeclare the deprecated functions without the
+ deprecated attribute. */
+# define GCRYPT_NO_DEPRECATED
+# include "gcrypt.h"
+/* The algorithm IDs. */
+ gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data);
+ void gcry_ac_data_destroy (gcry_ac_data_t data);
+ gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+ gcry_ac_data_t data);
+ unsigned int gcry_ac_data_length (gcry_ac_data_t data);
+ void gcry_ac_data_clear (gcry_ac_data_t data);
+ gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi);
+ gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi);
+ gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi);
+ gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers);
+ gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers);
+ void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...);
+ void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap);
+ gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags);
+ void gcry_ac_close (gcry_ac_handle_t handle);
+ gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data);
+ gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data);
+ gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which);
+ gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key);
+ gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key);
+ gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits);
+ gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip);
+ void gcry_ac_key_destroy (gcry_ac_key_t key);
+ void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair);
+ gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write);
+ gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write);
+ gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted);
+ gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted);
+ gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature);
+ gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature);
+ gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher);
+ gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message);
+ gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature);
+ gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature);
+ gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name);
+ gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm);
+#else
+# include "gcrypt.h"
+#endif
+
+/* Prototypes of functions exported but not ready for use. */
+gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
+ unsigned char *buffer, int buflen);
+void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
+gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os,
+ size_t *os_n);
+void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
+
+
+
+/* Our use of the ELF visibility feature works by passing
+ -fvisibiliy=hidden on the command line and by explicitly marking
+ all exported functions as visible.
+
+ NOTE: When adding new functions, please make sure to add them to
+ libgcrypt.vers and libgcrypt.def as well. */
+
+#ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
+
+/* A macro to flag a function as visible. Note that we take the
+ definition from the mapped name. */
+#ifdef GCRY_USE_VISIBILITY
+# define MARK_VISIBLE(name) \
+ extern __typeof__ (_##name) name __attribute__ ((visibility("default")));
+# define MARK_VISIBLEX(name) \
+ extern __typeof__ (name) name __attribute__ ((visibility("default")));
+#else
+# define MARK_VISIBLE(name) /* */
+# define MARK_VISIBLEX(name) /* */
+#endif
+
+
+/* First undef all redefined symbols so that we set the attribute on
+ the correct version name. */
+#undef gcry_check_version
+#undef gcry_control
+
+#undef gcry_set_allocation_handler
+#undef gcry_set_fatalerror_handler
+#undef gcry_set_gettext_handler
+#undef gcry_set_log_handler
+#undef gcry_set_outofcore_handler
+#undef gcry_set_progress_handler
+#undef gcry_err_code_from_errno
+#undef gcry_err_code_to_errno
+#undef gcry_err_make_from_errno
+#undef gcry_error_from_errno
+#undef gcry_strerror
+#undef gcry_strsource
+
+#undef gcry_free
+#undef gcry_malloc
+#undef gcry_malloc_secure
+#undef gcry_calloc
+#undef gcry_calloc_secure
+#undef gcry_realloc
+#undef gcry_strdup
+#undef gcry_is_secure
+#undef gcry_xcalloc
+#undef gcry_xcalloc_secure
+#undef gcry_xmalloc
+#undef gcry_xmalloc_secure
+#undef gcry_xrealloc
+#undef gcry_xstrdup
+
+#undef gcry_md_algo_info
+#undef gcry_md_algo_name
+#undef gcry_md_close
+#undef gcry_md_copy
+#undef gcry_md_ctl
+#undef gcry_md_enable
+#undef gcry_md_get
+#undef gcry_md_get_algo
+#undef gcry_md_get_algo_dlen
+#undef gcry_md_hash_buffer
+#undef gcry_md_info
+#undef gcry_md_is_enabled
+#undef gcry_md_is_secure
+#undef gcry_md_list
+#undef gcry_md_map_name
+#undef gcry_md_open
+#undef gcry_md_read
+/* gcry_md_register is not anymore a macro. */
+#undef gcry_md_unregister
+#undef gcry_md_reset
+#undef gcry_md_setkey
+#undef gcry_md_write
+#undef gcry_md_debug
+
+#undef gcry_cipher_algo_info
+#undef gcry_cipher_algo_name
+#undef gcry_cipher_close
+#undef gcry_cipher_setkey
+#undef gcry_cipher_setiv
+#undef gcry_cipher_setctr
+#undef gcry_cipher_ctl
+#undef gcry_cipher_decrypt
+#undef gcry_cipher_encrypt
+#undef gcry_cipher_get_algo_blklen
+#undef gcry_cipher_get_algo_keylen
+#undef gcry_cipher_info
+#undef gcry_cipher_list
+#undef gcry_cipher_map_name
+#undef gcry_cipher_mode_from_oid
+#undef gcry_cipher_open
+/* gcry_cipher_register is not anymore a macro. */
+#undef gcry_cipher_unregister
+
+#undef gcry_pk_algo_info
+#undef gcry_pk_algo_name
+#undef gcry_pk_ctl
+#undef gcry_pk_decrypt
+#undef gcry_pk_encrypt
+#undef gcry_pk_genkey
+#undef gcry_pk_get_keygrip
+#undef gcry_pk_get_curve
+#undef gcry_pk_get_param
+#undef gcry_pk_get_nbits
+#undef gcry_pk_list
+#undef gcry_pk_map_name
+/* gcry_pk_register is not anymore a macro. */
+#undef gcry_pk_unregister
+#undef gcry_pk_sign
+#undef gcry_pk_testkey
+#undef gcry_pk_verify
+
+#undef gcry_ac_data_new
+#undef gcry_ac_data_destroy
+#undef gcry_ac_data_copy
+#undef gcry_ac_data_length
+#undef gcry_ac_data_clear
+#undef gcry_ac_data_set
+#undef gcry_ac_data_get_name
+#undef gcry_ac_data_get_index
+#undef gcry_ac_open
+#undef gcry_ac_close
+#undef gcry_ac_key_init
+#undef gcry_ac_key_pair_generate
+#undef gcry_ac_key_pair_extract
+#undef gcry_ac_key_data_get
+#undef gcry_ac_key_test
+#undef gcry_ac_key_get_nbits
+#undef gcry_ac_key_get_grip
+#undef gcry_ac_key_destroy
+#undef gcry_ac_key_pair_destroy
+#undef gcry_ac_data_encrypt
+#undef gcry_ac_data_decrypt
+#undef gcry_ac_data_sign
+#undef gcry_ac_data_verify
+#undef gcry_ac_id_to_name
+#undef gcry_ac_name_to_id
+#undef gcry_ac_data_encode
+#undef gcry_ac_data_decode
+#undef gcry_ac_mpi_to_os
+#undef gcry_ac_mpi_to_os_alloc
+#undef gcry_ac_os_to_mpi
+#undef gcry_ac_data_encrypt_scheme
+#undef gcry_ac_data_decrypt_scheme
+#undef gcry_ac_data_sign_scheme
+#undef gcry_ac_data_verify_scheme
+#undef gcry_ac_data_to_sexp
+#undef gcry_ac_data_from_sexp
+#undef gcry_ac_io_init
+#undef gcry_ac_io_init_va
+
+#undef gcry_kdf_derive
+
+#undef gcry_prime_check
+#undef gcry_prime_generate
+#undef gcry_prime_group_generator
+#undef gcry_prime_release_factors
+
+#undef gcry_random_add_bytes
+#undef gcry_random_bytes
+#undef gcry_random_bytes_secure
+#undef gcry_randomize
+#undef gcry_create_nonce
+
+#undef gcry_sexp_alist
+#undef gcry_sexp_append
+#undef gcry_sexp_build
+#undef gcry_sexp_build_array
+#undef gcry_sexp_cadr
+#undef gcry_sexp_canon_len
+#undef gcry_sexp_car
+#undef gcry_sexp_cdr
+#undef gcry_sexp_cons
+#undef gcry_sexp_create
+#undef gcry_sexp_dump
+#undef gcry_sexp_find_token
+#undef gcry_sexp_length
+#undef gcry_sexp_new
+#undef gcry_sexp_nth
+#undef gcry_sexp_nth_data
+#undef gcry_sexp_nth_mpi
+#undef gcry_sexp_prepend
+#undef gcry_sexp_release
+#undef gcry_sexp_sprint
+#undef gcry_sexp_sscan
+#undef gcry_sexp_vlist
+#undef gcry_sexp_nth_string
+
+#undef gcry_mpi_add
+#undef gcry_mpi_add_ui
+#undef gcry_mpi_addm
+#undef gcry_mpi_aprint
+#undef gcry_mpi_clear_bit
+#undef gcry_mpi_clear_flag
+#undef gcry_mpi_clear_highbit
+#undef gcry_mpi_cmp
+#undef gcry_mpi_cmp_ui
+#undef gcry_mpi_copy
+#undef gcry_mpi_div
+#undef gcry_mpi_dump
+#undef gcry_mpi_gcd
+#undef gcry_mpi_get_flag
+#undef gcry_mpi_get_nbits
+#undef gcry_mpi_get_opaque
+#undef gcry_mpi_invm
+#undef gcry_mpi_mod
+#undef gcry_mpi_mul
+#undef gcry_mpi_mul_2exp
+#undef gcry_mpi_mul_ui
+#undef gcry_mpi_mulm
+#undef gcry_mpi_new
+#undef gcry_mpi_powm
+#undef gcry_mpi_print
+#undef gcry_mpi_randomize
+#undef gcry_mpi_release
+#undef gcry_mpi_rshift
+#undef gcry_mpi_lshift
+#undef gcry_mpi_scan
+#undef gcry_mpi_set
+#undef gcry_mpi_set_bit
+#undef gcry_mpi_set_flag
+#undef gcry_mpi_set_highbit
+#undef gcry_mpi_set_opaque
+#undef gcry_mpi_set_ui
+#undef gcry_mpi_snew
+#undef gcry_mpi_sub
+#undef gcry_mpi_sub_ui
+#undef gcry_mpi_subm
+#undef gcry_mpi_swap
+#undef gcry_mpi_test_bit
+
+
+/* Now mark all symbols. */
+
+MARK_VISIBLE (gcry_check_version)
+MARK_VISIBLE (gcry_control)
+
+MARK_VISIBLE (gcry_set_allocation_handler)
+MARK_VISIBLE (gcry_set_fatalerror_handler)
+MARK_VISIBLE (gcry_set_gettext_handler)
+MARK_VISIBLE (gcry_set_log_handler)
+MARK_VISIBLE (gcry_set_outofcore_handler)
+MARK_VISIBLE (gcry_set_progress_handler)
+MARK_VISIBLE (gcry_err_code_from_errno)
+MARK_VISIBLE (gcry_err_code_to_errno)
+MARK_VISIBLE (gcry_err_make_from_errno)
+MARK_VISIBLE (gcry_error_from_errno)
+MARK_VISIBLE (gcry_strerror)
+MARK_VISIBLE (gcry_strsource)
+
+MARK_VISIBLE (gcry_free)
+MARK_VISIBLE (gcry_malloc)
+MARK_VISIBLE (gcry_malloc_secure)
+MARK_VISIBLE (gcry_calloc)
+MARK_VISIBLE (gcry_calloc_secure)
+MARK_VISIBLE (gcry_realloc)
+MARK_VISIBLE (gcry_strdup)
+MARK_VISIBLE (gcry_is_secure)
+MARK_VISIBLE (gcry_xcalloc)
+MARK_VISIBLE (gcry_xcalloc_secure)
+MARK_VISIBLE (gcry_xmalloc)
+MARK_VISIBLE (gcry_xmalloc_secure)
+MARK_VISIBLE (gcry_xrealloc)
+MARK_VISIBLE (gcry_xstrdup)
+
+MARK_VISIBLE (gcry_md_algo_info)
+MARK_VISIBLE (gcry_md_algo_name)
+MARK_VISIBLE (gcry_md_close)
+MARK_VISIBLE (gcry_md_copy)
+MARK_VISIBLE (gcry_md_ctl)
+MARK_VISIBLE (gcry_md_enable)
+MARK_VISIBLE (gcry_md_get)
+MARK_VISIBLE (gcry_md_get_algo)
+MARK_VISIBLE (gcry_md_get_algo_dlen)
+MARK_VISIBLE (gcry_md_hash_buffer)
+MARK_VISIBLE (gcry_md_info)
+MARK_VISIBLE (gcry_md_is_enabled)
+MARK_VISIBLE (gcry_md_is_secure)
+MARK_VISIBLE (gcry_md_list)
+MARK_VISIBLE (gcry_md_map_name)
+MARK_VISIBLE (gcry_md_open)
+MARK_VISIBLE (gcry_md_read)
+MARK_VISIBLEX(gcry_md_register)
+MARK_VISIBLE (gcry_md_reset)
+MARK_VISIBLE (gcry_md_setkey)
+MARK_VISIBLE (gcry_md_unregister)
+MARK_VISIBLE (gcry_md_write)
+MARK_VISIBLE (gcry_md_debug)
+
+MARK_VISIBLE (gcry_cipher_algo_info)
+MARK_VISIBLE (gcry_cipher_algo_name)
+MARK_VISIBLE (gcry_cipher_close)
+MARK_VISIBLE (gcry_cipher_setkey)
+MARK_VISIBLE (gcry_cipher_setiv)
+MARK_VISIBLE (gcry_cipher_setctr)
+MARK_VISIBLE (gcry_cipher_ctl)
+MARK_VISIBLE (gcry_cipher_decrypt)
+MARK_VISIBLE (gcry_cipher_encrypt)
+MARK_VISIBLE (gcry_cipher_get_algo_blklen)
+MARK_VISIBLE (gcry_cipher_get_algo_keylen)
+MARK_VISIBLE (gcry_cipher_info)
+MARK_VISIBLE (gcry_cipher_list)
+MARK_VISIBLE (gcry_cipher_map_name)
+MARK_VISIBLE (gcry_cipher_mode_from_oid)
+MARK_VISIBLE (gcry_cipher_open)
+MARK_VISIBLEX(gcry_cipher_register)
+MARK_VISIBLE (gcry_cipher_unregister)
+
+MARK_VISIBLE (gcry_pk_algo_info)
+MARK_VISIBLE (gcry_pk_algo_name)
+MARK_VISIBLE (gcry_pk_ctl)
+MARK_VISIBLE (gcry_pk_decrypt)
+MARK_VISIBLE (gcry_pk_encrypt)
+MARK_VISIBLE (gcry_pk_genkey)
+MARK_VISIBLE (gcry_pk_get_keygrip)
+MARK_VISIBLE (gcry_pk_get_curve)
+MARK_VISIBLE (gcry_pk_get_param)
+MARK_VISIBLE (gcry_pk_get_nbits)
+MARK_VISIBLE (gcry_pk_list)
+MARK_VISIBLE (gcry_pk_map_name)
+MARK_VISIBLEX(gcry_pk_register)
+MARK_VISIBLE (gcry_pk_sign)
+MARK_VISIBLE (gcry_pk_testkey)
+MARK_VISIBLE (gcry_pk_unregister)
+MARK_VISIBLE (gcry_pk_verify)
+
+MARK_VISIBLE (gcry_ac_data_new)
+MARK_VISIBLE (gcry_ac_data_destroy)
+MARK_VISIBLE (gcry_ac_data_copy)
+MARK_VISIBLE (gcry_ac_data_length)
+MARK_VISIBLE (gcry_ac_data_clear)
+MARK_VISIBLE (gcry_ac_data_set)
+MARK_VISIBLE (gcry_ac_data_get_name)
+MARK_VISIBLE (gcry_ac_data_get_index)
+MARK_VISIBLE (gcry_ac_open)
+MARK_VISIBLE (gcry_ac_close)
+MARK_VISIBLE (gcry_ac_key_init)
+MARK_VISIBLE (gcry_ac_key_pair_generate)
+MARK_VISIBLE (gcry_ac_key_pair_extract)
+MARK_VISIBLE (gcry_ac_key_data_get)
+MARK_VISIBLE (gcry_ac_key_test)
+MARK_VISIBLE (gcry_ac_key_get_nbits)
+MARK_VISIBLE (gcry_ac_key_get_grip)
+MARK_VISIBLE (gcry_ac_key_destroy)
+MARK_VISIBLE (gcry_ac_key_pair_destroy)
+MARK_VISIBLE (gcry_ac_data_encrypt)
+MARK_VISIBLE (gcry_ac_data_decrypt)
+MARK_VISIBLE (gcry_ac_data_sign)
+MARK_VISIBLE (gcry_ac_data_verify)
+MARK_VISIBLE (gcry_ac_id_to_name)
+MARK_VISIBLE (gcry_ac_name_to_id)
+/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in
+ libgcrypt.vers. */
+MARK_VISIBLE (gcry_ac_data_encode)
+MARK_VISIBLE (gcry_ac_data_decode)
+MARK_VISIBLE (gcry_ac_mpi_to_os)
+MARK_VISIBLE (gcry_ac_mpi_to_os_alloc)
+MARK_VISIBLE (gcry_ac_os_to_mpi)
+MARK_VISIBLE (gcry_ac_data_encrypt_scheme)
+MARK_VISIBLE (gcry_ac_data_decrypt_scheme)
+MARK_VISIBLE (gcry_ac_data_sign_scheme)
+MARK_VISIBLE (gcry_ac_data_verify_scheme)
+MARK_VISIBLE (gcry_ac_data_to_sexp)
+MARK_VISIBLE (gcry_ac_data_from_sexp)
+MARK_VISIBLE (gcry_ac_io_init)
+MARK_VISIBLE (gcry_ac_io_init_va)
+
+MARK_VISIBLE (gcry_kdf_derive)
+
+MARK_VISIBLE (gcry_prime_check)
+MARK_VISIBLE (gcry_prime_generate)
+MARK_VISIBLE (gcry_prime_group_generator)
+MARK_VISIBLE (gcry_prime_release_factors)
+
+MARK_VISIBLE (gcry_random_add_bytes)
+MARK_VISIBLE (gcry_random_bytes)
+MARK_VISIBLE (gcry_random_bytes_secure)
+MARK_VISIBLE (gcry_randomize)
+MARK_VISIBLE (gcry_create_nonce)
+
+MARK_VISIBLE (gcry_sexp_alist)
+MARK_VISIBLE (gcry_sexp_append)
+MARK_VISIBLE (gcry_sexp_build)
+MARK_VISIBLE (gcry_sexp_build_array)
+MARK_VISIBLE (gcry_sexp_cadr)
+MARK_VISIBLE (gcry_sexp_canon_len)
+MARK_VISIBLE (gcry_sexp_car)
+MARK_VISIBLE (gcry_sexp_cdr)
+MARK_VISIBLE (gcry_sexp_cons)
+MARK_VISIBLE (gcry_sexp_create)
+MARK_VISIBLE (gcry_sexp_dump)
+MARK_VISIBLE (gcry_sexp_find_token)
+MARK_VISIBLE (gcry_sexp_length)
+MARK_VISIBLE (gcry_sexp_new)
+MARK_VISIBLE (gcry_sexp_nth)
+MARK_VISIBLE (gcry_sexp_nth_data)
+MARK_VISIBLE (gcry_sexp_nth_mpi)
+MARK_VISIBLE (gcry_sexp_prepend)
+MARK_VISIBLE (gcry_sexp_release)
+MARK_VISIBLE (gcry_sexp_sprint)
+MARK_VISIBLE (gcry_sexp_sscan)
+MARK_VISIBLE (gcry_sexp_vlist)
+MARK_VISIBLE (gcry_sexp_nth_string)
+
+MARK_VISIBLE (gcry_mpi_add)
+MARK_VISIBLE (gcry_mpi_add_ui)
+MARK_VISIBLE (gcry_mpi_addm)
+MARK_VISIBLE (gcry_mpi_aprint)
+MARK_VISIBLE (gcry_mpi_clear_bit)
+MARK_VISIBLE (gcry_mpi_clear_flag)
+MARK_VISIBLE (gcry_mpi_clear_highbit)
+MARK_VISIBLE (gcry_mpi_cmp)
+MARK_VISIBLE (gcry_mpi_cmp_ui)
+MARK_VISIBLE (gcry_mpi_copy)
+MARK_VISIBLE (gcry_mpi_div)
+MARK_VISIBLE (gcry_mpi_dump)
+MARK_VISIBLE (gcry_mpi_gcd)
+MARK_VISIBLE (gcry_mpi_get_flag)
+MARK_VISIBLE (gcry_mpi_get_nbits)
+MARK_VISIBLE (gcry_mpi_get_opaque)
+MARK_VISIBLE (gcry_mpi_invm)
+MARK_VISIBLE (gcry_mpi_mod)
+MARK_VISIBLE (gcry_mpi_mul)
+MARK_VISIBLE (gcry_mpi_mul_2exp)
+MARK_VISIBLE (gcry_mpi_mul_ui)
+MARK_VISIBLE (gcry_mpi_mulm)
+MARK_VISIBLE (gcry_mpi_new)
+MARK_VISIBLE (gcry_mpi_powm)
+MARK_VISIBLE (gcry_mpi_print)
+MARK_VISIBLE (gcry_mpi_randomize)
+MARK_VISIBLE (gcry_mpi_release)
+MARK_VISIBLE (gcry_mpi_rshift)
+MARK_VISIBLE (gcry_mpi_lshift)
+MARK_VISIBLE (gcry_mpi_scan)
+MARK_VISIBLE (gcry_mpi_set)
+MARK_VISIBLE (gcry_mpi_set_bit)
+MARK_VISIBLE (gcry_mpi_set_flag)
+MARK_VISIBLE (gcry_mpi_set_highbit)
+MARK_VISIBLE (gcry_mpi_set_opaque)
+MARK_VISIBLE (gcry_mpi_set_ui)
+MARK_VISIBLE (gcry_mpi_snew)
+MARK_VISIBLE (gcry_mpi_sub)
+MARK_VISIBLE (gcry_mpi_sub_ui)
+MARK_VISIBLE (gcry_mpi_subm)
+MARK_VISIBLE (gcry_mpi_swap)
+MARK_VISIBLE (gcry_mpi_test_bit)
+
+
+
+#undef MARK_VISIBLE
+#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/
+
+#endif /*GCRY_VISIBILITY_H*/
--- /dev/null
+2011-06-13 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_sign): Run PKCS1 tests only for RSA.
+ (check_pubkey_crypt): Ditto.
+
+ * pkcs1v2-pss.h, pkcs1v2-oaep.h, pkcs1v2-v15s.h, pkcs1v2-v15c.h: New.
+ * pkcs1v2.c: (check_pss, check_v15crypt): New.
+ (check_pss, check_pss): Factor test vector tables out.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_crypt): Run OAEP tests only for RSA.
+
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * pkcs1v2.c: New.
+ * Makefile.am (TESTS): Add pkcs1v2.
+
+ * basic.c (check_pubkey_sign): Add a test using random-override.
+ (check_pubkey_crypt): Ditto. Print ALGO in verbose mode.
+ (check_pubkey_grip): Silence unused parameter warning.
+
+2011-06-03 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Add option --die.
+
+2011-05-27 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_crypt): Add test data with invalid padding.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (do_check_one_pubkey): Add new arg ALGO to tell which PK
+ algorithm is used for check_pubkey_sign, check_pubkey_crypt,
+ check_pubkey_grip.
+ (check_pubkey_sign): Add new arg ALGO; skip test data if it does
+ not match ALGO.
+ (check_pubkey_crypt): Add new arg ALGO.
+ (check_pubkey_grip): Ditto.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_crypt): Remove unused "unpad" flag.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * basic.c (check_pubkey_sign): Add an OAEP flag parsing test case.
+ (check_pubkey_crypt): New.
+ (do_check_one_pubkey): Call it.
+ (check_one_pubkey): Free SKEY and PKEY.
+
+2011-04-11 Werner Koch <wk@g10code.com>
+
+ * basic.c (mismatch): New.
+ (check_ctr_cipher): Remove length error code checks. Add
+ truncation and streaming checks.
+
+2011-04-04 Werner Koch <wk@g10code.com>
+
+ * keygrip.c (main): Add option --repetitions.
+ (check): Make use of it.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * random.c (readn): Remove used var P.
+
+2011-02-21 Werner Koch <wk@g10code.com>
+
+ * version.c (main): Do a verbatim check of the version string.
+ * basic.c (main): Ditto. But die on mismatch.
+
+ * benchmark.c (md_bench): Allow for the --alignment option.
+ (main): Allow alignments between 1 and 16.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add option --disable-hwf.
+
+ * basic.c (DIM): New.
+ (check_bulk_cipher_modes): New.
+ (main): Run new test.
+
+2011-02-15 Werner Koch <wk@g10code.com>
+
+ * benchmark.c: Add option --cipher-with-keysetup.
+ (cipher_bench): Implement this option.
+
+2011-02-14 Werner Koch <wk@g10code.com>
+
+ * benchmark.c: Add option --alignment.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * curves.c: New.
+
+2011-01-04 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (LDADD): Fix typo in last change. Reported by
+ Andrey Jivsov.
+
+2010-07-19 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (LDADD): Add GPG_ERROR_LIBS to help a new wannabe ld.
+
+2010-06-10 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c (mpi2bitstr_nlz): Handle case for LENGTH==0.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * basic.c (check_cbc_mac_cipher): Print more info.
+ (main): Factor some code out to ...
+ (check_cipher_modes): .. new.
+
+2010-04-06 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * aeswrap.c, hmac.c, basic.c: Typo fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_digests): Add tests for TIGER1 and TIGER2 from
+ the NESSIE project.
+
+2010-01-21 Werner Koch <wk@g10code.com>
+
+ * benchmark.c [_GCRYPT_IN_LIBGCRYPT]: Include libcompat.h.
+ (start_timer, stop_timer) [__MINGW32CE__]: Use GetThreadTimes.
+ * Makefile.am (LDADD): Add libcompat.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_ctr_cipher): Add some return code checks.
+
+ * benchmark.c (cipher_bench): Merge Stream with ECB column.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * aeswrap.c: New.
+
+2009-07-09 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (progress_cb): New.
+ (main): Add option --progress.
+
+2009-06-08 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (cipher_bench): Center labels. Suggested by Brad Hards.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (print_buffer): Remove parens from initializer for
+ better portability. Reported by Dan Fandrich.
+
+2009-02-13 Werner Koch <wk@g10code.com>
+
+ * rsacvt.c (compute_missing): Fix dqm1 computation. Take care of
+ openpgp flag.
+ (main): Add option --openpgp.
+
+2009-02-11 Werner Koch <wk@g10code.com>
+
+ * rsacvt.c: New.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * cavs_tests.sh: Pass option -D to driver if required.
+
+ * fipsdrv.c (run_dsa_sign): Use hash of the data.
+ (dsa_gen_with_seed): New.
+ (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them.
+ (main): Optically take a seed for dsa-pgq-gen.
+ (standalone_mode): New.
+ (main): Add option --standalone.
+ (print_dsa_domain_parameters): Implement standalone mode.
+
+2009-01-21 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again.
+ (run_rsa_derive): Also print N.
+
+ * fipsdrv.c (run_dsa_verify): Use hash of the data.
+
+ * pubkey.c (get_dsa_key_fips186_with_seed_new): New.
+ (check_run): Call it.
+
+2008-12-11 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_rsa_derive): New.
+ (main): Add mode rsa-derive.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Check for error after running self-test in
+ non-fips mode.
+
+ * pubkey.c (get_dsa_key_with_domain_new): New.
+ (get_dsa_key_fips186_with_domain_new): New.
+ (check_run): Call them.
+
+2008-12-08 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c [W32]: Include fcntl.h.
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (get_dsa_key_new): Add arg transient_key.
+ (check_run): Use it.
+
+2008-12-03 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_dsa_pqg_gen): Facor code out into ..
+ (print_dsa_domain_parameters, dsa_gen): .. these two new functions.
+ (print_sexp, read_sexp_from_file): New.
+ (run_dsa_sign): New.
+ (run_dsa_verify): New.
+
+2008-12-02 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c: All standalone build.
+
+ * mpitests.c (mpi_powm): New.
+
+2008-11-28 Werner Koch <wk@g10code.com>
+
+ * fips186-dsa.c: New.
+
+ * fipsdrv.c (print_mpi_line, print_data_line): New.
+ (run_dsa_pqg_gen): New.
+ (usage): Add mode dsa-pqg-gen.
+
+2008-11-25 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (get_dsa_key_new): New.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * tsexp.c (basic): Add test for format character S.
+
+ * pubkey.c (check_x931_derived_key): New.
+ (get_keys_x931_new): New.
+ (check_run): Check X9.31 generated RSA key.
+
+2008-11-07 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_cipher_mct_loop, get_current_iv): New.
+ (read_textline, read_hexline, skip_to_empty_line): New.
+ (main): New option --mct-server.
+ * cavs_driver.pl: Update from upstream and adjust to new fipsdrv.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_encrypt_decrypt): Disable weak key detection.
+
+2008-10-31 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_rsa_sign): Buffer needs to be larger for SHA512.
+
+2008-10-27 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (run_encrypt_decrypt): Make IV_BUFFER optional.
+ (main): Ditto.
+ * cavs_driver.pl: Remove the --no-fips flags.
+ (libgcrypt_encdec($$$$$)): Make IV optional.
+ (libgcrypt_state_cipher($$$$$)): Ditto.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (md_bench): Do not test MD5 in fips mode.
+ * basic.c (check_digests, check_hmac): Ditto.
+
+2008-10-06 Werner Koch <wk@g10code.com>
+
+ * cavs_driver.pl: New version from upstream.
+ (libgcrypt_rsa_verify($$$$)): Pass pkcs1.
+ (libgcrypt_rsa_sign($$$)): Pass pkcs1 and hash algo.
+
+ * fipsdrv.c (run_rsa_sign): Hash data in pkcs1 mode.
+ (run_rsa_verify): Ditto.
+ (read_key_file): Rename to read_private_key_file. Factor public
+ key code out to..
+ (read_public_key_file): .. new.
+
+2008-10-02 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c (print_buffer): Add base64 printing code.
+ (base64_decode, read_key_file, parse_tag, read_sig_file): New.
+ (run_rsa_gen, run_rsa_sign): New.
+ (main): Add modes rsa-gen, rsa-sign and rsa-verify.
+
+
+2008-09-29 Werner Koch <wk@g10code.com>
+
+ * fipsdrv.c: Merge code from fipsrngdrv.c
+ * fipsrngdrv.c: Remove.
+
+2008-09-26 Werner Koch <wk@g10code.com>
+
+ * Makefile.am: Distribute cavs_driver.pl.
+ * cavs_tests.sh: New.
+ * fipsdrv.c: New.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Do not disable secure memory in FIPS mode.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Do not disable secure memory in FIPS mode.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * fipsrngdrv.c (main): Bail out on write error. Implement verbose
+ option.
+ (main): Use flag to disable dup block checks.
+
+2008-09-15 Werner Koch <wk@g10code.com>
+
+ * fipsrngdrv.c: New.
+
+2008-09-09 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): New option --selftest.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * keygrip.c: Update to also check ECDSA.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * rsa-16k.key: New sample key.
+
+2008-08-27 Werner Koch <wk@g10code.com>
+
+ * pkbench.c (read_file): New.
+ (process_key_pair_file): Replace mmap by read_file.
+ (main): Add a --fips option.
+ * Makefile.am (EXTRA_DIST): Remove.
+ (EXTRA_PROGRAMS): Add pkbench.
+
+ * basic.c (main): Extended FIPS self-test test.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * basic.c (get_keys_new): Use transient-key flag.
+ * benchmark.c (main): First check options then do the libgcrypt
+ initialization.
+ (rsa_bench): Use transient-key flag if not in fips mode.
+
+2008-08-20 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c (test_lshift): New.
+ (mpi2bitstr_nlz, lshiftbitstring): New.
+ (main): Run test.
+
+2008-08-18 Werner Koch <wk@g10code.com>
+
+ * basic.c (main): Add option --fips.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * register.c (main): Check for fips mode.
+ (check_run): Take care of fips mode.
+
+ * basic.c (check_cbc_mac_cipher, check_ciphers, check_digests)
+ (check_hmac, check_pubkey): Do not test unavalaible algorithms in
+ fips mode.
+ (main): Check for fips mode.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_one_cipher): Also check in-place encryption.
+
+2008-03-17 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add option --cipher-repetition.
+ (cipher_bench): Use it.
+
+2008-03-12 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (rsa_bench): Add arg NO_BLINDING.
+ (main): Add option --no-blinding.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sample_private_key_1_1,sample_private_key_1_2): New.
+ (get_keys_sample): Add arg SECRET_VARIANT.
+ (check_run): Check all variants. Also check gcry_pk_testkey.
+ (check_keys_crypt): Add DECRYPT_FAIL_CODE.
+ (check_keys): Ditto.
+
+2007-11-30 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Add optione --verbose and reworked the
+ option parsing.
+ (random_bench): Dump random stats.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (start_timer, stop_timer, elapsed_time) [W32]: Fixed.
+
+2007-06-20 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (rsa_bench): New.
+ (main): New command "rsa".
+
+2007-05-03 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (EXTRA_DIST): Do not build pkbench.c
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * basic.c (check_ciphers): Add Camellia.
+
+2007-04-30 David Shaw <dshaw@jabberwocky.com>
+
+ * basic.c (check_ciphers): #if out ciphers we don't have. Add
+ test for GCRY_CIPHER_RFC2268_40.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * version.c: New.
+ * Makefile.am (TESTS): Add version.
+
+2007-04-30 Marcus Brinkmann <marcus@g10code.de>
+
+ * benchmark.c (ecc_bench): Release KEY_SPEC.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac-data.c (check_run): Don't give redundant GCRY_AC_FLAG_DEALLOC
+ in addition to GCRY_AC_FLAG_COPY. Don't release LABEL1 or MPI0,
+ as those are donated to libgcrypt, but do release MPI0 and MPI2.
+
+2007-04-12 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac-schemes.c (scheme_spec): Revert last change.
+
+ * ac-schemes.c (scheme_spec): Remove const qualifier from member M.
+ (es_check): Remove const qualifier from C and M2.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * pkbench.c (generate_key): Support named curves.
+
+ * benchmark.c (dsa_bench): New args ITERATIONS and PRINT_HEADER.
+ (main): Call dsa and ecc benchs.
+ (show_sexp): New.
+
+ * Makefile.am (TESTS): Move pkbench to EXTRA_PROGRAMS.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (die): New.
+ (ecc_bench): New.
+
+ * pkbench.c (main): Reworked to provide proper option handling.
+
+2007-03-13 Werner Koch <wk@g10code.com>
+
+ * mpitests.c: Reformatted to GNU standards.
+ (main): Add options --verbose and --debug for future use.
+
+2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk)
+
+ * mpitests.c: New.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (TEST): Run benchmark as last.
+
+ * ac-data.c (check_sexp_conversion): Print label only in verbose
+ mode.
+
+ * pubkey.c (main): Run test just 2 times instead of 10.
+ (get_elg_key_new): New.
+ (check_run): Also run tests with Elgamal keys.
+ (check_keys): New arg NBITS_DATA.
+ (get_elg_key_new): Use only 400 for the 512 bit Elgamal test.
+
+ * random.c: New.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * basic.c (check_pubkey_sign): Also try signing using an OID.
+
+ * Makefile.am (TESTS) [W32]: Removed pkbench for now.
+ * pkbench.c (benchmark): Fixed for W32.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * hmac.c (check_one_mac): Make pointer args const.
+ * basic.c (check_one_md): Ditto.
+ (check_one_hmac): Ditto.
+
+ * keygen.c (progress_cb): Filter out line feeds.
+ * basic.c (progress_handler): Ditto.
+
+2006-12-18 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (AM_CFLAGS, AM_CPPFLAGS): Splitted and merged with
+ Moritz' changes.
+ (INCLUDES): Removed.
+
+ * keygen.c (progress_handler): New.
+ (main): Use it in verbose mode.
+
+2006-11-05 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the
+ new gcrypt.h is used, not the one installed in the system.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * keygen.c (check_rsa_keys): Also create an 1536 bit DSA key.
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * t-mpi-bit.c: New.
+
+2006-07-06 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): New option --use-random-daemon. New command
+ strongrandom.
+ (random_bench): New arg VERY_STRONG.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (main): Allow for seed file argument to random bench.
+
+ * basic.c (main): Use progress handler only in verbose mode.
+ (main): Speed up test key generation.
+ * ac-data.c (check_sexp_conversion, check_run): Take care of VERBOSE.
+ * ac.c (main): Ditto.
+ * pubkey.c (main): Ditto.
+ * pkbench.c (main): Ditto.
+ * keygen.c (main): Ditto.
+ (check_rsa_keys): Print key only in verbose mode.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2006-02-18)
+
+ * basic.c (check_one_hmac, check_hmac): New.
+
+2006-03-07 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (cipher_bench): Add OFB mode.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * basic.c: Added test cases for OFB and CFB modes. Fixed some
+ compiler warnings for signedness.
+
+2005-11-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac-data.c: Added way more test cases.
+
+2005-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added keygrip.
+ * keygrip.c: New.
+
+2005-09-19 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (dsa_bench): New.
+
+2005-08-19 Werner Koch <wk@g10code.com>
+
+ * hmac.c (main): Added all FIPS tests.
+
+2005-08-18 Werner Koch <wk@g10code.com>
+
+ * hmac.c: New.
+
+2005-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * tsexp.c: Include <config.h> in case HAVE_CONFIG_H is defined;
+ thanks to Albert Chin.
+ * testapi.c: Likewise.
+ * register.c: Likewise.
+ * pubkey.c: Likewise.
+ * prime.c: Likewise.
+ * pkbench.c: Likewise.
+ * keygen.c: Likewise.
+ * benchmark.c: Likewise.
+ * basic.c: Likewise.
+ * ac-schemes.c: Likewise.
+ * ac-data.c: Likewise.
+ * ac.c: Likewise.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * ac-data.c (check_run): Include new test.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_digests): Add tests for Whirlpool.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * ac-schemes.c: New file.
+ * ac-data.c: New file.
+ * Makefile.am (TESTS): Added ac-schemes and ac-data.
+
+2004-09-15 Moritz Schulte <moritz@g10code.com>
+
+ * pkbench.c: Include <time.h>.
+
+2004-08-24 Moritz Schulte <moritz@g10code.com>
+
+ * pkbench.c (context_init): Improve generation of test data.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: pkbench.
+ * pkbench.c: New file.
+
+2004-02-25 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (TEST): Add benchmark.
+
+ * benchmark.c (md_bench, cipher_bench): Allow NULL arg to to run
+ tests for all algorithms.
+ (main): Run all tests by default.
+
+2004-02-03 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (basic): New pass to check secure memory switching.
+
+2004-01-12 Moritz Schulte <mo@g10code.com>
+
+ * ac.c (check_one): Adjust to new ac API.
+
+2003-11-22 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (check_keys_crypt): Fixed my last patch.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (basic): Add pass structure and a test for the %b
+ format.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * Makefile.am (noinst_PROGRAMS): Use this so that test programs
+ get always build.
+
+ * keygen.c (check_nonce): New.
+ (main): Add a basic check for the nocen function.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_aes128_cbc_cts_cipher): Make it a prototype
+
+ * ac.c (check_run): Comment unused variable.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * prime.c (check_primes): Generate a generator and avoid printing
+ unless in verbose mode.
+
+2003-10-07 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (check_sscan): New.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (check_keys_crypt): Fix for compatibility mode.
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * Makefile.am (TESTS): Added: prime.
+
+ * prime.c: New file.
+
+2003-08-27 Moritz Schulte <mo@g10code.com>
+
+ * basic.c (check_ciphers): Added: Serpent.
+ Write braces around flags.
+
+2003-08-04 Moritz Schulte <moritz@g10code.com>
+
+ * benchmark.c (do_powm): Adjust for new gcry_mpi_scan interface.
+
+2003-07-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (key_copy): New function...
+ (check_one): ... use it.
+
+2003-07-22 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_ciphers): Use gcry_cipher_map_name.
+
+2003-07-18 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (check_run): Renamed to ...
+ (check_one): ... this, changed calling interface.
+ (check_run): New function.
+
+ * register.c: Adjust gcry_cipher_spec_t structure.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * register.c: Adjust cipher specification structure.
+
+ * benchmark.c: New file.
+ * testapi.c: New file.
+
+ * Makefile.am (EXTRA_PROGRAMS): Set to: benchmark testapi.
+ (check_PROGRAMS): Set to: $(TESTS).
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c, basic.c, keygen.c, register.c, sexp.c, tsexp.c: Used
+ gcry_err* wrappers for libgpg symbols.
+
+ * basic.c (check_ciphers): Added: GCRY_CIPHER_TWOFISH128.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (LIBS): Remove: -lpthread.
+
+ * basic.c (check_one_cipher): Fix variable initialization. Thanks
+ to Simon Joseffson <jas@extundo.com>.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: register.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * register.c (check_run): Adjusted for new gcry_cipher_register API.
+
+2003-07-02 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added: ac.
+ * ac.c: New file.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_cbc_mac_cipher): Adjusted for new API of get_blklen
+ and get_keylen.
+ (check_ctr_cipher): Ditto.
+ (check_one_cipher): Ditto.
+ (check_one_md): Adjusted for new API of gcry_md_copy.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * register.c: Replace old type GcryModule with newer one:
+ gcry_module_t.
+ Adjusted for new API.
+
+ * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+
+2003-06-15 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (get_keys_new): New function.
+ (do_check_one_pubkey): New function ...
+ (check_one_pubkey): ... use it.
+ (progress_handler): New function.
+ (main): Use gcry_set_progress_handler.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c: Replaced calls to gcry_strerror with calls to
+ gpg_strerror.
+ (check_one_md): Adjust for new gcry_md_copy API.
+
+ * tsexp.c: Likewise.
+ * keygen.c: Likewise.
+
+2003-06-12 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c: Changed here and there, reorganized pubkey checks,
+ added DSA and ELG keys.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c, keygen.c, pubkey.c, register.c, tsexp.c: Changed to use
+ new API.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * tsexp.c (canon_len): Adjust for new gcry_sexp_canon_len API.
+
+2003-05-26 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (verify_one_signature): Adjust for libgpg-error.
+ (check_pubkey_sign): Likewise.
+ (check_pubkey): Likewise.
+ * basic.c (check_pubkey_sign): Likewise.
+ * tsexp.c (canon_len): Likewise.
+ (back_and_forth_one): Likewise.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c: Changed the sample private key to contain the
+ identifier `openpgp-rsa' instead of `rsa'.
+
+ * basic.c (check_digests): Enabled/fixed some tests for TIGER.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Removed `register' for now.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_digests): Include checks for SHA512 and SHA384.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_one_md): Also test md_copy.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added register.
+
+ * register.c: New file.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_one_cipher): New. Test CTR.
+ (main): Call it.
+ (check_ciphers): Check CTR mode.
+
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (TESTS): Added pubkey.
+
+ * pubkey.c: New file.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_cbc_mac_cipher): New.
+ (main): Use it.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * keygen.c (check_rsa_keys): Don't expect an exponent when asking
+ for e=0.
+ (check_generated_rsa_key): Just print exponent if EXPECTED_E is 0.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * basic.c (check_one_cipher): Use gcry_cipher_reset() instead of
+ gcry_cipher_close(), gcry_cipher_open and gcry_cipher_setkey().
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * keygen.c: New.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_digests): Add CRC.
+ (check_one_md): Print computed and expected values on error.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_one_md): Kludge to check a one million "a".
+ (check_digests): Add checks for SHA-256.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_pubkey): Check the keygrip for the sample key.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * basic.c (verify_one_signature,check_pubkey_sign)
+ (check_pubkey): New.
+ (main): Check public key functions. Add a --debug option.
+
+2002-11-23 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_digests): Add another test for MD4. By Simon
+ Josefsson.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * basic.c (check_aes128_cbc_cts_cipher): New function.
+ (check_one_cipher): Add flags parameter.
+ (check_ciphers): Support flags parameter.
+ (main): Check CTS.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_one_md): New. By Simon Josefsson.
+ (check_digests): New tests for MD4. By Simon.
+
+2002-08-26 Werner Koch <wk@gnupg.org>
+
+ * basic.c (check_ciphers): Check simple DES.
+
+2002-05-16 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (back_and_forth): Very minimal test of the new functions.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of all files to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * basic.c: Add option --verbose.
+
+2002-01-11 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c (canon_len): Fixed tests.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * tsexp.c: New.
+
+
+ Copyright 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
+
+ This file is free software; as a special exception the author gives
+ unlimited permission to copy and/or distribute it, with or without
+ modifications, as long as this notice is preserved.
+
+ This file is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
--- /dev/null
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+## Process this file with automake to produce Makefile.in
+
+TESTS = version t-mpi-bit prime register ac ac-schemes ac-data basic \
+ mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap \
+ curves t-kdf pkcs1v2
+
+
+# random.c uses fork() thus a test for W32 does not make any sense.
+if !HAVE_W32_SYSTEM
+TESTS += random
+endif
+
+# The last test to run.
+TESTS += benchmark
+
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+
+LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la $(GPG_ERROR_LIBS)
+
+EXTRA_PROGRAMS = testapi pkbench
+noinst_PROGRAMS = $(TESTS) fipsdrv rsacvt
+
+EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
+ pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h
--- /dev/null
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is part of Libgcrypt.
+#
+# Libgcrypt is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as
+# published by the Free Software Foundation; either version 2.1 of
+# the License, or (at your option) any later version.
+#
+# Libgcrypt 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+TESTS = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \
+ register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \
+ ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \
+ tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \
+ keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \
+ curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \
+ $(am__EXEEXT_1) benchmark$(EXEEXT)
+
+# random.c uses fork() thus a test for W32 does not make any sense.
+@HAVE_W32_SYSTEM_FALSE@am__append_1 = random
+EXTRA_PROGRAMS = testapi$(EXEEXT) pkbench$(EXEEXT)
+noinst_PROGRAMS = $(am__EXEEXT_2) fipsdrv$(EXEEXT) rsacvt$(EXEEXT)
+subdir = tests
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ ChangeLog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
+ $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+@HAVE_W32_SYSTEM_FALSE@am__EXEEXT_1 = random$(EXEEXT)
+am__EXEEXT_2 = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \
+ register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \
+ ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \
+ tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \
+ keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \
+ curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \
+ $(am__EXEEXT_1) benchmark$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+ac_SOURCES = ac.c
+ac_OBJECTS = ac.$(OBJEXT)
+ac_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+ac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+ac_data_SOURCES = ac-data.c
+ac_data_OBJECTS = ac-data.$(OBJEXT)
+ac_data_LDADD = $(LDADD)
+ac_data_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+ac_schemes_SOURCES = ac-schemes.c
+ac_schemes_OBJECTS = ac-schemes.$(OBJEXT)
+ac_schemes_LDADD = $(LDADD)
+ac_schemes_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+aeswrap_SOURCES = aeswrap.c
+aeswrap_OBJECTS = aeswrap.$(OBJEXT)
+aeswrap_LDADD = $(LDADD)
+aeswrap_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+basic_SOURCES = basic.c
+basic_OBJECTS = basic.$(OBJEXT)
+basic_LDADD = $(LDADD)
+basic_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+benchmark_SOURCES = benchmark.c
+benchmark_OBJECTS = benchmark.$(OBJEXT)
+benchmark_LDADD = $(LDADD)
+benchmark_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+curves_SOURCES = curves.c
+curves_OBJECTS = curves.$(OBJEXT)
+curves_LDADD = $(LDADD)
+curves_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+fips186_dsa_SOURCES = fips186-dsa.c
+fips186_dsa_OBJECTS = fips186-dsa.$(OBJEXT)
+fips186_dsa_LDADD = $(LDADD)
+fips186_dsa_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+fipsdrv_SOURCES = fipsdrv.c
+fipsdrv_OBJECTS = fipsdrv.$(OBJEXT)
+fipsdrv_LDADD = $(LDADD)
+fipsdrv_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+hmac_SOURCES = hmac.c
+hmac_OBJECTS = hmac.$(OBJEXT)
+hmac_LDADD = $(LDADD)
+hmac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+keygen_SOURCES = keygen.c
+keygen_OBJECTS = keygen.$(OBJEXT)
+keygen_LDADD = $(LDADD)
+keygen_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+keygrip_SOURCES = keygrip.c
+keygrip_OBJECTS = keygrip.$(OBJEXT)
+keygrip_LDADD = $(LDADD)
+keygrip_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+mpitests_SOURCES = mpitests.c
+mpitests_OBJECTS = mpitests.$(OBJEXT)
+mpitests_LDADD = $(LDADD)
+mpitests_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pkbench_SOURCES = pkbench.c
+pkbench_OBJECTS = pkbench.$(OBJEXT)
+pkbench_LDADD = $(LDADD)
+pkbench_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pkcs1v2_SOURCES = pkcs1v2.c
+pkcs1v2_OBJECTS = pkcs1v2.$(OBJEXT)
+pkcs1v2_LDADD = $(LDADD)
+pkcs1v2_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+prime_SOURCES = prime.c
+prime_OBJECTS = prime.$(OBJEXT)
+prime_LDADD = $(LDADD)
+prime_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pubkey_SOURCES = pubkey.c
+pubkey_OBJECTS = pubkey.$(OBJEXT)
+pubkey_LDADD = $(LDADD)
+pubkey_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+random_SOURCES = random.c
+random_OBJECTS = random.$(OBJEXT)
+random_LDADD = $(LDADD)
+random_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+register_SOURCES = register.c
+register_OBJECTS = register.$(OBJEXT)
+register_LDADD = $(LDADD)
+register_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+rsacvt_SOURCES = rsacvt.c
+rsacvt_OBJECTS = rsacvt.$(OBJEXT)
+rsacvt_LDADD = $(LDADD)
+rsacvt_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+t_kdf_SOURCES = t-kdf.c
+t_kdf_OBJECTS = t-kdf.$(OBJEXT)
+t_kdf_LDADD = $(LDADD)
+t_kdf_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+t_mpi_bit_SOURCES = t-mpi-bit.c
+t_mpi_bit_OBJECTS = t-mpi-bit.$(OBJEXT)
+t_mpi_bit_LDADD = $(LDADD)
+t_mpi_bit_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+testapi_SOURCES = testapi.c
+testapi_OBJECTS = testapi.$(OBJEXT)
+testapi_LDADD = $(LDADD)
+testapi_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+tsexp_SOURCES = tsexp.c
+tsexp_OBJECTS = tsexp.$(OBJEXT)
+tsexp_LDADD = $(LDADD)
+tsexp_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+version_SOURCES = version.c
+version_OBJECTS = version.$(OBJEXT)
+version_LDADD = $(LDADD)
+version_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+ ../compat/libcompat.la $(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c benchmark.c \
+ curves.c fips186-dsa.c fipsdrv.c hmac.c keygen.c keygrip.c \
+ mpitests.c pkbench.c pkcs1v2.c prime.c pubkey.c random.c \
+ register.c rsacvt.c t-kdf.c t-mpi-bit.c testapi.c tsexp.c \
+ version.c
+DIST_SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c \
+ benchmark.c curves.c fips186-dsa.c fipsdrv.c hmac.c keygen.c \
+ keygrip.c mpitests.c pkbench.c pkcs1v2.c prime.c pubkey.c \
+ random.c register.c rsacvt.c t-kdf.c t-mpi-bit.c testapi.c \
+ tsexp.c version.c
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_FILEVERSION = @BUILD_FILEVERSION@
+BUILD_REVISION = @BUILD_REVISION@
+BUILD_TIMESTAMP = @BUILD_TIMESTAMP@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DL_LIBS = @DL_LIBS@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
+FGREP = @FGREP@
+GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
+GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
+GCRYPT_RANDOM = @GCRYPT_RANDOM@
+GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
+GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@
+GPG_ERROR_LIBS = @GPG_ERROR_LIBS@
+GREP = @GREP@
+INSERT_SYS_SELECT_H = @INSERT_SYS_SELECT_H@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@
+LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@
+LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@
+LIBGCRYPT_CONFIG_HOST = @LIBGCRYPT_CONFIG_HOST@
+LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@
+LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@
+LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@
+LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@
+LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@
+LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@
+LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MPI_SFLAGS = @MPI_SFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTH_CFLAGS = @PTH_CFLAGS@
+PTH_CONFIG = @PTH_CONFIG@
+PTH_LIBS = @PTH_LIBS@
+RANLIB = @RANLIB@
+RC = @RC@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+SYS_SOCKET_H = @SYS_SOCKET_H@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+emacs_local_vars_begin = @emacs_local_vars_begin@
+emacs_local_vars_end = @emacs_local_vars_end@
+emacs_local_vars_read_only = @emacs_local_vars_read_only@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+
+# Need to include ../src in addition to top_srcdir because gcrypt.h is
+# a built header.
+AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la $(GPG_ERROR_LIBS)
+EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl \
+ pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+ac$(EXEEXT): $(ac_OBJECTS) $(ac_DEPENDENCIES)
+ @rm -f ac$(EXEEXT)
+ $(LINK) $(ac_OBJECTS) $(ac_LDADD) $(LIBS)
+ac-data$(EXEEXT): $(ac_data_OBJECTS) $(ac_data_DEPENDENCIES)
+ @rm -f ac-data$(EXEEXT)
+ $(LINK) $(ac_data_OBJECTS) $(ac_data_LDADD) $(LIBS)
+ac-schemes$(EXEEXT): $(ac_schemes_OBJECTS) $(ac_schemes_DEPENDENCIES)
+ @rm -f ac-schemes$(EXEEXT)
+ $(LINK) $(ac_schemes_OBJECTS) $(ac_schemes_LDADD) $(LIBS)
+aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES)
+ @rm -f aeswrap$(EXEEXT)
+ $(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS)
+basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES)
+ @rm -f basic$(EXEEXT)
+ $(LINK) $(basic_OBJECTS) $(basic_LDADD) $(LIBS)
+benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES)
+ @rm -f benchmark$(EXEEXT)
+ $(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS)
+curves$(EXEEXT): $(curves_OBJECTS) $(curves_DEPENDENCIES)
+ @rm -f curves$(EXEEXT)
+ $(LINK) $(curves_OBJECTS) $(curves_LDADD) $(LIBS)
+fips186-dsa$(EXEEXT): $(fips186_dsa_OBJECTS) $(fips186_dsa_DEPENDENCIES)
+ @rm -f fips186-dsa$(EXEEXT)
+ $(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS)
+fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES)
+ @rm -f fipsdrv$(EXEEXT)
+ $(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_LDADD) $(LIBS)
+hmac$(EXEEXT): $(hmac_OBJECTS) $(hmac_DEPENDENCIES)
+ @rm -f hmac$(EXEEXT)
+ $(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS)
+keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES)
+ @rm -f keygen$(EXEEXT)
+ $(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS)
+keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES)
+ @rm -f keygrip$(EXEEXT)
+ $(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS)
+mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES)
+ @rm -f mpitests$(EXEEXT)
+ $(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS)
+pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES)
+ @rm -f pkbench$(EXEEXT)
+ $(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS)
+pkcs1v2$(EXEEXT): $(pkcs1v2_OBJECTS) $(pkcs1v2_DEPENDENCIES)
+ @rm -f pkcs1v2$(EXEEXT)
+ $(LINK) $(pkcs1v2_OBJECTS) $(pkcs1v2_LDADD) $(LIBS)
+prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES)
+ @rm -f prime$(EXEEXT)
+ $(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS)
+pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES)
+ @rm -f pubkey$(EXEEXT)
+ $(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS)
+random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES)
+ @rm -f random$(EXEEXT)
+ $(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS)
+register$(EXEEXT): $(register_OBJECTS) $(register_DEPENDENCIES)
+ @rm -f register$(EXEEXT)
+ $(LINK) $(register_OBJECTS) $(register_LDADD) $(LIBS)
+rsacvt$(EXEEXT): $(rsacvt_OBJECTS) $(rsacvt_DEPENDENCIES)
+ @rm -f rsacvt$(EXEEXT)
+ $(LINK) $(rsacvt_OBJECTS) $(rsacvt_LDADD) $(LIBS)
+t-kdf$(EXEEXT): $(t_kdf_OBJECTS) $(t_kdf_DEPENDENCIES)
+ @rm -f t-kdf$(EXEEXT)
+ $(LINK) $(t_kdf_OBJECTS) $(t_kdf_LDADD) $(LIBS)
+t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES)
+ @rm -f t-mpi-bit$(EXEEXT)
+ $(LINK) $(t_mpi_bit_OBJECTS) $(t_mpi_bit_LDADD) $(LIBS)
+testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES)
+ @rm -f testapi$(EXEEXT)
+ $(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS)
+tsexp$(EXEEXT): $(tsexp_OBJECTS) $(tsexp_DEPENDENCIES)
+ @rm -f tsexp$(EXEEXT)
+ $(LINK) $(tsexp_OBJECTS) $(tsexp_LDADD) $(LIBS)
+version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES)
+ @rm -f version$(EXEEXT)
+ $(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-data.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-schemes.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aeswrap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips186-dsa.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fipsdrv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygen.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygrip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpitests.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkbench.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkcs1v2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/register.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsacvt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-kdf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-bit.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsexp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null
+Some notes about the tests.
+
+rsa-16k.key - A 16384 bit RSA key (public and privat), created 2008-08-28.
+ It took 91 minutes to create it on a 1500Mhz Pentium M.
+ pkpench showed these results:
+ encrypt: 80 ms
+ decrypt: 14370 ms
+ sign: 14110 ms
+ verify: 30 ms
--- /dev/null
+/* ac-data.c - Public key encryption/decryption tests
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define assert_err(err) \
+ do \
+ if (err) \
+ { \
+ fprintf (stderr, "Error occurred at line %i: %s\n", \
+ __LINE__, gcry_strerror (err)); \
+ exit (1); \
+ } \
+ while (0)
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+static void
+check_sexp_conversion (gcry_ac_data_t data, const char **identifiers)
+{
+ gcry_ac_data_t data2;
+ gcry_error_t err;
+ gcry_sexp_t sexp;
+ unsigned int i;
+ const char *label1, *label2;
+ gcry_mpi_t mpi1, mpi2;
+ size_t length1, length2;
+
+ err = gcry_ac_data_to_sexp (data, &sexp, identifiers);
+ assert_err (err);
+ if (verbose)
+ gcry_sexp_dump (sexp);
+ err = gcry_ac_data_from_sexp (&data2, sexp, identifiers);
+ assert_err (err);
+
+ length1 = gcry_ac_data_length (data);
+ length2 = gcry_ac_data_length (data2);
+ assert (length1 == length2);
+
+ for (i = 0; i < length1; i++)
+ {
+ err = gcry_ac_data_get_index (data, 0, i, &label1, &mpi1);
+ assert_err (err);
+ err = gcry_ac_data_get_index (data2, 0, i, &label2, &mpi2);
+ assert_err (err);
+ if (verbose)
+ {
+ fprintf (stderr, "Label1=`%s'\n", label1);
+ fprintf (stderr, "Label2=`%s'\n", label2);
+ }
+ assert (! strcmp (label1, label2));
+ assert (! gcry_mpi_cmp (mpi1, mpi2));
+ }
+
+ gcry_ac_data_destroy (data2);
+ gcry_sexp_release (sexp);
+}
+
+void
+check_run (void)
+{
+ const char *identifiers[] = { "foo",
+ "bar",
+ "baz",
+ "hello",
+ "somemoretexthere",
+ "blahblahblah",
+ NULL };
+ const char *identifiers_null[] = { NULL };
+ gcry_ac_data_t data;
+ gcry_error_t err;
+ const char *label0;
+ const char *label1;
+ gcry_mpi_t mpi0;
+ gcry_mpi_t mpi1;
+ gcry_mpi_t mpi2;
+
+ /* Initialize values. */
+
+ label0 = "thisisreallylonglabelbutsincethereisnolimitationonthelengthoflabelsitshouldworkjustfine";
+ mpi0 = gcry_mpi_new (0);
+ assert (mpi0);
+ gcry_mpi_set_ui (mpi0, 123456);
+
+ err = gcry_ac_data_new (&data);
+ assert_err (err);
+
+ check_sexp_conversion (data, identifiers);
+ check_sexp_conversion (data, identifiers_null);
+ check_sexp_conversion (data, NULL);
+
+ err = gcry_ac_data_set (data, 0, label0, mpi0);
+ assert_err (err);
+ err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1);
+ assert_err (err);
+ assert (label0 == label1);
+ assert (mpi0 == mpi1);
+ check_sexp_conversion (data, identifiers);
+ check_sexp_conversion (data, identifiers_null);
+ check_sexp_conversion (data, NULL);
+
+ if (verbose)
+ printf ("data-set-test-0 succeeded\n");
+
+ gcry_ac_data_clear (data);
+
+ err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, label0, mpi0);
+ assert_err (err);
+
+ err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0);
+ assert_err (err);
+ err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0);
+ assert_err (err);
+ err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "bar", mpi0);
+ assert_err (err);
+ err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "blah1", mpi0);
+ assert_err (err);
+ check_sexp_conversion (data, identifiers);
+ check_sexp_conversion (data, identifiers_null);
+ check_sexp_conversion (data, NULL);
+
+ err = gcry_ac_data_get_name (data, 0, label0, &mpi1);
+ assert_err (err);
+ assert (mpi0 != mpi1);
+ err = gcry_ac_data_get_name (data, GCRY_AC_FLAG_COPY, label0, &mpi2);
+ assert_err (err);
+ assert (mpi0 != mpi1);
+ assert (mpi1 != mpi2);
+ err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1);
+ assert_err (err);
+ gcry_mpi_release (mpi0);
+ gcry_mpi_release (mpi2);
+
+ if (verbose)
+ printf ("data-set-test-1 succeeded\n");
+
+ gcry_ac_data_clear (data);
+ assert (! gcry_ac_data_length (data));
+ check_sexp_conversion (data, identifiers);
+ check_sexp_conversion (data, identifiers_null);
+ check_sexp_conversion (data, NULL);
+
+ if (verbose)
+ printf ("data-set-test-2 succeeded\n");
+
+ gcry_ac_data_destroy (data);
+
+
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+ int i = 1;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+
+ for (; i > 0; i--)
+ check_run ();
+
+ return 0;
+}
--- /dev/null
+/* ac-schemes.c - Tests for ES/SSA
+ Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "../src/gcrypt.h"
+
+static unsigned int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+typedef struct scheme_spec
+{
+ unsigned int idx;
+ gcry_ac_scheme_t scheme;
+ unsigned int flags;
+ const char *m;
+ size_t m_n;
+} scheme_spec_t;
+
+#define SCHEME_SPEC_FLAG_GET_OPTS (1 << 0)
+
+#define FILL(idx, scheme, flags, m) \
+ { idx, GCRY_AC_##scheme, flags, m, sizeof (m) }
+
+scheme_spec_t es_specs[] =
+ {
+ FILL (0, ES_PKCS_V1_5, 0, "foobar"),
+ FILL (1, ES_PKCS_V1_5, 0, "")
+ };
+
+scheme_spec_t ssa_specs[] =
+ {
+ FILL (0, SSA_PKCS_V1_5, SCHEME_SPEC_FLAG_GET_OPTS, "foobar")
+ };
+
+#undef FILL
+
+gcry_err_code_t
+scheme_get_opts (scheme_spec_t specs, void **opts)
+{
+ gcry_err_code_t err = GPG_ERR_NO_ERROR;
+ void *opts_new = NULL;
+
+ switch (specs.scheme)
+ {
+ case GCRY_AC_SSA_PKCS_V1_5:
+ {
+ gcry_ac_ssa_pkcs_v1_5_t *opts_pkcs_v1_5 = NULL;
+
+ opts_new = gcry_malloc (sizeof (gcry_ac_ssa_pkcs_v1_5_t));
+ if (! opts_new)
+ err = gpg_err_code_from_errno (ENOMEM);
+ else
+ {
+ opts_pkcs_v1_5 = (gcry_ac_ssa_pkcs_v1_5_t *) opts_new;
+
+ switch (specs.idx)
+ {
+ case 0:
+ opts_pkcs_v1_5->md = GCRY_MD_SHA1;
+ break;
+ case 1:
+ opts_pkcs_v1_5->md = GCRY_MD_MD5;
+ break;
+ }
+ }
+ }
+ case GCRY_AC_ES_PKCS_V1_5:
+ break;
+ }
+
+ if (! err)
+ *opts = opts_new;
+
+ return err;
+}
+
+gcry_error_t
+es_check (gcry_ac_handle_t handle, scheme_spec_t spec,
+ gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ char *c = NULL;
+ char *m2 = NULL;
+ size_t c_n = 0;
+ size_t m2_n = 0;
+ void *opts = NULL;
+ gcry_ac_io_t io_m;
+ gcry_ac_io_t io_c;
+ gcry_ac_io_t io_m2;
+
+ if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
+ err = scheme_get_opts (spec, &opts);
+ if (! err)
+ {
+ c = NULL;
+ m2 = NULL;
+
+ gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, spec.m, spec.m_n);
+ gcry_ac_io_init (&io_c, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &c, &c_n);
+
+ err = gcry_ac_data_encrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, opts, key_public,
+ &io_m, &io_c);
+ if (! err)
+ {
+ gcry_ac_io_init (&io_c, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, c, c_n);
+ gcry_ac_io_init (&io_m2, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &m2, &m2_n);
+
+ err = gcry_ac_data_decrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0,
+ opts, key_secret, &io_c, &io_m2);
+ }
+ if (! err)
+ assert ((spec.m_n == m2_n) && (! strncmp (spec.m, m2, spec.m_n)));
+
+ if (c)
+ gcry_free (c);
+ if (m2)
+ gcry_free (m2);
+ }
+
+ if (opts)
+ gcry_free (opts);
+
+ return err;
+}
+
+gcry_error_t
+ssa_check (gcry_ac_handle_t handle, scheme_spec_t spec,
+ gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned char *s = NULL;
+ size_t s_n = 0;
+ void *opts = NULL;
+ gcry_ac_io_t io_m;
+ gcry_ac_io_t io_s;
+
+ if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
+ err = scheme_get_opts (spec, &opts);
+ if (! err)
+ {
+ gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, spec.m, spec.m_n);
+ gcry_ac_io_init (&io_s, GCRY_AC_IO_WRITABLE,
+ GCRY_AC_IO_STRING, &s, &s_n);
+
+ err = gcry_ac_data_sign_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_secret,
+ &io_m, &io_s);
+ if (! err)
+ {
+ gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, spec.m, spec.m_n);
+ gcry_ac_io_init (&io_s, GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_STRING, s, s_n);
+ err = gcry_ac_data_verify_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_public,
+ &io_m, &io_s);
+ }
+ assert (! err);
+
+ if (s)
+ gcry_free (s);
+ }
+
+ if (opts)
+ gcry_free (opts);
+
+ return err;
+}
+
+void
+es_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; (i < (sizeof (es_specs) / sizeof (*es_specs))) && (! err); i++)
+ err = es_check (handle, es_specs[i], key_public, key_secret);
+
+ assert (! err);
+}
+
+void
+ssa_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int i = 0;
+
+ for (i = 0; (i < (sizeof (ssa_specs) / sizeof (*ssa_specs))) && (! err); i++)
+ err = ssa_check (handle, ssa_specs[i], key_public, key_secret);
+
+ assert (! err);
+}
+
+#define KEY_TYPE_PUBLIC (1 << 0)
+#define KEY_TYPE_SECRET (1 << 1)
+
+typedef struct key_spec
+{
+ const char *name;
+ unsigned int flags;
+ const char *mpi_string;
+} key_spec_t;
+
+key_spec_t key_specs[] =
+ {
+ { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
+ "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" },
+ { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
+ "010001" },
+ { "d", KEY_TYPE_SECRET,
+ "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" },
+ { "p", KEY_TYPE_SECRET,
+ "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" },
+ { "q", KEY_TYPE_SECRET,
+ "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" },
+ { "u", KEY_TYPE_SECRET,
+ "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" },
+ { NULL },
+ };
+
+gcry_error_t
+key_init (gcry_ac_key_type_t type, gcry_ac_key_t *key)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_ac_data_t key_data = NULL;
+ gcry_ac_key_t key_new = NULL;
+ gcry_mpi_t mpi = NULL;
+ unsigned int i = 0;
+
+ err = gcry_ac_data_new (&key_data);
+ for (i = 0; key_specs[i].name && (! err); i++)
+ {
+ if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC))
+ || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET)))
+ {
+ err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL);
+ if (! err)
+ {
+ gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
+ key_specs[i].name, mpi);
+ gcry_mpi_release (mpi);
+ }
+ }
+ }
+ if (! err)
+ err = gcry_ac_key_init (&key_new, NULL, type, key_data);
+
+ if (key_data)
+ gcry_ac_data_destroy (key_data);
+
+ if (! err)
+ *key = key_new;
+
+ return err;
+}
+
+static void
+check_run (void)
+{
+ gcry_ac_handle_t handle = NULL;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_ac_key_t key_public = NULL, key_secret = NULL;
+
+ err = key_init (GCRY_AC_KEY_PUBLIC, &key_public);
+ if (! err)
+ err = key_init (GCRY_AC_KEY_SECRET, &key_secret);
+
+ if (! err)
+ err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
+ if (! err)
+ {
+ es_checks (handle, key_public, key_secret);
+ ssa_checks (handle, key_public, key_secret);
+ }
+
+ assert (! err);
+}
+
+int
+main (int argc, char **argv)
+{
+ unsigned int debug = 0;
+
+ if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
+ verbose = 1;
+ else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
+ verbose = debug = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (! gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ check_run ();
+
+ return 0;
+}
--- /dev/null
+/* pubkey.c - Public key encryption/decryption tests
+ * Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+void
+key_copy (gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type,
+ gcry_ac_key_t *key_cp, gcry_ac_key_t key)
+{
+ gcry_error_t err = 0;
+
+ err = gcry_ac_key_init (key_cp, handle, type,
+ gcry_ac_key_data_get (key));
+
+ assert (! err);
+}
+
+void
+check_one (gcry_mpi_t x)
+{
+ gcry_ac_handle_t handle;
+ gcry_ac_key_pair_t key_pair;
+ gcry_ac_key_t key_sec, key_sec_cp, key_pub, key_pub_cp;
+ gcry_error_t err = 0;
+ gcry_mpi_t x2;
+ gcry_ac_data_t data, data2;
+ gcry_ac_key_spec_rsa_t rsa_spec;
+
+ rsa_spec.e = gcry_mpi_new (0);
+ gcry_mpi_set_ui (rsa_spec.e, 1);
+
+ err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
+ assert (! err);
+
+ err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec, &key_pair, NULL);
+ assert (! err);
+
+ key_sec = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_SECRET);
+ key_copy (handle, GCRY_AC_KEY_SECRET, &key_sec_cp, key_sec);
+
+ key_pub = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_PUBLIC);
+ key_copy (handle, GCRY_AC_KEY_PUBLIC, &key_pub_cp, key_pub);
+
+ err = gcry_ac_data_encrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_pub_cp, x, &data);
+ assert (! err);
+
+ err = gcry_ac_data_decrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_sec_cp, &x2, data);
+ assert (! err);
+
+ assert (! gcry_mpi_cmp (x, x2));
+
+ gcry_ac_data_destroy (data);
+
+ err = gcry_ac_data_sign (handle, key_sec, x, &data);
+ assert (! err);
+ err = gcry_ac_data_copy (&data2, data);
+ assert (! err);
+ gcry_ac_data_destroy (data);
+ err = gcry_ac_data_copy (&data, data2);
+ assert (! err);
+ gcry_ac_data_destroy (data2);
+
+ err = gcry_ac_data_verify (handle, key_pub, x, data);
+ assert (! err);
+
+ gcry_ac_data_destroy (data);
+
+ err = gcry_ac_data_sign (handle, key_sec, x, &data);
+ assert (! err);
+ {
+ const char *label;
+ gcry_mpi_t y;
+
+ err = gcry_ac_data_get_index (data, 0, 0, &label, &y);
+ assert (! err);
+ gcry_mpi_add_ui (y, y, 1);
+
+ err = gcry_ac_data_verify (handle, key_pub, x, data);
+ assert (gcry_err_code (err) == GPG_ERR_BAD_SIGNATURE);
+ }
+
+ gcry_ac_close (handle);
+}
+
+void
+check_run (void)
+{
+ /*const char *s = "All Hail Discordia."; -- not used */
+ unsigned int a = 0x4223;
+ gcry_mpi_t x;
+
+ x = gcry_mpi_new (0);
+ gcry_mpi_set_ui (x, a);
+ check_one (x);
+ gcry_mpi_release (x);
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+ int i = 1;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+ for (; i > 0; i--)
+ check_run ();
+
+ return 0;
+}
--- /dev/null
+/* aeswrap.c - AESWRAP mode regression tests
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+static int error_count;
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+
+static void
+check (int algo,
+ const void *kek, size_t keklen,
+ const void *data, size_t datalen,
+ const void *expected, size_t expectedlen)
+{
+ gcry_error_t err;
+ gcry_cipher_hd_t hd;
+ unsigned char outbuf[32+8];
+ size_t outbuflen;
+
+ err = gcry_cipher_open (&hd, algo, GCRY_CIPHER_MODE_AESWRAP, 0);
+ if (err)
+ {
+ fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, kek, keklen);
+ if (err)
+ {
+ fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ outbuflen = datalen + 8;
+ if (outbuflen > sizeof outbuf)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen);
+ if (err)
+ {
+ fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != expectedlen || memcmp (outbuf, expected, expectedlen))
+ {
+ const unsigned char *s;
+ int i;
+
+ fail ("mismatch at encryption!\n");
+ fprintf (stderr, "computed: ");
+ for (i = 0; i < outbuflen; i++)
+ fprintf (stderr, "%02x ", outbuf[i]);
+ fprintf (stderr, "\nexpected: ");
+ for (s = expected, i = 0; i < expectedlen; s++, i++)
+ fprintf (stderr, "%02x ", *s);
+ putc ('\n', stderr);
+ }
+
+
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ {
+ const unsigned char *s;
+ int i;
+
+ fail ("mismatch at decryption!\n");
+ fprintf (stderr, "computed: ");
+ for (i = 0; i < outbuflen; i++)
+ fprintf (stderr, "%02x ", outbuf[i]);
+ fprintf (stderr, "\nexpected: ");
+ for (s = data, i = 0; i < datalen; s++, i++)
+ fprintf (stderr, "%02x ", *s);
+ putc ('\n', stderr);
+ }
+
+ /* Now the last step again with a key reset. */
+ gcry_cipher_reset (hd);
+
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ fail ("mismatch at decryption(2)!\n");
+
+ /* And once ore without a key reset. */
+ outbuflen = expectedlen - 8;
+ if (outbuflen > sizeof outbuf)
+ err = gpg_error (GPG_ERR_INTERNAL);
+ else
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen);
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ if (outbuflen != datalen || memcmp (outbuf, data, datalen))
+ fail ("mismatch at decryption(3)!\n");
+
+ gcry_cipher_close (hd);
+}
+
+
+static void
+check_all (void)
+{
+ if (verbose)
+ fprintf (stderr, "4.1 Wrap 128 bits of Key Data with a 128-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES128,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82"
+ "\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.2 Wrap 128 bits of Key Data with a 192-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES192,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17", 24,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x96\x77\x8B\x25\xAE\x6C\xA4\x35\xF9\x2B\x5B\x97\xC0\x50\xAE\xD2"
+ "\x46\x8A\xB8\xA1\x7A\xD8\x4E\x5D", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.3 Wrap 128 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES256,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16,
+ "\x64\xE8\xC3\xF9\xCE\x0F\x5B\xA2\x63\xE9\x77\x79\x05\x81\x8A\x2A"
+ "\x93\xC8\x19\x1E\x7D\x6E\x8A\xE7", 24);
+
+ if (verbose)
+ fprintf (stderr, "4.4 Wrap 192 bits of Key Data with a 192-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES192,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17", 24,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07", 24,
+ "\x03\x1D\x33\x26\x4E\x15\xD3\x32\x68\xF2\x4E\xC2\x60\x74\x3E\xDC"
+ "\xE1\xC6\xC7\xDD\xEE\x72\x5A\x93\x6B\xA8\x14\x91\x5C\x67\x62\xD2", 32);
+
+ if (verbose)
+ fprintf (stderr, "4.5 Wrap 192 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES256,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07", 24,
+ "\xA8\xF9\xBC\x16\x12\xC6\x8B\x3F\xF6\xE6\xF4\xFB\xE3\x0E\x71\xE4"
+ "\x76\x9C\x8B\x80\xA3\x2C\xB8\x95\x8C\xD5\xD1\x7D\x6B\x25\x4D\xA1", 32);
+
+ if (verbose)
+ fprintf (stderr, "4.6 Wrap 256 bits of Key Data with a 256-bit KEK\n");
+ check
+ (GCRY_CIPHER_AES,
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32,
+ "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 32,
+ "\x28\xC9\xF4\x04\xC4\xB8\x10\xF4\xCB\xCC\xB3\x5C\xFB\x87\xF8\x26"
+ "\x3F\x57\x86\xE2\xD8\x0E\xD3\x26\xCB\xC7\xF0\xE7\x1A\x99\xF4\x3B"
+ "\xFB\x98\x8B\x9B\x7A\x02\xDD\x21", 40);
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ check_all ();
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* basic.c - basic regression tests
+ * Copyright (C) 2001, 2002, 2003, 2005, 2008,
+ * 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+#ifndef DIM
+# define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#endif
+
+
+typedef struct test_spec_pubkey_key
+{
+ const char *secret;
+ const char *public;
+ const char *grip;
+}
+test_spec_pubkey_key_t;
+
+typedef struct test_spec_pubkey
+{
+ int id;
+ int flags;
+ test_spec_pubkey_key_t key;
+}
+test_spec_pubkey_t;
+
+#define FLAG_CRYPT (1 << 0)
+#define FLAG_SIGN (1 << 1)
+#define FLAG_GRIP (1 << 2)
+
+static int verbose;
+static int error_count;
+static int in_fips_mode;
+static int die_on_error;
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+ if (die_on_error)
+ exit (1);
+}
+
+static void
+mismatch (const void *expected, size_t expectedlen,
+ const void *computed, size_t computedlen)
+{
+ const unsigned char *p;
+
+ fprintf (stderr, "expected:");
+ for (p = expected; expectedlen; p++, expectedlen--)
+ fprintf (stderr, " %02x", *p);
+ fprintf (stderr, "\ncomputed:");
+ for (p = computed; computedlen; p++, computedlen--)
+ fprintf (stderr, " %02x", *p);
+ fprintf (stderr, "\n");
+}
+
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+#define MAX_DATA_LEN 100
+
+void
+progress_handler (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+ (void)what;
+ (void)current;
+ (void)total;
+
+ if (printchar == '\n')
+ fputs ( "<LF>", stdout);
+ else
+ putchar (printchar);
+ fflush (stdout);
+}
+
+static void
+check_cbc_mac_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ unsigned char plaintext[MAX_DATA_LEN];
+ size_t plaintextlen;
+ char mac[MAX_DATA_LEN];
+ }
+ tv[] =
+ {
+ { GCRY_CIPHER_AES,
+ "chicken teriyaki",
+ "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
+ 0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" },
+ { GCRY_CIPHER_3DES,
+ "abcdefghABCDEFGH01234567",
+ "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
+ 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
+ { GCRY_CIPHER_DES,
+ "abcdefgh",
+ "This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
+ 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
+ };
+ gcry_cipher_hd_t hd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, blklen, keylen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CBC MAC checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ tv[i].algo);
+ continue;
+ }
+
+ err = gcry_cipher_open (&hd,
+ tv[i].algo,
+ GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
+ if (!hd)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_open failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n",
+ tv[i].algo);
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen (tv[i].algo);
+ if (!keylen)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n",
+ tv[i].algo);
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking CBC MAC for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_encrypt (hd,
+ out, blklen,
+ tv[i].plaintext,
+ tv[i].plaintextlen ?
+ tv[i].plaintextlen :
+ strlen ((char*)tv[i].plaintext));
+ if (err)
+ {
+ fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
+ tv[i].algo, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+#if 0
+ {
+ int j;
+ for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++)
+ printf ("\\x%02x", out[j] & 0xFF);
+ printf ("\n");
+ }
+#endif
+
+ if (memcmp (tv[i].mac, out, blklen))
+ fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);
+
+ gcry_cipher_close (hd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed CBC MAC checks.\n");
+}
+
+static void
+check_aes128_cbc_cts_cipher (void)
+{
+ char key[128 / 8] = "chicken teriyaki";
+ unsigned char plaintext[] =
+ "I would like the General Gau's Chicken, please, and wonton soup.";
+ struct tv
+ {
+ unsigned char out[MAX_DATA_LEN];
+ int inlen;
+ } tv[] =
+ {
+ { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
+ "\x97",
+ 17 },
+ { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
+ 31 },
+ { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
+ 32 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
+ 47 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
+ 48 },
+ { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
+ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
+ "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
+ "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
+ 64 },
+ };
+ gcry_cipher_hd_t hd;
+ unsigned char out[MAX_DATA_LEN];
+ int i;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting AES128 CBC CTS checks.\n");
+ err = gcry_cipher_open (&hd,
+ GCRY_CIPHER_AES,
+ GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, key, 128 / 8);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking encryption for length %i\n", tv[i].inlen);
+ err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN,
+ plaintext, tv[i].inlen);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (tv[i].out, out, tv[i].inlen))
+ fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i);
+
+ err = gcry_cipher_setiv (hd, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+ if (verbose)
+ fprintf (stderr, " checking decryption for length %i\n", tv[i].inlen);
+ err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (plaintext, out, tv[i].inlen))
+ fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i);
+ }
+
+ gcry_cipher_close (hd);
+ if (verbose)
+ fprintf (stderr, " Completed AES128 CBC CTS checks.\n");
+}
+
+static void
+check_ctr_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char ctr[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ } data[8];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
+
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" },
+ { "", 0, "" }
+ }
+ },
+ /* Some truncation tests. With a truncated second block and
+ also with a single truncated block. */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae",
+ 1,
+ "\x98" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17",
+ 15,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6" },
+ {"", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b",
+ 1,
+ "\x87" },
+ {"", 0, "" }
+ }
+ },
+ /* Tests to see whether it works correctly as a stream cipher. */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 17,
+ "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
+ {"\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
+
+ { "", 0, "" }
+ }
+ },
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ {{"\x6b",
+ 1,
+ "\x87" },
+ {"\xc1\xbe",
+ 2,
+ "\x4d\x61" },
+ {"\xe2\x2e\x40",
+ 3,
+ "\x91\xb6\x20" },
+ {"\x9f",
+ 1,
+ "\xe3" },
+ {"\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 9,
+ "\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e",
+ 15,
+ "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" },
+ {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+ 9,
+ "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e" },
+
+ { "", 0, "" }
+ }
+ },
+#if USE_CAST5
+ /* A selfmade test vector using an 64 bit block cipher. */
+ { GCRY_CIPHER_CAST5,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8",
+ {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xe8\xa7\xac\x68\xca\xca\xa0\x20\x10\xcb\x1b\xcc\x79\x2c\xc4\x48" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c",
+ 8,
+ "\x16\xe8\x72\x77\xb0\x98\x29\x68" },
+ {"\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 8,
+ "\x9a\xb3\xa8\x03\x3b\xb4\x14\xba" },
+ {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\xa1\x00",
+ 10,
+ "\x31\x5e\xd3\xfb\x1b\x8d\xd1\xf9\xb0\x83" },
+ { "", 0, "" }
+ }
+ },
+#endif /*USE_CAST5*/
+ { 0,
+ "",
+ "",
+ {
+ {"", 0, "" }
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CTR cipher checks.\n");
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (!tv[i].algo)
+ continue;
+
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setctr (hde, tv[i].ctr, blklen);
+ if (!err)
+ err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (verbose)
+ fprintf (stderr, " checking CTR mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen == -1 ?
+ strlen ((char*)tv[i].data[j].plaintext) :
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ {
+ fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j);
+ mismatch (tv[i].data[j].out, tv[i].data[j].inlen,
+ out, tv[i].data[j].inlen);
+ }
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ {
+ fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j);
+ mismatch (tv[i].data[j].plaintext, tv[i].data[j].inlen,
+ out, tv[i].data[j].inlen);
+ }
+
+ }
+
+ /* Now check that we get valid return codes back for good and
+ bad inputs. */
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ "1234567890123456", 16);
+ if (err)
+ fail ("aes-ctr, encryption failed for valid input");
+
+ err = gcry_cipher_encrypt (hde, out, 15,
+ "1234567890123456", 16);
+ if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT)
+ fail ("aes-ctr, too short output buffer returned wrong error: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_cipher_encrypt (hde, out, 0,
+ "1234567890123456", 16);
+ if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT)
+ fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_cipher_encrypt (hde, out, 16,
+ "1234567890123456", 16);
+ if (err)
+ fail ("aes-ctr, correct length output buffer returned error: %s\n",
+ gpg_strerror (err));
+
+ /* Again, now for decryption. */
+ err = gcry_cipher_decrypt (hde, out, MAX_DATA_LEN,
+ "1234567890123456", 16);
+ if (err)
+ fail ("aes-ctr, decryption failed for valid input");
+
+ err = gcry_cipher_decrypt (hde, out, 15,
+ "1234567890123456", 16);
+ if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT)
+ fail ("aes-ctr, too short output buffer returned wrong error: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_cipher_decrypt (hde, out, 0,
+ "1234567890123456", 16);
+ if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT)
+ fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_cipher_decrypt (hde, out, 16,
+ "1234567890123456", 16);
+ if (err)
+ fail ("aes-ctr, correct length output buffer returned error: %s\n",
+ gpg_strerror (err));
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed CTR cipher checks.\n");
+}
+
+static void
+check_cfb_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"},
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" },
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" },
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" }
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting CFB checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (verbose)
+ fprintf (stderr, " checking CFB mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-cfb, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-cfb, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) {
+ fail ("aes-cfb, encrypt mismatch entry %d:%d\n", i, j);
+ }
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-cfb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed CFB checks.\n");
+}
+
+static void
+check_ofb_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"},
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" },
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" },
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" }
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, " Starting OFB checks.\n");
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ if (verbose)
+ fprintf (stderr, " checking OFB mode for %s [%i]\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo);
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we encrypt and decrypt one byte at a time */
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ int byteNum;
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].data[j].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+ if (verbose)
+ fprintf (stderr, " Completed OFB checks.\n");
+}
+
+
+/* Check that our bulk encryption fucntions work properly. */
+static void
+check_bulk_cipher_modes (void)
+{
+ struct
+ {
+ int algo;
+ int mode;
+ const char *key;
+ int keylen;
+ const char *iv;
+ int ivlen;
+ char t1_hash[20];
+ } tv[] = {
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[0]*/
+ { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63,
+ 0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[1]*/
+ { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9,
+ 0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[2]*/
+ { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb,
+ 0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[3]*/
+ { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4,
+ 0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[4]*/
+ { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1,
+ 0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[5]*/
+ { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02,
+ 0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[6]*/
+ { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b,
+ 0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[7]*/
+ { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa,
+ 0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[8]*/
+ { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce,
+ 0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[9]*/
+ { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34,
+ 0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[10]*/
+ { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08,
+ 0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[11]*/
+ { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce,
+ 0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 }
+ },
+ { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnop", 16,
+ "1234567890123456", 16,
+/*[12]*/
+ { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa,
+ 0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 }
+ },
+ { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnopABCDEFG", 24,
+ "1234567890123456", 16,
+/*[13]*/
+ { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33,
+ 0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 }
+ },
+ { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB,
+ "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+ "1234567890123456", 16,
+/*[14]*/
+ { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5,
+ 0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f }
+ }
+ };
+ gcry_cipher_hd_t hde = NULL;
+ gcry_cipher_hd_t hdd = NULL;
+ unsigned char *buffer_base, *outbuf_base; /* Allocated buffers. */
+ unsigned char *buffer, *outbuf; /* Aligned buffers. */
+ size_t buflen;
+ unsigned char hash[20];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ if (verbose)
+ fprintf (stderr, "Starting bulk cipher checks.\n");
+
+ buflen = 16*100; /* We check a 1600 byte buffer. */
+ buffer_base = gcry_xmalloc (buflen+15);
+ buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f));
+ outbuf_base = gcry_xmalloc (buflen+15);
+ outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f));
+
+
+ for (i = 0; i < DIM (tv); i++)
+ {
+ if (verbose)
+ fprintf (stderr, " checking bulk encryption for %s [%i], mode %d\n",
+ gcry_cipher_algo_name (tv[i].algo),
+ tv[i].algo, tv[i].mode);
+ err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0);
+ if (err)
+ {
+ fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("gcry_cipher_get_algo_keylen failed\n");
+ goto leave;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+ if (err)
+ {
+ fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("gcry_cipher_get_algo_blklen failed\n");
+ goto leave;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
+ if (err)
+ {
+ fail ("gcry_cipher_setiv failed: %s\n", gpg_strerror (err));
+ goto leave;
+ }
+
+ /* Fill the buffer with our test pattern. */
+ for (j=0; j < buflen; j++)
+ buffer[j] = ((j & 0xff) ^ ((j >> 8) & 0xff));
+
+ err = gcry_cipher_encrypt (hde, outbuf, buflen, buffer, buflen);
+ if (err)
+ {
+ fail ("gcry_cipher_encrypt (algo %d, mode %d) failed: %s\n",
+ tv[i].algo, tv[i].mode, gpg_strerror (err));
+ goto leave;
+ }
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, outbuf, buflen);
+#if 0
+ printf ("/*[%d]*/\n", i);
+ fputs (" {", stdout);
+ for (j=0; j < 20; j++)
+ printf (" 0x%02x%c%s", hash[j], j==19? ' ':',', j == 9? "\n ":"");
+ puts ("}");
+#endif
+
+ if (memcmp (hash, tv[i].t1_hash, 20))
+ fail ("encrypt mismatch (algo %d, mode %d)\n",
+ tv[i].algo, tv[i].mode);
+
+ err = gcry_cipher_decrypt (hdd, outbuf, buflen, NULL, 0);
+ if (err)
+ {
+ fail ("gcry_cipher_decrypt (algo %d, mode %d) failed: %s\n",
+ tv[i].algo, tv[i].mode, gpg_strerror (err));
+ goto leave;
+ }
+
+ if (memcmp (buffer, outbuf, buflen))
+ fail ("decrypt mismatch (algo %d, mode %d)\n",
+ tv[i].algo, tv[i].mode);
+
+ gcry_cipher_close (hde); hde = NULL;
+ gcry_cipher_close (hdd); hdd = NULL;
+ }
+
+ if (verbose)
+ fprintf (stderr, "Completed bulk cipher checks.\n");
+ leave:
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ gcry_free (buffer_base);
+ gcry_free (outbuf_base);
+}
+
+
+
+static void
+check_one_cipher (int algo, int mode, int flags)
+{
+ gcry_cipher_hd_t hd;
+ char key[32];
+ unsigned char plain[16], in[16], out[16];
+ int keylen;
+ gcry_error_t err = 0;
+
+ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
+ memcpy (plain, "foobar42FOOBAR17", 16);
+
+ keylen = gcry_cipher_get_algo_keylen (algo);
+ if (!keylen)
+ {
+ fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
+ algo, mode);
+ return;
+ }
+
+ if (keylen < 40 / 8 || keylen > 32)
+ {
+ fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen);
+ return;
+ }
+
+ err = gcry_cipher_open (&hd, algo, mode, flags);
+ if (err)
+ {
+ fail ("algo %d, mode %d, gcry_cipher_open failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ return;
+ }
+
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ err = gcry_cipher_encrypt (hd, out, 16, plain, 16);
+ if (err)
+ {
+ fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ gcry_cipher_reset (hd);
+
+ err = gcry_cipher_decrypt (hd, in, 16, out, 16);
+ if (err)
+ {
+ fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (plain, in, 16))
+ fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
+
+ /* Again, using in-place encryption. */
+ gcry_cipher_reset (hd);
+
+ memcpy (out, plain, 16);
+ err = gcry_cipher_encrypt (hd, out, 16, NULL, 0);
+ if (err)
+ {
+ fail ("algo %d, mode %d, in-place, gcry_cipher_encrypt failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ gcry_cipher_reset (hd);
+
+ err = gcry_cipher_decrypt (hd, out, 16, NULL, 0);
+ if (err)
+ {
+ fail ("algo %d, mode %d, in-place, gcry_cipher_decrypt failed: %s\n",
+ algo, mode, gpg_strerror (err));
+ gcry_cipher_close (hd);
+ return;
+ }
+
+ if (memcmp (plain, out, 16))
+ fail ("algo %d, mode %d, in-place, encrypt-decrypt mismatch\n",algo, mode);
+
+
+ gcry_cipher_close (hd);
+
+}
+
+
+static void
+check_ciphers (void)
+{
+ static int algos[] = {
+#if USE_BLOWFISH
+ GCRY_CIPHER_BLOWFISH,
+#endif
+#if USE_DES
+ GCRY_CIPHER_DES,
+ GCRY_CIPHER_3DES,
+#endif
+#if USE_CAST5
+ GCRY_CIPHER_CAST5,
+#endif
+#if USE_AES
+ GCRY_CIPHER_AES,
+ GCRY_CIPHER_AES192,
+ GCRY_CIPHER_AES256,
+#endif
+#if USE_TWOFISH
+ GCRY_CIPHER_TWOFISH,
+ GCRY_CIPHER_TWOFISH128,
+#endif
+#if USE_SERPENT
+ GCRY_CIPHER_SERPENT128,
+ GCRY_CIPHER_SERPENT192,
+ GCRY_CIPHER_SERPENT256,
+#endif
+#if USE_RFC2268
+ GCRY_CIPHER_RFC2268_40,
+#endif
+#if USE_SEED
+ GCRY_CIPHER_SEED,
+#endif
+#if USE_CAMELLIA
+ GCRY_CIPHER_CAMELLIA128,
+ GCRY_CIPHER_CAMELLIA192,
+ GCRY_CIPHER_CAMELLIA256,
+#endif
+ 0
+ };
+ static int algos2[] = {
+#if USE_ARCFOUR
+ GCRY_CIPHER_ARCFOUR,
+#endif
+ 0
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting Cipher checks.\n");
+ for (i = 0; algos[i]; i++)
+ {
+ if (gcry_cipher_test_algo (algos[i]) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i]);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking %s [%i]\n",
+ gcry_cipher_algo_name (algos[i]),
+ gcry_cipher_map_name (gcry_cipher_algo_name (algos[i])));
+
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
+ }
+
+ for (i = 0; algos2[i]; i++)
+ {
+ if (gcry_cipher_test_algo (algos[i]) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i]);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking `%s'\n",
+ gcry_cipher_algo_name (algos2[i]));
+
+ check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
+ }
+ /* we have now run all cipher's selftests */
+
+ if (verbose)
+ fprintf (stderr, "Completed Cipher checks.\n");
+
+ /* TODO: add some extra encryption to test the higher level functions */
+}
+
+
+static void
+check_cipher_modes(void)
+{
+ if (verbose)
+ fprintf (stderr, "Starting Cipher Mode checks.\n");
+
+ check_aes128_cbc_cts_cipher ();
+ check_cbc_mac_cipher ();
+ check_ctr_cipher ();
+ check_cfb_cipher ();
+ check_ofb_cipher ();
+
+ if (verbose)
+ fprintf (stderr, "Completed Cipher Mode checks.\n");
+}
+
+static void
+check_one_md (int algo, const char *data, int len, const char *expect)
+{
+ gcry_md_hd_t hd, hd2;
+ unsigned char *p;
+ int mdlen;
+ int i;
+ gcry_error_t err = 0;
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ mdlen = gcry_md_get_algo_dlen (algo);
+ if (mdlen < 1 || mdlen > 500)
+ {
+ fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
+ return;
+ }
+
+ if (*data == '!' && !data[1])
+ { /* hash one million times a "a" */
+ char aaa[1000];
+
+ /* Write in odd size chunks so that we test the buffering. */
+ memset (aaa, 'a', 1000);
+ for (i = 0; i < 1000; i++)
+ gcry_md_write (hd, aaa, 1000);
+ }
+ else
+ gcry_md_write (hd, data, len);
+
+ err = gcry_md_copy (&hd2, hd);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
+ }
+
+ gcry_md_close (hd);
+
+ p = gcry_md_read (hd2, algo);
+
+ if (memcmp (p, expect, mdlen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", p[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, digest mismatch\n", algo);
+ }
+
+ gcry_md_close (hd2);
+}
+
+
+static void
+check_digests (void)
+{
+ static struct algos
+ {
+ int md;
+ const char *data;
+ const char *expect;
+ } algos[] =
+ {
+ { GCRY_MD_MD4, "",
+ "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" },
+ { GCRY_MD_MD4, "a",
+ "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" },
+ { GCRY_MD_MD4, "message digest",
+ "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" },
+ { GCRY_MD_MD5, "",
+ "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" },
+ { GCRY_MD_MD5, "a",
+ "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" },
+ { GCRY_MD_MD5, "abc",
+ "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" },
+ { GCRY_MD_MD5, "message digest",
+ "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" },
+ { GCRY_MD_SHA1, "abc",
+ "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
+ "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" },
+ { GCRY_MD_SHA1,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
+ "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" },
+ { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ ,
+ "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
+ "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" },
+ /* From RFC3874 */
+ { GCRY_MD_SHA224, "abc",
+ "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3"
+ "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7" },
+ { GCRY_MD_SHA224,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50"
+ "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25" },
+ { GCRY_MD_SHA224, "!",
+ "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b"
+ "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" },
+ { GCRY_MD_SHA256, "abc",
+ "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
+ "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
+ { GCRY_MD_SHA256,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
+ "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
+ { GCRY_MD_SHA256, "!",
+ "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
+ "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" },
+ { GCRY_MD_SHA384, "abc",
+ "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
+ "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
+ "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" },
+ { GCRY_MD_SHA512, "abc",
+ "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
+ "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
+ "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
+ "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" },
+ { GCRY_MD_RMD160, "",
+ "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
+ "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" },
+ { GCRY_MD_RMD160, "a",
+ "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
+ "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" },
+ { GCRY_MD_RMD160, "abc",
+ "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
+ "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" },
+ { GCRY_MD_RMD160, "message digest",
+ "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
+ "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" },
+ { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" },
+ { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" },
+ { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" },
+ { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" },
+ { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" },
+ { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY",
+ "\xe3\x41\x80\xf7" },
+#if 0
+ { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" },
+ { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" },
+ { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" },
+#endif
+ { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" },
+#if 0
+ { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" },
+ { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" },
+#endif
+ { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" },
+ { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" },
+
+ { GCRY_MD_TIGER, "",
+ "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76"
+ "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" },
+ { GCRY_MD_TIGER, "abc",
+ "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41"
+ "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" },
+ { GCRY_MD_TIGER, "Tiger",
+ "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38"
+ "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" },
+ { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"
+ "hijklmnopqrstuvwxyz0123456789+-",
+ "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8"
+ "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" },
+ { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef"
+ "ghijklmnopqrstuvwxyz+0123456789",
+ "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12"
+ "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" },
+ { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham",
+ "\x0C\x41\x0A\x04\x29\x68\x86\x8A\x16\x71\xDA\x5A"
+ "\x3F\xD2\x9A\x72\x5E\xC1\xE4\x57\xD3\xCD\xB3\x03" },
+ { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham, proceedings of Fa"
+ "st Software Encryption 3, Cambridge.",
+ "\xEB\xF5\x91\xD5\xAF\xA6\x55\xCE\x7F\x22\x89\x4F"
+ "\xF8\x7F\x54\xAC\x89\xC8\x11\xB6\xB0\xDA\x31\x93" },
+ { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
+ "by Ross Anderson and Eli Biham, proceedings of Fa"
+ "st Software Encryption 3, Cambridge, 1996.",
+ "\x3D\x9A\xEB\x03\xD1\xBD\x1A\x63\x57\xB2\x77\x4D"
+ "\xFD\x6D\x5B\x24\xDD\x68\x15\x1D\x50\x39\x74\xFC" },
+ { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh"
+ "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS"
+ "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
+ "\x00\xB8\x3E\xB4\xE5\x34\x40\xC5\x76\xAC\x6A\xAE"
+ "\xE0\xA7\x48\x58\x25\xFD\x15\xE7\x0A\x59\xFF\xE4" },
+
+ { GCRY_MD_TIGER1, "",
+ "\x32\x93\xAC\x63\x0C\x13\xF0\x24\x5F\x92\xBB\xB1"
+ "\x76\x6E\x16\x16\x7A\x4E\x58\x49\x2D\xDE\x73\xF3" },
+ { GCRY_MD_TIGER1, "a",
+ "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B"
+ "\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09" },
+ { GCRY_MD_TIGER1, "abc",
+ "\x2A\xAB\x14\x84\xE8\xC1\x58\xF2\xBF\xB8\xC5\xFF"
+ "\x41\xB5\x7A\x52\x51\x29\x13\x1C\x95\x7B\x5F\x93" },
+ { GCRY_MD_TIGER1, "message digest",
+ "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48"
+ "\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6" },
+ { GCRY_MD_TIGER1, "abcdefghijklmnopqrstuvwxyz",
+ "\x17\x14\xA4\x72\xEE\xE5\x7D\x30\x04\x04\x12\xBF"
+ "\xCC\x55\x03\x2A\x0B\x11\x60\x2F\xF3\x7B\xEE\xE9" },
+ { GCRY_MD_TIGER1,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\x0F\x7B\xF9\xA1\x9B\x9C\x58\xF2\xB7\x61\x0D\xF7"
+ "\xE8\x4F\x0A\xC3\xA7\x1C\x63\x1E\x7B\x53\xF7\x8E" },
+ { GCRY_MD_TIGER1,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz" "0123456789",
+ "\x8D\xCE\xA6\x80\xA1\x75\x83\xEE\x50\x2B\xA3\x8A"
+ "\x3C\x36\x86\x51\x89\x0F\xFB\xCC\xDC\x49\xA8\xCC" },
+ { GCRY_MD_TIGER1,
+ "1234567890" "1234567890" "1234567890" "1234567890"
+ "1234567890" "1234567890" "1234567890" "1234567890",
+ "\x1C\x14\x79\x55\x29\xFD\x9F\x20\x7A\x95\x8F\x84"
+ "\xC5\x2F\x11\xE8\x87\xFA\x0C\xAB\xDF\xD9\x1B\xFD" },
+ { GCRY_MD_TIGER1, "!",
+ "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7"
+ "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" },
+
+ { GCRY_MD_TIGER2, "",
+ "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27"
+ "\x45\x37\x4B\x92\x4A\xA8\x31\x3F\xEF\x91\x9F\x41" },
+ { GCRY_MD_TIGER2, "a",
+ "\x67\xE6\xAE\x8E\x9E\x96\x89\x99\xF7\x0A\x23\xE7"
+ "\x2A\xEA\xA9\x25\x1C\xBC\x7C\x78\xA7\x91\x66\x36" },
+ { GCRY_MD_TIGER2, "abc",
+ "\xF6\x8D\x7B\xC5\xAF\x4B\x43\xA0\x6E\x04\x8D\x78"
+ "\x29\x56\x0D\x4A\x94\x15\x65\x8B\xB0\xB1\xF3\xBF" },
+ { GCRY_MD_TIGER2, "message digest",
+ "\xE2\x94\x19\xA1\xB5\xFA\x25\x9D\xE8\x00\x5E\x7D"
+ "\xE7\x50\x78\xEA\x81\xA5\x42\xEF\x25\x52\x46\x2D" },
+ { GCRY_MD_TIGER2, "abcdefghijklmnopqrstuvwxyz",
+ "\xF5\xB6\xB6\xA7\x8C\x40\x5C\x85\x47\xE9\x1C\xD8"
+ "\x62\x4C\xB8\xBE\x83\xFC\x80\x4A\x47\x44\x88\xFD" },
+ { GCRY_MD_TIGER2,
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
+ "\xA6\x73\x7F\x39\x97\xE8\xFB\xB6\x3D\x20\xD2\xDF"
+ "\x88\xF8\x63\x76\xB5\xFE\x2D\x5C\xE3\x66\x46\xA9" },
+ { GCRY_MD_TIGER2,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz" "0123456789",
+ "\xEA\x9A\xB6\x22\x8C\xEE\x7B\x51\xB7\x75\x44\xFC"
+ "\xA6\x06\x6C\x8C\xBB\x5B\xBA\xE6\x31\x95\x05\xCD" },
+ { GCRY_MD_TIGER2,
+ "1234567890" "1234567890" "1234567890" "1234567890"
+ "1234567890" "1234567890" "1234567890" "1234567890",
+ "\xD8\x52\x78\x11\x53\x29\xEB\xAA\x0E\xEC\x85\xEC"
+ "\xDC\x53\x96\xFD\xA8\xAA\x3A\x58\x20\x94\x2F\xFF" },
+ { GCRY_MD_TIGER2, "!",
+ "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15"
+ "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" },
+
+ { GCRY_MD_WHIRLPOOL, "",
+ "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
+ "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
+ "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
+ "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" },
+ { GCRY_MD_WHIRLPOOL, "a",
+ "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+ "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+ "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
+ "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
+ { GCRY_MD_WHIRLPOOL, "a",
+ "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
+ "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
+ "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
+ "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
+ { GCRY_MD_WHIRLPOOL,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+ "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
+ "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
+ "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
+ "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" },
+ { GCRY_MD_WHIRLPOOL,
+ "!",
+ "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D"
+ "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5"
+ "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD"
+ "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" },
+ { 0 },
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting hash checks.\n");
+
+ for (i = 0; algos[i].md; i++)
+ {
+ if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
+ && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i].md);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr, " checking %s [%i] for length %zi\n",
+ gcry_md_algo_name (algos[i].md),
+ algos[i].md,
+ !strcmp (algos[i].data, "!")?
+ 1000000 : strlen(algos[i].data));
+
+ check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data),
+ algos[i].expect);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Completed hash checks.\n");
+}
+
+static void
+check_one_hmac (int algo, const char *data, int datalen,
+ const char *key, int keylen, const char *expect)
+{
+ gcry_md_hd_t hd, hd2;
+ unsigned char *p;
+ int mdlen;
+ int i;
+ gcry_error_t err = 0;
+
+ err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ mdlen = gcry_md_get_algo_dlen (algo);
+ if (mdlen < 1 || mdlen > 500)
+ {
+ fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
+ return;
+ }
+
+ gcry_md_setkey( hd, key, keylen );
+
+ gcry_md_write (hd, data, datalen);
+
+ err = gcry_md_copy (&hd2, hd);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
+ }
+
+ gcry_md_close (hd);
+
+ p = gcry_md_read (hd2, algo);
+ if (!p)
+ fail("algo %d, hmac gcry_md_read failed\n", algo);
+
+ if (memcmp (p, expect, mdlen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", p[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, digest mismatch\n", algo);
+ }
+
+ gcry_md_close (hd2);
+}
+
+static void
+check_hmac (void)
+{
+ static struct algos
+ {
+ int md;
+ const char *data;
+ const char *key;
+ const char *expect;
+ } algos[] =
+ {
+ { GCRY_MD_MD5, "what do ya want for nothing?", "Jefe",
+ "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" },
+ { GCRY_MD_MD5,
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+ "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" },
+ { GCRY_MD_MD5,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd",
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
+ "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" },
+ { GCRY_MD_MD5,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" },
+ { GCRY_MD_MD5, "Test With Truncation",
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+ "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" },
+ { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa",
+ "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" },
+ { GCRY_MD_MD5,
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa",
+ "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", },
+ { GCRY_MD_SHA256, "what do ya want for nothing?", "Jefe",
+ "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a"
+ "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" },
+ { GCRY_MD_SHA256,
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b",
+ "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88"
+ "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" },
+ { GCRY_MD_SHA256,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd",
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA",
+ "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7"
+ "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" },
+ { GCRY_MD_SHA256,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08"
+ "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" },
+ { GCRY_MD_SHA256,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f"
+ "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" },
+ { GCRY_MD_SHA256,
+ "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44"
+ "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" },
+ { GCRY_MD_SHA224, "what do ya want for nothing?", "Jefe",
+ "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
+ "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" },
+ { GCRY_MD_SHA224,
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b",
+ "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47"
+ "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" },
+ { GCRY_MD_SHA224,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd",
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA",
+ "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64"
+ "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" },
+ { GCRY_MD_SHA224,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62"
+ "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" },
+ { GCRY_MD_SHA224,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
+ "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" },
+ { GCRY_MD_SHA224,
+ "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
+ "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" },
+ { GCRY_MD_SHA384, "what do ya want for nothing?", "Jefe",
+ "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+ "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+ "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" },
+ { GCRY_MD_SHA384,
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b",
+ "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15"
+ "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea"
+ "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" },
+ { GCRY_MD_SHA384,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd",
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA",
+ "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f"
+ "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b"
+ "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" },
+ { GCRY_MD_SHA384,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7"
+ "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e"
+ "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" },
+ { GCRY_MD_SHA384,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+ "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+ "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" },
+ { GCRY_MD_SHA384,
+ "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+ "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+ "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" },
+ { GCRY_MD_SHA512, "what do ya want for nothing?", "Jefe",
+ "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+ "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54"
+ "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+ "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" },
+ { GCRY_MD_SHA512,
+ "Hi There",
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b",
+ "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+ "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+ "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+ "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" },
+ { GCRY_MD_SHA512,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd",
+ "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA",
+ "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9"
+ "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39"
+ "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07"
+ "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb" },
+ { GCRY_MD_SHA512,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd",
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19",
+ "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7"
+ "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb"
+ "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63"
+ "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" },
+ { GCRY_MD_SHA512,
+ "Test Using Larger Than Block-Size Key - Hash Key First",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+ "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+ "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+ "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" },
+ { GCRY_MD_SHA512,
+ "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa",
+ "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+ "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44"
+ "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15"
+ "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" },
+ { 0 },
+ };
+ int i;
+
+ if (verbose)
+ fprintf (stderr, "Starting hashed MAC checks.\n");
+
+ for (i = 0; algos[i].md; i++)
+ {
+ if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
+ && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ algos[i].md);
+ continue;
+ }
+ if (verbose)
+ fprintf (stderr,
+ " checking %s [%i] for %zi byte key and %zi byte data\n",
+ gcry_md_algo_name (algos[i].md),
+ algos[i].md,
+ strlen(algos[i].key), strlen(algos[i].data));
+
+ check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data),
+ algos[i].key, strlen(algos[i].key),
+ algos[i].expect);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Completed hashed MAC checks.\n");
+ }
+
+/* Check that the signature SIG matches the hash HASH. PKEY is the
+ public key used for the verification. BADHASH is a hasvalue which
+ should; result in a bad signature status. */
+static void
+verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash,
+ gcry_sexp_t badhash, gcry_sexp_t sig)
+{
+ gcry_error_t rc;
+
+ rc = gcry_pk_verify (sig, hash, pkey);
+ if (rc)
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_verify (sig, badhash, pkey);
+ if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE)
+ fail ("gcry_pk_verify failed to detect a bad signature: %s\n",
+ gpg_strerror (rc));
+}
+
+
+/* Test the public key sign function using the private ket SKEY. PKEY
+ is used for verification. */
+static void
+check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ gcry_error_t rc;
+ gcry_sexp_t sig, badhash, hash;
+ int dataidx;
+ static const char baddata[] =
+ "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
+ static struct
+ {
+ const char *data;
+ int algo;
+ int expected_rc;
+ } datas[] =
+ {
+ { "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags oaep)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ 0,
+ GPG_ERR_CONFLICT },
+ /* This test is to see whether hash algorithms not hard wired in
+ pubkey.c are detected: */
+ { "(data\n (flags pkcs1)\n"
+ " (hash oid.1.3.14.3.2.29 "
+ " #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags )\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ 0,
+ GPG_ERR_CONFLICT },
+ { "(data\n (flags pkcs1)\n"
+ " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ GPG_ERR_DIGEST_ALGO },
+ { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
+ 0,
+ 0 },
+ { "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ GCRY_PK_RSA,
+ GPG_ERR_CONFLICT },
+ { "(data\n (flags raw foo)\n"
+ " (value #11223344556677889900AA#))\n",
+ 0,
+ GPG_ERR_INV_FLAG },
+ { "(data\n (flags pss)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { "(data\n (flags pss)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ GCRY_PK_RSA,
+ 0 },
+ { NULL }
+ };
+
+ (void)n;
+
+ rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ for (dataidx = 0; datas[dataidx].data; dataidx++)
+ {
+ if (datas[dataidx].algo && datas[dataidx].algo != algo)
+ continue;
+
+ if (verbose)
+ fprintf (stderr, " signature test %d\n", dataidx);
+
+ rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
+ strlen (datas[dataidx].data));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ rc = gcry_pk_sign (&sig, hash, skey);
+ if (gcry_err_code (rc) != datas[dataidx].expected_rc)
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
+
+ if (!rc)
+ verify_one_signature (pkey, hash, badhash, sig);
+
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (hash);
+ hash = NULL;
+ }
+
+ gcry_sexp_release (badhash);
+}
+
+static void
+check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ gcry_error_t rc;
+ gcry_sexp_t plain, ciph, data;
+ int dataidx;
+ static struct
+ {
+ int algo; /* If not 0 run test only if ALGO matches. */
+ const char *data;
+ const char *hint;
+ int unpadded;
+ int encrypt_expected_rc;
+ int decrypt_expected_rc;
+ } datas[] =
+ {
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ NULL,
+ 0,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags pkcs1)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)(hash-algo sha1)",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)(hash-algo sha1)(label \"test\")",
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
+ " (value #11223344556677889900AA#)\n"
+ " (random-override #4253647587980912233445566778899019283747#))\n",
+ "(flags oaep)(hash-algo sha1)(label \"test\")",
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { 0,
+ "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
+ NULL,
+ 1,
+ 0,
+ 0 },
+ { GCRY_PK_RSA,
+ "(data\n (flags pkcs1)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ NULL,
+ 0,
+ GPG_ERR_CONFLICT,
+ 0},
+ { 0,
+ "(data\n (flags raw foo)\n"
+ " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
+ NULL,
+ 0,
+ GPG_ERR_INV_FLAG,
+ 0},
+ { 0,
+ "(data\n (flags raw)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags oaep)",
+ 1,
+ 0,
+ GPG_ERR_ENCODING_PROBLEM },
+ { GCRY_PK_RSA,
+ "(data\n (flags oaep)\n"
+ " (value #11223344556677889900AA#))\n",
+ "(flags pkcs1)",
+ 1,
+ 0,
+ GPG_ERR_ENCODING_PROBLEM },
+ { 0,
+ "(data\n (flags pss)\n"
+ " (value #11223344556677889900AA#))\n",
+ NULL,
+ 0,
+ GPG_ERR_CONFLICT },
+ { 0, NULL }
+ };
+
+ (void)n;
+
+ for (dataidx = 0; datas[dataidx].data; dataidx++)
+ {
+ if (datas[dataidx].algo && datas[dataidx].algo != algo)
+ continue;
+
+ if (verbose)
+ fprintf (stderr, " encryption/decryption test %d (algo %d)\n",
+ dataidx, algo);
+
+ rc = gcry_sexp_sscan (&data, NULL, datas[dataidx].data,
+ strlen (datas[dataidx].data));
+ if (rc)
+ die ("converting data failed: %s\n", gpg_strerror (rc));
+
+ rc = gcry_pk_encrypt (&ciph, data, pkey);
+ if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc)
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc));
+
+ if (!rc)
+ {
+ /* Insert decoding hint to CIPH. */
+ if (datas[dataidx].hint)
+ {
+ size_t hint_len, len;
+ char *hint, *buf;
+ gcry_sexp_t list;
+
+ /* Convert decoding hint into canonical sexp. */
+ hint_len = gcry_sexp_new (&list, datas[dataidx].hint,
+ strlen (datas[dataidx].hint), 1);
+ hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, NULL, 0);
+ hint = gcry_malloc (hint_len);
+ if (!hint)
+ die ("can't allocate memory\n");
+ hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, hint,
+ hint_len);
+ gcry_sexp_release (list);
+
+ /* Convert CIPH into canonical sexp. */
+ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, NULL, 0);
+ buf = gcry_malloc (len + hint_len);
+ if (!buf)
+ die ("can't allocate memory\n");
+ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, buf, len);
+ /* assert (!strcmp (buf, "(7:enc-val", 10)); */
+
+ /* Copy decoding hint into CIPH. */
+ memmove (buf + 10 + hint_len, buf + 10, len - 10);
+ memcpy (buf + 10, hint, hint_len);
+ gcry_free (hint);
+ gcry_sexp_new (&list, buf, len + hint_len, 1);
+ gcry_free (buf);
+ gcry_sexp_release (ciph);
+ ciph = list;
+ }
+ rc = gcry_pk_decrypt (&plain, ciph, skey);
+ if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc)
+ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (rc));
+
+ if (!rc && datas[dataidx].unpadded)
+ {
+ gcry_sexp_t p1, p2;
+
+ p1 = gcry_sexp_find_token (data, "value", 0);
+ p2 = gcry_sexp_find_token (plain, "value", 0);
+ if (p1 && p2)
+ {
+ const char *s1, *s2;
+ size_t n1, n2;
+
+ s1 = gcry_sexp_nth_data (p1, 1, &n1);
+ s2 = gcry_sexp_nth_data (p2, 1, &n2);
+ if (n1 != n2 || memcmp (s1, s2, n1))
+ fail ("gcry_pk_encrypt/gcry_pk_decrypt do not roundtrip\n");
+ }
+ gcry_sexp_release (p1);
+ gcry_sexp_release (p2);
+ }
+ }
+
+ gcry_sexp_release (plain);
+ plain = NULL;
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ gcry_sexp_release (data);
+ data = NULL;
+ }
+}
+
+static void
+check_pubkey_grip (int n, const unsigned char *grip,
+ gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
+{
+ unsigned char sgrip[20], pgrip[20];
+
+ (void)algo;
+
+ if (!gcry_pk_get_keygrip (skey, sgrip))
+ die ("get keygrip for private RSA key failed\n");
+ if (!gcry_pk_get_keygrip (pkey, pgrip))
+ die ("[%i] get keygrip for public RSA key failed\n", n);
+ if (memcmp (sgrip, pgrip, 20))
+ fail ("[%i] keygrips don't match\n", n);
+ if (memcmp (sgrip, grip, 20))
+ fail ("wrong keygrip for RSA key\n");
+}
+
+static void
+do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey,
+ const unsigned char *grip, int algo, int flags)
+{
+ if (flags & FLAG_SIGN)
+ check_pubkey_sign (n, skey, pkey, algo);
+ if (flags & FLAG_CRYPT)
+ check_pubkey_crypt (n, skey, pkey, algo);
+ if (grip && (flags & FLAG_GRIP))
+ check_pubkey_grip (n, grip, skey, pkey, algo);
+}
+
+static void
+check_one_pubkey (int n, test_spec_pubkey_t spec)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t skey, pkey;
+
+ err = gcry_sexp_sscan (&skey, NULL, spec.key.secret,
+ strlen (spec.key.secret));
+ if (!err)
+ err = gcry_sexp_sscan (&pkey, NULL, spec.key.public,
+ strlen (spec.key.public));
+ if (err)
+ die ("converting sample key failed: %s\n", gpg_strerror (err));
+
+ do_check_one_pubkey (n, skey, pkey,
+ (const unsigned char*)spec.key.grip,
+ spec.id, spec.flags);
+
+ gcry_sexp_release (skey);
+ gcry_sexp_release (pkey);
+}
+
+static void
+get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+ if (verbose)
+ fprintf (stderr, " generating RSA key:");
+ rc = gcry_sexp_new (&key_spec,
+ in_fips_mode ? "(genkey (rsa (nbits 4:1024)))"
+ : "(genkey (rsa (nbits 4:1024)(transient-key)))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+static void
+check_one_pubkey_new (int n)
+{
+ gcry_sexp_t skey, pkey;
+
+ get_keys_new (&pkey, &skey);
+ do_check_one_pubkey (n, skey, pkey, NULL,
+ GCRY_PK_RSA, FLAG_SIGN | FLAG_CRYPT);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+}
+
+/* Run all tests for the public key functions. */
+static void
+check_pubkey (void)
+{
+ test_spec_pubkey_t pubkeys[] =
+ {
+ {
+ GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN,
+
+ { "(private-key\n"
+ " (rsa\n"
+ " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+ " (e #010001#)\n"
+ " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ " 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ " C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ " C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+ " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ " fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+ " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ " 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
+ " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ " ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))\n",
+
+ "(public-key\n"
+ " (rsa\n"
+ " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+ " (e #010001#)))\n",
+
+ "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
+ "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
+ },
+ {
+ GCRY_PK_DSA, FLAG_SIGN,
+
+ { "(private-key\n"
+ " (DSA\n"
+ " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+ " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+ " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+ " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
+ " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
+ " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+ " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+ " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+ " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
+ " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+ " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+ " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+ " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)\n"
+ " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n",
+
+ "(public-key\n"
+ " (DSA\n"
+ " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+ " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+ " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+ " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
+ " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
+ " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+ " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+ " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+ " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
+ " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+ " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+ " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+ " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))\n",
+
+ "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8"
+ "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
+ },
+ {
+ GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT,
+
+ { "(private-key\n"
+ " (ELG\n"
+ " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
+ " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
+ " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
+ " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
+ " (g #05#)\n"
+ " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
+ " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
+ " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
+ " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)\n"
+ " (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214#)))\n",
+
+ "(public-key\n"
+ " (ELG\n"
+ " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
+ " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
+ " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
+ " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
+ " (g #05#)\n"
+ " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
+ " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
+ " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
+ " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)))\n",
+
+ "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8"
+ "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" }
+ },
+ };
+ int i;
+ if (verbose)
+ fprintf (stderr, "Starting public key checks.\n");
+ for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
+ if (pubkeys[i].id)
+ {
+ if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ pubkeys[i].id);
+ continue;
+ }
+ check_one_pubkey (i, pubkeys[i]);
+ }
+ if (verbose)
+ fprintf (stderr, "Completed public key checks.\n");
+
+ if (verbose)
+ fprintf (stderr, "Starting additional public key checks.\n");
+ for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
+ if (pubkeys[i].id)
+ {
+ if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode)
+ {
+ if (verbose)
+ fprintf (stderr, " algorithm %d not available in fips mode\n",
+ pubkeys[i].id);
+ continue;
+ }
+ check_one_pubkey_new (i);
+ }
+ if (verbose)
+ fprintf (stderr, "Completed additional public key checks.\n");
+
+}
+
+int
+main (int argc, char **argv)
+{
+ gpg_error_t err;
+ int last_argc = -1;
+ int debug = 0;
+ int use_fips = 0;
+ int selftest_only = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ use_fips = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--selftest"))
+ {
+ selftest_only = 1;
+ verbose += 2;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--die"))
+ {
+ die_on_error = 1;
+ argc--; argv++;
+ }
+ }
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
+ if (use_fips)
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+
+ /* Check that we test exactly our version - including the patchlevel. */
+ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
+ die ("version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION,gcry_check_version (NULL));
+
+ if ( gcry_fips_mode_active () )
+ in_fips_mode = 1;
+
+ if (!in_fips_mode)
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ if (verbose)
+ gcry_set_progress_handler (progress_handler, NULL);
+
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+ if (!selftest_only)
+ {
+ check_ciphers ();
+ check_cipher_modes ();
+ check_bulk_cipher_modes ();
+ check_digests ();
+ check_hmac ();
+ check_pubkey ();
+ }
+
+
+ if (in_fips_mode && !selftest_only)
+ {
+ /* If we are in fips mode do some more tests. */
+ gcry_md_hd_t md;
+
+ /* First trigger a self-test. */
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+ if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("not in operational state after self-test\n");
+
+ /* Get us into the error state. */
+ err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
+ if (err)
+ fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err));
+ else
+ {
+ err = gcry_md_enable (md, GCRY_MD_SHA256);
+ if (err)
+ fail ("failed to add SHA-256 hash context: %s\n",
+ gpg_strerror (err));
+ else
+ {
+ /* gcry_md_get_algo is only defined for a context with
+ just one digest algorithm. With our setup it should
+ put the oibrary intoerror state. */
+ fputs ("Note: Two lines with error messages follow "
+ "- this is expected\n", stderr);
+ gcry_md_get_algo (md);
+ gcry_md_close (md);
+ if (gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("expected error state but still in operational state\n");
+ else
+ {
+ /* Now run a self-test and to get back into
+ operational state. */
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+ if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0))
+ fail ("did not reach operational after error "
+ "and self-test\n");
+ }
+ }
+ }
+
+ }
+ else
+ {
+ /* If in standard mode, run selftests. */
+ if (gcry_control (GCRYCTL_SELFTEST, 0))
+ fail ("running self-test failed\n");
+ }
+
+ if (verbose)
+ fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count);
+
+ if (in_fips_mode && !gcry_fips_mode_active ())
+ fprintf (stderr, "FIPS mode is not anymore active\n");
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* benchmark.c - for libgcrypt
+ * Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/times.h>
+#endif
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+# include "../compat/libcompat.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+#define PGM "benchmark"
+
+static int verbose;
+
+/* Do encryption tests with large buffers. */
+static int large_buffers;
+
+/* Number of cipher repetitions. */
+static int cipher_repetitions;
+
+/* Number of hash repetitions. */
+static int hash_repetitions;
+
+/* Alignment of the buffers. */
+static int buffer_alignment;
+
+/* Whether to include the keysetup in the cipher timings. */
+static int cipher_with_keysetup;
+
+/* Whether fips mode was active at startup. */
+static int in_fips_mode;
+
+
+static const char sample_private_dsa_key_1024[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
+ "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
+ "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
+ "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
+" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
+" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
+ "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
+ "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
+ "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
+" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
+ "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
+ "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
+ "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
+" (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n"
+"))\n";
+
+static const char sample_public_dsa_key_1024[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
+ "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
+ "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
+ "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
+" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
+" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
+ "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
+ "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
+ "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
+" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
+ "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
+ "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
+ "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
+"))\n";
+
+
+static const char sample_private_dsa_key_2048[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
+ "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
+ "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
+ "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
+ "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
+ "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
+ "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
+ "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
+" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
+" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
+ "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
+ "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
+ "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
+ "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
+ "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
+ "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
+ "6EE4425A553AF8885FEA15A88135BE133520#)\n"
+" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
+ "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
+ "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
+ "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
+ "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
+ "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
+ "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
+ "14A264330AECCB24DE2A1107847B23490897#)\n"
+" (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n"
+"))\n";
+
+
+static const char sample_public_dsa_key_2048[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
+ "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
+ "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
+ "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
+ "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
+ "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
+ "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
+ "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
+" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
+" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
+ "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
+ "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
+ "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
+ "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
+ "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
+ "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
+ "6EE4425A553AF8885FEA15A88135BE133520#)\n"
+" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
+ "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
+ "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
+ "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
+ "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
+ "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
+ "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
+ "14A264330AECCB24DE2A1107847B23490897#)\n"
+"))\n";
+
+
+static const char sample_private_dsa_key_3072[] =
+"(private-key\n"
+" (dsa\n"
+" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
+ "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
+ "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
+ "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
+ "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
+ "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
+ "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
+ "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
+ "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
+ "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
+ "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
+ "8015353D3778B02B892AF7#)\n"
+" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
+" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
+ "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
+ "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
+ "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
+ "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
+ "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
+ "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
+ "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
+ "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
+ "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
+ "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
+ "4997AF9EB55C6660B01A#)\n"
+" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
+ "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
+ "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
+ "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
+ "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
+ "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
+ "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
+ "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
+ "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
+ "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
+ "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
+ "2703D518D8D49FF0EBE6#)\n"
+" (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n"
+"))\n";
+
+static const char sample_public_dsa_key_3072[] =
+"(public-key\n"
+" (dsa\n"
+" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
+ "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
+ "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
+ "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
+ "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
+ "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
+ "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
+ "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
+ "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
+ "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
+ "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
+ "8015353D3778B02B892AF7#)\n"
+" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
+" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
+ "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
+ "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
+ "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
+ "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
+ "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
+ "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
+ "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
+ "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
+ "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
+ "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
+ "4997AF9EB55C6660B01A#)\n"
+" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
+ "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
+ "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
+ "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
+ "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
+ "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
+ "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
+ "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
+ "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
+ "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
+ "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
+ "2703D518D8D49FF0EBE6#)\n"
+"))\n";
+
+
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
+ exit(2);} while(0)
+
+
+/* Helper for the start and stop timer. */
+#ifdef _WIN32
+struct {
+ FILETIME creation_time, exit_time, kernel_time, user_time;
+} started_at, stopped_at;
+#else
+static clock_t started_at, stopped_at;
+#endif
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ putchar ('\n');
+ fputs ( PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = malloc (size);
+ if (!buf)
+ die ("out of core\n");
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+}
+
+
+static void
+start_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+ GetThreadTimes (GetCurrentThread (),
+ &started_at.creation_time, &started_at.exit_time,
+ &started_at.kernel_time, &started_at.user_time);
+#else
+ GetProcessTimes (GetCurrentProcess (),
+ &started_at.creation_time, &started_at.exit_time,
+ &started_at.kernel_time, &started_at.user_time);
+#endif
+ stopped_at = started_at;
+#else
+ struct tms tmp;
+
+ times (&tmp);
+ started_at = stopped_at = tmp.tms_utime;
+#endif
+}
+
+static void
+stop_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+ GetThreadTimes (GetCurrentThread (),
+ &stopped_at.creation_time, &stopped_at.exit_time,
+ &stopped_at.kernel_time, &stopped_at.user_time);
+#else
+ GetProcessTimes (GetCurrentProcess (),
+ &stopped_at.creation_time, &stopped_at.exit_time,
+ &stopped_at.kernel_time, &stopped_at.user_time);
+#endif
+#else
+ struct tms tmp;
+
+ times (&tmp);
+ stopped_at = tmp.tms_utime;
+#endif
+}
+
+static const char *
+elapsed_time (void)
+{
+ static char buf[50];
+#if _WIN32
+ unsigned long long t1, t2, t;
+
+ t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
+ + started_at.kernel_time.dwLowDateTime);
+ t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
+ + started_at.user_time.dwLowDateTime);
+ t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
+ + stopped_at.kernel_time.dwLowDateTime);
+ t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32)
+ + stopped_at.user_time.dwLowDateTime);
+ t = (t2 - t1)/10000;
+ snprintf (buf, sizeof buf, "%5.0fms", (double)t );
+#else
+ snprintf (buf, sizeof buf, "%5.0fms",
+ (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
+#endif
+ return buf;
+}
+
+
+static void
+progress_cb (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+
+ fprintf (stderr, PGM ": progress (%s %c %d %d)\n",
+ what, printchar, current, total);
+ fflush (stderr);
+}
+
+
+static void
+random_bench (int very_strong)
+{
+ char buf[128];
+ int i;
+
+ printf ("%-10s", "random");
+
+ if (!very_strong)
+ {
+ start_timer ();
+ for (i=0; i < 100; i++)
+ gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ }
+
+ start_timer ();
+ for (i=0; i < 100; i++)
+ gcry_randomize (buf, 8,
+ very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+
+ putchar ('\n');
+ if (verbose)
+ gcry_control (GCRYCTL_DUMP_RANDOM_STATS);
+}
+
+
+
+static void
+md_bench ( const char *algoname )
+{
+ int algo;
+ gcry_md_hd_t hd;
+ int i, j, repcount;
+ char buf_base[1000+15];
+ size_t bufsize = 1000;
+ char *buf;
+ char *largebuf_base;
+ char *largebuf;
+ char digest[512/8];
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+ if (!algoname)
+ {
+ for (i=1; i < 400; i++)
+ if (in_fips_mode && i == GCRY_MD_MD5)
+ ; /* Don't use MD5 in fips mode. */
+ else if ( !gcry_md_test_algo (i) )
+ md_bench (gcry_md_algo_name (i));
+ return;
+ }
+
+ buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment);
+
+ algo = gcry_md_map_name (algoname);
+ if (!algo)
+ {
+ fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ for (i=0; i < bufsize; i++)
+ buf[i] = i;
+
+ printf ("%-12s", gcry_md_algo_name (algo));
+
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ gcry_md_write (hd, buf, bufsize);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ gcry_md_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 10000; i++)
+ gcry_md_write (hd, buf, bufsize/10);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ gcry_md_reset (hd);
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000000; i++)
+ gcry_md_write (hd, buf, 1);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 1000; i++)
+ for (j=0; j < bufsize; j++)
+ gcry_md_putc (hd, buf[j]);
+ gcry_md_final (hd);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ gcry_md_close (hd);
+
+ /* Now 100 hash operations on 10000 bytes using the fast function.
+ We initialize the buffer so that all memory pages are committed
+ and we have repeatable values. */
+ if (gcry_md_get_algo_dlen (algo) > sizeof digest)
+ die ("digest buffer too short\n");
+
+ largebuf_base = malloc (10000+15);
+ if (!largebuf_base)
+ die ("out of core\n");
+ largebuf = (largebuf_base
+ + ((16 - ((size_t)largebuf_base & 0x0f)) % buffer_alignment));
+
+ for (i=0; i < 10000; i++)
+ largebuf[i] = i;
+ start_timer ();
+ for (repcount=0; repcount < hash_repetitions; repcount++)
+ for (i=0; i < 100; i++)
+ gcry_md_hash_buffer (algo, digest, largebuf, 10000);
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ free (largebuf_base);
+
+ putchar ('\n');
+ fflush (stdout);
+}
+
+static void
+cipher_bench ( const char *algoname )
+{
+ static int header_printed;
+ int algo;
+ gcry_cipher_hd_t hd;
+ int i;
+ int keylen, blklen;
+ char key[128];
+ char *outbuf, *buf;
+ char *raw_outbuf, *raw_buf;
+ size_t allocated_buflen, buflen;
+ int repetitions;
+ static struct { int mode; const char *name; int blocked; } modes[] = {
+ { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1 },
+ { GCRY_CIPHER_MODE_CBC, " CBC", 1 },
+ { GCRY_CIPHER_MODE_CFB, " CFB", 0 },
+ { GCRY_CIPHER_MODE_OFB, " OFB", 0 },
+ { GCRY_CIPHER_MODE_CTR, " CTR", 0 },
+ { GCRY_CIPHER_MODE_STREAM, "", 0 },
+ {0}
+ };
+ int modeidx;
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+
+
+ if (!algoname)
+ {
+ for (i=1; i < 400; i++)
+ if ( !gcry_cipher_test_algo (i) )
+ cipher_bench (gcry_cipher_algo_name (i));
+ return;
+ }
+
+ if (large_buffers)
+ {
+ allocated_buflen = 1024 * 100;
+ repetitions = 10;
+ }
+ else
+ {
+ allocated_buflen = 1024;
+ repetitions = 1000;
+ }
+ repetitions *= cipher_repetitions;
+
+ raw_buf = gcry_xmalloc (allocated_buflen+15);
+ buf = (raw_buf
+ + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment));
+ outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15);
+ outbuf = (raw_outbuf
+ + ((16 - ((size_t)raw_outbuf & 0x0f)) % buffer_alignment));
+
+ if (!header_printed)
+ {
+ if (cipher_repetitions != 1)
+ printf ("Running each test %d times.\n", cipher_repetitions);
+ printf ("%-12s", "");
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ if (*modes[modeidx].name)
+ printf (" %-15s", modes[modeidx].name );
+ putchar ('\n');
+ printf ("%-12s", "");
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ if (*modes[modeidx].name)
+ printf (" ---------------" );
+ putchar ('\n');
+ header_printed = 1;
+ }
+
+ algo = gcry_cipher_map_name (algoname);
+ if (!algo)
+ {
+ fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
+ exit (1);
+ }
+
+ keylen = gcry_cipher_get_algo_keylen (algo);
+ if (!keylen)
+ {
+ fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+ algoname);
+ exit (1);
+ }
+ if ( keylen > sizeof key )
+ {
+ fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
+ algo, keylen );
+ exit (1);
+ }
+ for (i=0; i < keylen; i++)
+ key[i] = i + (clock () & 0xff);
+
+ blklen = gcry_cipher_get_algo_blklen (algo);
+ if (!blklen)
+ {
+ fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
+ algoname);
+ exit (1);
+ }
+
+ printf ("%-12s", gcry_cipher_algo_name (algo));
+ fflush (stdout);
+
+ for (modeidx=0; modes[modeidx].mode; modeidx++)
+ {
+ if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
+ | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
+ continue;
+
+ for (i=0; i < sizeof buf; i++)
+ buf[i] = i;
+
+ err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
+ exit (1);
+ }
+
+ if (!cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ buflen = allocated_buflen;
+ if (modes[modeidx].blocked)
+ buflen = (buflen / blklen) * blklen;
+
+ start_timer ();
+ for (i=err=0; !err && i < repetitions; i++)
+ {
+ if (cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+ err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
+ }
+ stop_timer ();
+
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+ gcry_cipher_close (hd);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
+ gpg_strerror (err) );
+ exit (1);
+ }
+
+ err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
+ exit (1);
+ }
+
+ if (!cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+
+ start_timer ();
+ for (i=err=0; !err && i < repetitions; i++)
+ {
+ if (cipher_with_keysetup)
+ {
+ err = gcry_cipher_setkey (hd, key, keylen);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hd);
+ exit (1);
+ }
+ }
+ err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen);
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+ gcry_cipher_close (hd);
+ if (err)
+ {
+ fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
+ gpg_strerror (err) );
+ exit (1);
+ }
+ }
+
+ putchar ('\n');
+ gcry_free (raw_buf);
+ gcry_free (raw_outbuf);
+}
+
+
+
+static void
+rsa_bench (int iterations, int print_header, int no_blinding)
+{
+ gpg_error_t err;
+ int p_sizes[] = { 1024, 2048, 3072, 4096 };
+ int testno;
+
+ if (print_header)
+ printf ("Algorithm generate %4d*sign %4d*verify\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (testno=0; testno < DIM (p_sizes); testno++)
+ {
+ gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
+ gcry_mpi_t x;
+ gcry_sexp_t data;
+ gcry_sexp_t sig = NULL;
+ int count;
+
+ printf ("RSA %3d bit ", p_sizes[testno]);
+ fflush (stdout);
+
+ err = gcry_sexp_build (&key_spec, NULL,
+ gcry_fips_mode_active ()
+ ? "(genkey (RSA (nbits %d)))"
+ : "(genkey (RSA (nbits %d)(transient-key)))",
+ p_sizes[testno]);
+ if (err)
+ die ("creating S-expression failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ die ("creating %d bit RSA key failed: %s\n",
+ p_sizes[testno], gcry_strerror (err));
+
+ pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+ sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+ gcry_sexp_release (key_pair);
+ gcry_sexp_release (key_spec);
+
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ x = gcry_mpi_new (p_sizes[testno]);
+ gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL,
+ "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ die ("signing failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key);
+ if (err)
+ {
+ putchar ('\n');
+ show_sexp ("seckey:\n", sec_key);
+ show_sexp ("data:\n", data);
+ show_sexp ("sig:\n", sig);
+ die ("verify failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+
+ if (no_blinding)
+ {
+ fflush (stdout);
+ x = gcry_mpi_new (p_sizes[testno]);
+ gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL,
+ "(data (flags no-blinding) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ die ("signing failed (%d): %s\n", count, gpg_strerror (err));
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+ }
+
+ putchar ('\n');
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+
+static void
+dsa_bench (int iterations, int print_header)
+{
+ gpg_error_t err;
+ gcry_sexp_t pub_key[3], sec_key[3];
+ int p_sizes[3] = { 1024, 2048, 3072 };
+ int q_sizes[3] = { 160, 224, 256 };
+ gcry_sexp_t data;
+ gcry_sexp_t sig;
+ int i, j;
+
+ err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
+ strlen (sample_public_dsa_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
+ strlen (sample_private_dsa_key_1024));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
+ strlen (sample_public_dsa_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
+ strlen (sample_private_dsa_key_2048));
+ if (!err)
+ err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
+ strlen (sample_public_dsa_key_3072));
+ if (!err)
+ err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
+ strlen (sample_private_dsa_key_3072));
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting sample keys failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ if (print_header)
+ printf ("Algorithm generate %4d*sign %4d*verify\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (i=0; i < DIM (q_sizes); i++)
+ {
+ gcry_mpi_t x;
+
+ x = gcry_mpi_new (q_sizes[i]);
+ gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ {
+ fprintf (stderr, PGM ": converting data failed: %s\n",
+ gcry_strerror (err));
+ exit (1);
+ }
+
+ printf ("DSA %d/%d -", p_sizes[i], q_sizes[i]);
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ err = gcry_pk_sign (&sig, data, sec_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": signing failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ start_timer ();
+ for (j=0; j < iterations; j++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key[i]);
+ if (err)
+ {
+ putchar ('\n');
+ fprintf (stderr, PGM ": verify failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ stop_timer ();
+ printf (" %s\n", elapsed_time ());
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ }
+
+
+ for (i=0; i < DIM (q_sizes); i++)
+ {
+ gcry_sexp_release (sec_key[i]);
+ gcry_sexp_release (pub_key[i]);
+ }
+}
+
+
+static void
+ecc_bench (int iterations, int print_header)
+{
+#if USE_ECC
+ gpg_error_t err;
+ int p_sizes[] = { 192, 224, 256, 384, 521 };
+ int testno;
+
+ if (print_header)
+ printf ("Algorithm generate %4d*sign %4d*verify\n"
+ "------------------------------------------------\n",
+ iterations, iterations );
+ for (testno=0; testno < DIM (p_sizes); testno++)
+ {
+ gcry_sexp_t key_spec, key_pair, pub_key, sec_key;
+ gcry_mpi_t x;
+ gcry_sexp_t data;
+ gcry_sexp_t sig = NULL;
+ int count;
+
+ printf ("ECDSA %3d bit ", p_sizes[testno]);
+ fflush (stdout);
+
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
+ if (err)
+ die ("creating S-expression failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ die ("creating %d bit ECC key failed: %s\n",
+ p_sizes[testno], gcry_strerror (err));
+
+ pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+ sec_key = gcry_sexp_find_token (key_pair, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+ gcry_sexp_release (key_pair);
+ gcry_sexp_release (key_spec);
+
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ x = gcry_mpi_new (p_sizes[testno]);
+ gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
+ err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+ gcry_mpi_release (x);
+ if (err)
+ die ("converting data failed: %s\n", gcry_strerror (err));
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ gcry_sexp_release (sig);
+ err = gcry_pk_sign (&sig, data, sec_key);
+ if (err)
+ die ("signing failed: %s\n", gpg_strerror (err));
+ }
+ stop_timer ();
+ printf (" %s", elapsed_time ());
+ fflush (stdout);
+
+ start_timer ();
+ for (count=0; count < iterations; count++)
+ {
+ err = gcry_pk_verify (sig, data, pub_key);
+ if (err)
+ {
+ putchar ('\n');
+ show_sexp ("seckey:\n", sec_key);
+ show_sexp ("data:\n", data);
+ show_sexp ("sig:\n", sig);
+ die ("verify failed: %s\n", gpg_strerror (err));
+ }
+ }
+ stop_timer ();
+ printf (" %s\n", elapsed_time ());
+ fflush (stdout);
+
+ gcry_sexp_release (sig);
+ gcry_sexp_release (data);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+#endif /*USE_ECC*/
+}
+
+
+
+static void
+do_powm ( const char *n_str, const char *e_str, const char *m_str)
+{
+ gcry_mpi_t e, n, msg, cip;
+ gcry_error_t err;
+ int i;
+
+ err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
+ if (err) BUG ();
+ err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
+ if (err) BUG ();
+ err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
+ if (err) BUG ();
+
+ cip = gcry_mpi_new (0);
+
+ start_timer ();
+ for (i=0; i < 1000; i++)
+ gcry_mpi_powm (cip, msg, e, n);
+ stop_timer ();
+ printf (" %s", elapsed_time ()); fflush (stdout);
+/* { */
+/* char *buf; */
+
+/* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
+/* BUG (); */
+/* printf ("result: %s\n", buf); */
+/* gcry_free (buf); */
+/* } */
+ gcry_mpi_release (cip);
+ gcry_mpi_release (msg);
+ gcry_mpi_release (n);
+ gcry_mpi_release (e);
+}
+
+
+static void
+mpi_bench (void)
+{
+ printf ("%-10s", "powm"); fflush (stdout);
+
+ do_powm (
+"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
+ "29",
+"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
+ );
+ do_powm (
+ "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
+ "29",
+ "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
+ );
+ do_powm (
+ "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
+ "29",
+ "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
+ );
+
+ putchar ('\n');
+
+
+}
+
+
+int
+main( int argc, char **argv )
+{
+ int last_argc = -1;
+ int no_blinding = 0;
+ int use_random_daemon = 0;
+ int with_progress = 0;
+
+ buffer_alignment = 1;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ fputs ("usage: benchmark "
+ "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
+ stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--use-random-daemon"))
+ {
+ use_random_daemon = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-blinding"))
+ {
+ no_blinding = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--large-buffers"))
+ {
+ large_buffers = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--cipher-repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ cipher_repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--cipher-with-keysetup"))
+ {
+ cipher_with_keysetup = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--hash-repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ hash_repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--alignment"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ buffer_alignment = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--disable-hwf"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+ fprintf (stderr, PGM ": unknown hardware feature `%s'"
+ " - option ignored\n", *argv);
+ argc--; argv++;
+ }
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ argc--; argv++;
+ /* This command needs to be called before gcry_check_version. */
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ argc--; argv++;
+ with_progress = 1;
+ }
+ }
+
+ if (buffer_alignment < 1 || buffer_alignment > 16)
+ die ("value for --alignment must be in the range 1 to 16\n");
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fprintf (stderr, PGM ": version mismatch; pgm=%s, library=%s\n",
+ GCRYPT_VERSION, gcry_check_version (NULL));
+ exit (1);
+ }
+
+ if (gcry_fips_mode_active ())
+ in_fips_mode = 1;
+ else
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+ if (use_random_daemon)
+ gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
+
+ if (with_progress)
+ gcry_set_progress_handler (progress_cb, NULL);
+
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ if (cipher_repetitions < 1)
+ cipher_repetitions = 1;
+ if (hash_repetitions < 1)
+ hash_repetitions = 1;
+
+ if ( !argc )
+ {
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ md_bench (NULL);
+ putchar ('\n');
+ cipher_bench (NULL);
+ putchar ('\n');
+ rsa_bench (100, 1, no_blinding);
+ dsa_bench (100, 0);
+ ecc_bench (100, 0);
+ putchar ('\n');
+ mpi_bench ();
+ putchar ('\n');
+ random_bench (0);
+ }
+ else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom"))
+ {
+ if (argc == 1)
+ random_bench ((**argv == 's'));
+ else if (argc == 2)
+ {
+ gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]);
+ random_bench ((**argv == 's'));
+ gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE);
+ }
+ else
+ fputs ("usage: benchmark [strong]random [seedfile]\n", stdout);
+ }
+ else if ( !strcmp (*argv, "md"))
+ {
+ if (argc == 1)
+ md_bench (NULL);
+ else
+ for (argc--, argv++; argc; argc--, argv++)
+ md_bench ( *argv );
+ }
+ else if ( !strcmp (*argv, "cipher"))
+ {
+ if (argc == 1)
+ cipher_bench (NULL);
+ else
+ for (argc--, argv++; argc; argc--, argv++)
+ cipher_bench ( *argv );
+ }
+ else if ( !strcmp (*argv, "mpi"))
+ {
+ mpi_bench ();
+ }
+ else if ( !strcmp (*argv, "rsa"))
+ {
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ rsa_bench (100, 1, no_blinding);
+ }
+ else if ( !strcmp (*argv, "dsa"))
+ {
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ dsa_bench (100, 1);
+ }
+ else if ( !strcmp (*argv, "ecc"))
+ {
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ ecc_bench (100, 1);
+ }
+ else
+ {
+ fprintf (stderr, PGM ": bad arguments\n");
+ return 1;
+ }
+
+
+ if (in_fips_mode && !gcry_fips_mode_active ())
+ fprintf (stderr, PGM ": FIPS mode is not anymore active\n");
+
+ return 0;
+}
--- /dev/null
+#!/usr/bin/env perl
+#
+# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $
+#
+# CAVS test driver (based on the OpenSSL driver)
+# Written by: Stephan Müller <sm@atsec.com>
+# Copyright (c) atsec information security corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# NO WARRANTY
+#
+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+# PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+# REPAIR OR CORRECTION.
+#
+# 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
+# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGES.
+#
+#
+# test execution instruction:
+# 1. get the request files from the lab
+# 2. call each request file from 1. with this program:
+# $0 <FILE>.rep
+# 3. send the resulting file <FILE>.rsp to the lab
+#
+#
+# Test should be easily adoptable to other implementations
+# See the first functions for this task
+#
+# Following tests are covered (others may also be covered
+# but have not been tested)
+#
+# AES
+# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256]
+# [CBC|CFB128|ECB|OFB]MCT[128|192|256]
+# [CBC|CFB128|ECB|OFB]VarKey[128|192|256]
+# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256]
+# [CBC|CFB128|ECB|OFB]MMT[128|192|256]
+# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256]
+#
+# RSA
+# SigGen[15|RSA]
+# SigVer15
+# (SigVerRSA is not applicable for OpenSSL as X9.31 padding
+# is not done through openssl dgst)
+# KeyGen RSA X9.31
+#
+# SHA
+# SHA[1|224|256|384|512]ShortMsg
+# SHA[1|224|256|384|512]LongMsg
+# SHA[1|224|256|384|512]Monte
+#
+# HMAC (SHA - caveat: we only support hash output equal to the block size of
+# of the hash - we do not support truncation of the hash; to support
+# that, we first need to decipher the HMAC.req file - see hmac_kat() )
+# HMAC
+#
+# TDES
+# T[CBC|CFB??|ECB|OFB]Monte[1|2|3]
+# T[CBC|CFB??|ECB|OFB]permop
+# T[CBC|CFB??|ECB|OFB]MMT[1|2|3]
+# T[CBC|CFB??|ECB|OFB]subtab
+# T[CBC|CFB??|ECB|OFB]varkey
+# T[CBC|CFB??|ECB|OFB]invperm
+# T[CBC|CFB??|ECB|OFB]vartext
+#
+# ANSI X9.31 RNG
+# ANSI931_AES128MCT
+# ANSI931_AES128VST
+#
+# DSA
+# PQGGen
+# SigGen
+# SigVer
+#
+# RC4 (atsec developed tests)
+# RC4KeyBD
+# RC4MCT
+# RC4PltBD
+# RC4REGT
+#
+
+use strict;
+use warnings;
+use IPC::Open2;
+use Getopt::Std;
+use MIME::Base64;
+
+# Contains the command line options
+my %opt;
+
+#################################################################
+##### Central interface functions to the external ciphers #######
+#################################################################
+# Only these interface routines should be changed in case of
+# porting to a new cipher library
+#
+# For porting to a new library, create implementation of these functions
+# and then add pointers to the respective implementation of each
+# function to the given variables.
+
+# common encryption/decryption routine
+# $1 key in hex form (please note for 3DES: even when ede3 for three
+# independent ciphers is given with the cipher specification, we hand in
+# either one key for k1 = k2 = k3, two keys which are concatinated for
+# k1 = k3, k2 independent, or three keys which are concatinated for
+# k1, k2, k3 independent)
+# $2 iv in hex form
+# $3 cipher - the cipher string is defined as specified in the openssl
+# enc(1ssl) specification for the option "-ciphername"
+# (e.g. aes-128-cbc or des-ede3-cbc)
+# $4 encrypt=1/decrypt=0
+# $5 de/encrypted data in hex form
+# return en/decrypted data in hex form
+my $encdec;
+
+#
+# Derive an RSA key from the given X9.31 parameters.
+# $1: modulus size
+# $2: E in hex form
+# $3: Xp1 in hex form
+# $4: Xp2 in hex form
+# $5: Xp in hex form
+# $6: Xq1 in hex form
+# $7: Xq2 in hex form
+# $8: Xq in hex form
+# return: string with the calculated values in hex format, where each value
+# is separated from the previous with a \n in the following order:
+# P\n
+# Q\n
+# N\n
+# D\n
+my $rsa_derive;
+
+# Sign a message with RSA
+# $1: data to be signed in hex form
+# $2: Hash algo
+# $3: Key file in PEM format with the private key
+# return: digest in hex format
+my $rsa_sign;
+
+# Verify a message with RSA
+# $1: data to be verified in hex form
+# $2: hash algo
+# $3: file holding the public RSA key in PEM format
+# $4: file holding the signature in binary form
+# return: 1 == verified / 0 == not verified
+my $rsa_verify;
+
+# generate a new private RSA key with the following properties:
+# exponent is 65537
+# PEM format
+# $1 key size in bit
+# $2 keyfile name
+# return: nothing, but file created
+my $gen_rsakey;
+
+# Creating a hash
+# $1: Plaintext in hex form
+# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g.
+# sha1, sha224, sha256, sha384, sha512
+# return: hash in hex form
+my $hash;
+
+# supplying the call to the external cipher implementation
+# that is being used to keep STDIN and STDOUT open
+# to maintain the state of the block chaining
+# $1: cipher
+# $2: 1=encryption, 0=decryption
+# $3: buffersize needed for openssl
+# $4: encryption key in binary form
+# $5: IV in binary form
+# return: command line to execute the application
+my $state_cipher;
+# the only difference of the DES version is that it implements the inner loop
+# of the TDES tests
+my $state_cipher_des;
+
+# supplying the call to the external cipher implementation
+# that is being used to keep STDIN and STDOUT open
+# to maintain the state of the RNG with its seed
+#
+# input holds seed values
+# $1: cipher key in hex format
+# $2: DT value in hex format
+# $3: V value in hex format
+#
+# return: command line to execute the application
+#
+# the application is expected to deliver random values on STDOUT - the script
+# reads 128 bits repeatedly where the state of the RNG must be retained
+# between the reads. The output of the RNG on STDOUT is assumed to be binary.
+my $state_rng;
+
+# Generate an HMAC based on SHAx
+# $1: Key to be used for the HMAC in hex format
+# $2: length of the hash to be calculated in bits
+# $3: Message for which the HMAC shall be calculated in hex format
+# $4: hash type (1 - SHA1, 224 - SHA224, and so on)
+# return: calculated HMAC in hex format
+my $hmac;
+
+#
+# Generate the P, Q, G, Seed, counter, h (value used to generate g) values
+# for DSA
+# $1: modulus size
+# return: string with the calculated values in hex format, where each value
+# is separated from the previous with a \n in the following order:
+# P\n
+# Q\n
+# G\n
+# Seed\n
+# counter\n
+# h
+my $dsa_pqggen;
+
+#
+# Generate an DSA public key from the provided parameters:
+# $1: Name of file to create
+# $2: P in hex form
+# $3: Q in hex form
+# $4: G in hex form
+# $5: Y in hex form
+my $dsa_genpubkey;
+
+# Verify a message with DSA
+# $1: data to be verified in hex form
+# $2: file holding the public DSA key in PEM format
+# $3: R value of the signature
+# $4: S value of the signature
+# return: 1 == verified / 0 == not verified
+my $dsa_verify;
+
+# generate a new DSA key with the following properties:
+# PEM format
+# $1 keyfile name
+# return: file created, hash with keys of P, Q, G in hex format
+my $gen_dsakey;
+
+# Sign a message with DSA
+# $1: data to be signed in hex form
+# $2: Key file in PEM format with the private key
+# return: hash of digest information in hex format with Y, R, S as keys
+my $dsa_sign;
+
+################################################################
+##### OpenSSL interface functions
+################################################################
+sub openssl_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "-e" : "-d";
+ my $data=shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "-iv $iv" if ($iv);
+
+ $data=hex2bin($data);
+ my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv";
+ $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given
+ $data=pipe_through_program($data,$program);
+ return bin2hex($data);
+}
+
+sub openssl_rsa_sign($$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+
+ $data=hex2bin($data);
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data=pipe_through_program($data,
+ "openssl dgst -$cipher -binary -sign $keyfile");
+ return bin2hex($data);
+}
+
+sub openssl_rsa_verify($$$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+ my $sigfile = shift;
+
+ $data = hex2bin($data);
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data = pipe_through_program($data,
+ "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile");
+
+ # Parse through the OpenSSL output information
+ return ($data =~ /OK/);
+}
+
+sub openssl_gen_rsakey($$) {
+ my $keylen = shift;
+ my $file = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ # generating of a key with exponent 0x10001
+ my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen");
+ system(@args) == 0
+ or die "system @args failed: $?";
+ die "system @args failed: file $file not created" if (! -f $file);
+}
+
+sub openssl_hash($$) {
+ my $pt = shift;
+ my $cipher = shift;
+
+ die "ARCFOUR not available for hashes" if $opt{'R'};
+ my $hash = hex2bin($pt);
+ #bin2hex not needed as the '-hex' already converts it
+ return pipe_through_program($hash, "openssl dgst -$cipher -hex");
+}
+
+sub openssl_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $encdec = shift;
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ my $enc = $encdec ? "-e": "-d";
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "-iv ".bin2hex($iv) if ($iv);
+
+ my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv";
+ #for ARCFOUR, no IV must be given
+ $out = "rc4 -k " . bin2hex($key) if $opt{'R'};
+ return $out;
+}
+
+###### End of OpenSSL interface implementation ############
+
+###########################################################
+###### libgcrypt implementation
+###########################################################
+sub libgcrypt_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "encrypt" : "decrypt";
+ my $data=shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv $iv" if ($iv);
+
+ my $program="fipsdrv --key $key $iv --algo $cipher $enc";
+
+ return pipe_through_program($data,$program);
+
+}
+
+sub libgcrypt_rsa_derive($$$$$$$$) {
+ my $n = shift;
+ my $e = shift;
+ my $xp1 = shift;
+ my $xp2 = shift;
+ my $xp = shift;
+ my $xq1 = shift;
+ my $xq2 = shift;
+ my $xq = shift;
+ my $sexp;
+ my @tmp;
+
+ $n = sprintf ("%u", $n);
+ $e = sprintf ("%u", hex($e));
+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
+ . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
+ . "(derive-parms"
+ . "(Xp1 #$xp1#)"
+ . "(Xp2 #$xp2#)"
+ . "(Xp #$xp#)"
+ . "(Xq1 #$xq1#)"
+ . "(Xq2 #$xq2#)"
+ . "(Xq #$xq#))))\n";
+
+ return pipe_through_program($sexp, "fipsdrv rsa-derive");
+}
+
+
+sub libgcrypt_rsa_sign($$$) {
+ my $data = shift;
+ my $hashalgo = shift;
+ my $keyfile = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+
+ return pipe_through_program($data,
+ "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign");
+}
+
+sub libgcrypt_rsa_verify($$$$) {
+ my $data = shift;
+ my $hashalgo = shift;
+ my $keyfile = shift;
+ my $sigfile = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ $data = pipe_through_program($data,
+ "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
+
+ # Parse through the output information
+ return ($data =~ /GOOD signature/);
+}
+
+sub libgcrypt_gen_rsakey($$) {
+ my $keylen = shift;
+ my $file = shift;
+
+ die "ARCFOUR not available for RSA" if $opt{'R'};
+ my @args = ("fipsdrv --keysize $keylen rsa-gen > $file");
+ system(@args) == 0
+ or die "system @args failed: $?";
+ die "system @args failed: file $file not created" if (! -f $file);
+}
+
+sub libgcrypt_hash($$) {
+ my $pt = shift;
+ my $hashalgo = shift;
+
+ my $program = "fipsdrv --algo $hashalgo digest";
+ die "ARCFOUR not available for hashes" if $opt{'R'};
+
+ return pipe_through_program($pt, $program);
+}
+
+sub libgcrypt_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $enc = (shift) ? "encrypt": "decrypt";
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv ".bin2hex($iv) if ($iv);
+
+ my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc";
+
+ return $program;
+}
+
+sub libgcrypt_state_cipher_des($$$$$) {
+ my $cipher = shift;
+ my $enc = (shift) ? "encrypt": "decrypt";
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ # We only invoke the driver with the IV parameter, if we have
+ # an IV, otherwise, we skip it
+ $iv = "--iv ".bin2hex($iv) if ($iv);
+
+ my $program="fipsdrv --algo '$cipher' --mct-server $enc";
+
+ return $program;
+}
+
+sub libgcrypt_state_rng($$$) {
+ my $key = shift;
+ my $dt = shift;
+ my $v = shift;
+
+ return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random";
+}
+
+sub libgcrypt_hmac($$$$) {
+ my $key = shift;
+ my $maclen = shift;
+ my $msg = shift;
+ my $hashtype = shift;
+
+ my $program = "fipsdrv --key $key --algo $hashtype hmac-sha";
+ return pipe_through_program($msg, $program);
+}
+
+sub libgcrypt_dsa_pqggen($) {
+ my $mod = shift;
+
+ my $program = "fipsdrv --keysize $mod dsa-pqg-gen";
+ return pipe_through_program("", $program);
+}
+
+sub libgcrypt_gen_dsakey($) {
+ my $file = shift;
+
+ my $program = "fipsdrv --keysize 1024 --key $file dsa-gen";
+ my $tmp;
+ my %ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ $tmp = pipe_through_program("", $program);
+ die "dsa key gen failed: file $file not created" if (! -f $file);
+
+ @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp);
+ return %ret;
+}
+
+sub libgcrypt_dsa_genpubkey($$$$$) {
+ my $filename = shift;
+ my $p = shift;
+ my $q = shift;
+ my $g = shift;
+ my $y = shift;
+
+ my $sexp;
+
+ $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))";
+
+ open(FH, ">", $filename) or die;
+ print FH $sexp;
+ close FH;
+}
+
+sub libgcrypt_dsa_sign($$) {
+ my $data = shift;
+ my $keyfile = shift;
+ my $tmp;
+ my %ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign");
+ @ret{'Y', 'R', 'S'} = split(/\n/, $tmp);
+ return %ret;
+}
+
+sub libgcrypt_dsa_verify($$$$) {
+ my $data = shift;
+ my $keyfile = shift;
+ my $r = shift;
+ my $s = shift;
+
+ my $ret;
+
+ die "ARCFOUR not available for DSA" if $opt{'R'};
+
+ my $sigfile = "$keyfile.sig";
+ open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
+ print FH "(sig-val(dsa(r #$r#)(s #$s#)))";
+ close FH;
+
+ $ret = pipe_through_program($data,
+ "fipsdrv --key $keyfile --signature $sigfile dsa-verify");
+ unlink ($sigfile);
+ # Parse through the output information
+ return ($ret =~ /GOOD signature/);
+}
+
+######### End of libgcrypt implementation ################
+
+################################################################
+###### Vendor1 interface functions
+################################################################
+
+sub vendor1_encdec($$$$$) {
+ my $key=shift;
+ my $iv=shift;
+ my $cipher=shift;
+ my $enc = (shift) ? "encrypt" : "decrypt";
+ my $data=shift;
+
+ $data=hex2bin($data);
+ my $program = "./aes $enc $key";
+ $data=pipe_through_program($data,$program);
+ return bin2hex($data);
+}
+
+sub vendor1_state_cipher($$$$$) {
+ my $cipher = shift;
+ my $encdec = shift;
+ my $bufsize = shift;
+ my $key = shift;
+ my $iv = shift;
+
+ $key = bin2hex($key);
+ my $enc = $encdec ? "encrypt": "decrypt";
+ my $out = "./aes $enc $key $bufsize";
+ return $out;
+}
+
+##### No other interface functions below this point ######
+##########################################################
+
+##########################################################
+# General helper routines
+
+# Executing a program by feeding STDIN and retrieving
+# STDOUT
+# $1: data string to be piped to the app on STDIN
+# rest: program and args
+# returns: STDOUT of program as string
+sub pipe_through_program($@) {
+ my $in = shift;
+ my @args = @_;
+
+ my ($CO, $CI);
+ my $pid = open2($CO, $CI, @args);
+
+ my $out = "";
+ my $len = length($in);
+ my $first = 1;
+ while (1) {
+ my $rin = "";
+ my $win = "";
+ # Output of prog is FD that we read
+ vec($rin,fileno($CO),1) = 1;
+ # Input of prog is FD that we write
+ # check for $first is needed because we can have NULL input
+ # that is to be written to the app
+ if ( $len > 0 || $first) {
+ (vec($win,fileno($CI),1) = 1);
+ $first=0;
+ }
+ # Let us wait for 100ms
+ my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1);
+ if ( $wout ) {
+ my $written = syswrite($CI, $in, $len);
+ die "broken pipe" if !defined $written;
+ $len -= $written;
+ substr($in, 0, $written) = "";
+ if ($len <= 0) {
+ close $CI or die "broken pipe: $!";
+ }
+ }
+ if ( $rout ) {
+ my $tmp_out = "";
+ my $bytes_read = sysread($CO, $tmp_out, 4096);
+ $out .= $tmp_out;
+ last if ($bytes_read == 0);
+ }
+ }
+ close $CO or die "broken pipe: $!";
+ waitpid $pid, 0;
+
+ return $out;
+}
+
+#
+# convert ASCII hex to binary input
+# $1 ASCII hex
+# return binary representation
+sub hex2bin($) {
+ my $in = shift;
+ my $len = length($in);
+ $len = 0 if ($in eq "00");
+ return pack("H$len", "$in");
+}
+
+#
+# convert binary input to ASCII hex
+# $1 binary value
+# return ASCII hex representation
+sub bin2hex($) {
+ my $in = shift;
+ my $len = length($in)*2;
+ return unpack("H$len", "$in");
+}
+
+# $1: binary byte (character)
+# returns: binary byte with odd parity using low bit as parity bit
+sub odd_par($) {
+ my $in = ord(shift);
+ my $odd_count=0;
+ for(my $i=1; $i<8; $i++) {
+ $odd_count++ if ($in & (1<<$i));
+ }
+
+ my $out = $in;
+ if ($odd_count & 1) { # check if parity is already odd
+ $out &= ~1; # clear the low bit
+ } else {
+ $out |= 1; # set the low bit
+ }
+
+ return chr($out);
+}
+
+# DES keys uses only the 7 high bits of a byte, the 8th low bit
+# is the parity bit
+# as the new key is calculated from oldkey XOR cipher in the MCT test,
+# the parity is not really checked and needs to be set to match
+# expectation (OpenSSL does not really care, but the FIPS
+# test result is expected that the key has the appropriate parity)
+# $1: arbitrary binary string
+# returns: string with odd parity set in low bit of each byte
+sub fix_key_parity($) {
+ my $in = shift;
+ my $out = "";
+ for (my $i = 0; $i < length($in); $i++) {
+ $out .= odd_par(substr($in, $i, 1));
+ }
+
+ return $out;
+}
+
+####################################################
+# DER/PEM utility functions
+# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html
+
+# Convert unsigned integer to base256 bigint bytes
+# $1 integer
+# returns base256 octet string
+sub int_base256_unsigned($) {
+ my $n = shift;
+
+ my $out = chr($n & 255);
+ while ($n>>=8) {
+ $out = chr($n & 255) . $out;
+ }
+
+ return $out;
+}
+
+# Convert signed integer to base256 bigint bytes
+# $1 integer
+# returns base256 octet string
+sub int_base256_signed($) {
+ my $n = shift;
+ my $negative = ($n < 0);
+
+ if ($negative) {
+ $n = -$n-1;
+ }
+
+ my $out = int_base256_unsigned($n);
+
+ if (ord(substr($out, 0, 1)) & 128) {
+ # it's supposed to be positive but has sign bit set,
+ # add a leading zero
+ $out = chr(0) . $out;
+ }
+
+ if ($negative) {
+ my $neg = chr(255) x length($out);
+ $out ^= $neg;
+ }
+
+ return $out;
+}
+
+# Length header for specified DER object length
+# $1 length as integer
+# return octet encoding for length
+sub der_len($) {
+ my $len = shift;
+
+ if ($len <= 127) {
+ return chr($len);
+ } else {
+ my $blen = int_base256_unsigned($len);
+
+ return chr(128 | length($blen)) . $blen;
+ }
+}
+
+# Prepend length header to object
+# $1 object as octet sequence
+# return length header for object followed by object as octets
+sub der_len_obj($) {
+ my $x = shift;
+
+ return der_len(length($x)) . $x;
+}
+
+# DER sequence
+# $* objects
+# returns DER sequence consisting of the objects passed as arguments
+sub der_seq {
+ my $seq = join("", @_);
+ return chr(0x30) . der_len_obj($seq);
+}
+
+# DER bitstring
+# $1 input octets (must be full octets, fractional octets not supported)
+# returns input encapsulated as bitstring
+sub der_bitstring($) {
+ my $x = shift;
+
+ $x = chr(0) . $x;
+
+ return chr(0x03) . der_len_obj($x);
+}
+
+# base-128-encoded integer, used for object numbers.
+# $1 integer
+# returns octet sequence
+sub der_base128($) {
+ my $n = shift;
+
+ my $out = chr($n & 127);
+
+ while ($n>>=7) {
+ $out = chr(128 | ($n & 127)) . $out;
+ }
+
+ return $out;
+}
+
+# Generating the PEM certificate string
+# (base-64-encoded DER string)
+# $1 DER string
+# returns octet sequence
+sub pem_cert($) {
+ my $n = shift;
+
+ my $out = "-----BEGIN PUBLIC KEY-----\n";
+ $out .= encode_base64($n);
+ $out .= "-----END PUBLIC KEY-----\n";
+
+ return $out;
+}
+
+# DER object identifier
+# $* sequence of id numbers
+# returns octets
+sub der_objectid {
+ my $v1 = shift;
+ my $v2 = shift;
+
+ my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_);
+
+ return chr(0x06) . der_len_obj($out);
+}
+
+# DER signed integer
+# $1 number as octet string (base 256 representation, high byte first)
+# returns number in DER integer encoding
+sub der_bigint($) {
+ my $x = shift;
+
+ return chr(0x02) . der_len_obj($x);
+}
+
+# DER positive integer with leading zeroes stripped
+# $1 number as octet string (base 256 representation, high byte first)
+# returns number in DER integer encoding
+sub der_pos_bigint($) {
+ my $x = shift;
+
+ # strip leading zero digits
+ $x =~ s/^[\0]+//;
+
+ # need to prepend a zero if high bit set, since it would otherwise be
+ # interpreted as a negative number. Also needed for number 0.
+ if (!length($x) || ord(substr($x, 0, 1)) >= 128) {
+ $x = chr(0) . $x;
+ }
+
+ return der_bigint($x);
+}
+
+# $1 number as signed integer
+# returns number as signed DER integer encoding
+sub der_int($) {
+ my $n = shift;
+
+ return der_bigint(int_base256_signed($n));
+}
+
+# the NULL object constant
+sub der_null() {
+ return chr(0x05) . chr(0x00);
+}
+
+# Unit test helper
+# $1 calculated result
+# $2 expected result
+# no return value, dies if results differ, showing caller's line number
+sub der_test($$) {
+ my $actual = bin2hex(shift);
+ my $expected = shift;
+
+ my @caller = caller;
+ $actual eq $expected or die "Error:line $caller[2]:assertion failed: "
+ ."$actual != $expected\n";
+}
+
+# Unit testing for the DER encoding functions
+# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html
+# No input, no output. Dies if unit tests fail.
+sub der_unit_test {
+ ## uncomment these if you want to test the test framework
+ #print STDERR "Unit test running\n";
+ #der_test chr(0), "42";
+
+ der_test der_null, "0500";
+
+ # length bytes
+ der_test der_len(1), "01";
+ der_test der_len(127), "7f";
+ der_test der_len(128), "8180";
+ der_test der_len(256), "820100";
+ der_test der_len(65536), "83010000";
+
+ # bigint
+ der_test der_bigint(chr(0)), "020100";
+ der_test der_bigint(chr(128)), "020180"; # -128
+ der_test der_pos_bigint(chr(128)), "02020080"; # +128
+ der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101";
+ der_test der_pos_bigint(chr(0)), "020100";
+
+ # integers (tests base256 conversion)
+ der_test der_int( 0), "020100";
+ der_test der_int( 127), "02017f";
+ der_test der_int( 128), "02020080";
+ der_test der_int( 256), "02020100";
+ der_test der_int( -1), "0201ff";
+ der_test der_int( -128), "020180";
+ der_test der_int( -129), "0202ff7f";
+ der_test der_int(-65536), "0203ff0000";
+ der_test der_int(-65537), "0203feffff";
+
+ # object encoding, "RSA Security"
+ der_test der_base128(840), "8648";
+ der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d";
+
+ # Combinations
+ der_test der_bitstring("ABCD"), "03050041424344";
+ der_test der_bitstring(der_null), "0303000500";
+ der_test der_seq(der_int(0), der_null), "30050201000500";
+
+ # The big picture
+ der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null),
+ der_bitstring(der_seq(der_pos_bigint(chr(5)),
+ der_pos_bigint(chr(3))))),
+ "3017300a06062a864886f70d05000309003006020105020103";
+}
+
+####################################################
+# OpenSSL missing functionality workarounds
+
+## Format of an RSA public key:
+# 0:d=0 hl=3 l= 159 cons: SEQUENCE
+# 3:d=1 hl=2 l= 13 cons: SEQUENCE
+# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
+# 16:d=2 hl=2 l= 0 prim: NULL
+# 18:d=1 hl=3 l= 141 prim: BIT STRING
+# [ sequence: INTEGER (n), INTEGER (e) ]
+
+# generate RSA pub key in PEM format
+# $1: filename where PEM key is to be stored
+# $2: n of the RSA key in hex
+# $3: e of the RSA key in hex
+# return: nothing, but file created
+sub gen_pubrsakey($$$) {
+ my $filename=shift;
+ my $n = shift;
+ my $e = shift;
+
+ # make sure the DER encoder works ;-)
+ der_unit_test();
+
+ # generate DER encoding of the public key
+
+ my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1);
+
+ my $der = der_seq(der_seq($rsaEncryption, der_null),
+ der_bitstring(der_seq(der_pos_bigint(hex2bin($n)),
+ der_pos_bigint(hex2bin($e)))));
+
+ open(FH, ">", $filename) or die;
+ print FH pem_cert($der);
+ close FH;
+
+}
+
+# generate RSA pub key in PEM format
+#
+# This implementation uses "openssl asn1parse -genconf" which was added
+# in openssl 0.9.8. It is not available in older openssl versions.
+#
+# $1: filename where PEM key is to be stored
+# $2: n of the RSA key in hex
+# $3: e of the RSA key in hex
+# return: nothing, but file created
+sub gen_pubrsakey_using_openssl($$$) {
+ my $filename=shift;
+ my $n = shift;
+ my $e = shift;
+
+ my $asn1 = "asn1=SEQUENCE:pubkeyinfo
+
+[pubkeyinfo]
+algorithm=SEQUENCE:rsa_alg
+pubkey=BITWRAP,SEQUENCE:rsapubkey
+
+[rsa_alg]
+algorithm=OID:rsaEncryption
+parameter=NULL
+
+[rsapubkey]
+n=INTEGER:0x$n
+
+e=INTEGER:0x$e";
+
+ open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?";
+ print FH $asn1;
+ close FH;
+ my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der");
+ system(@args) == 0 or die "system @args failed: $?";
+ @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der",
+ "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename");
+ system(@args) == 0 or die "system @args failed: $?";
+ die "RSA PEM formatted key file $filename was not created"
+ if (! -f $filename);
+
+ unlink("$filename.cnf");
+ unlink("$filename.der");
+}
+
+############################################
+# Test cases
+
+# This is the Known Answer Test
+# $1: the string that we have to put in front of the key
+# when printing the key
+# $2: crypto key1 in hex form
+# $3: crypto key2 in hex form (TDES, undef otherwise)
+# $4: crypto key3 in hex form (TDES, undef otherwise)
+# $5: IV in hex form
+# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
+# $7: cipher
+# $8: encrypt=1/decrypt=0
+# return: string formatted as expected by CAVS
+sub kat($$$$$$$$) {
+ my $keytype = shift;
+ my $key1 = shift;
+ my $key2 = shift;
+ my $key3 = shift;
+ my $iv = shift;
+ my $pt = shift;
+ my $cipher = shift;
+ my $enc = shift;
+
+ my $out = "";
+
+ $out .= "$keytype = $key1\n";
+
+ # this is the concardination of the keys for 3DES
+ if (defined($key2)) {
+ $out .= "KEY2 = $key2\n";
+ $key1 = $key1 . $key2;
+ }
+ if (defined($key3)) {
+ $out .= "KEY3 = $key3\n";
+ $key1= $key1 . $key3;
+ }
+
+ $out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
+ if ($enc) {
+ $out .= "PLAINTEXT = $pt\n";
+ $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n";
+ } else {
+ $out .= "CIPHERTEXT = $pt\n";
+ $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n";
+ }
+
+ return $out;
+}
+
+# This is the Known Answer Test for Hashes
+# $1: Plaintext in hex form
+# $2: hash
+# $3: hash length (undef if not applicable)
+# return: string formatted as expected by CAVS
+sub hash_kat($$$) {
+ my $pt = shift;
+ my $cipher = shift;
+ my $len = shift;
+
+ my $out = "";
+ $out .= "Len = $len\n" if (defined($len));
+ $out .= "Msg = $pt\n";
+
+ $pt = "" if(!$len);
+ $out .= "MD = " . &$hash($pt, $cipher) . "\n";
+ return $out;
+}
+
+# Known Answer Test for HMAC hash
+# $1: key length in bytes
+# $2: MAC length in bytes
+# $3: key for HMAC in hex form
+# $4: message to be hashed
+# return: string formatted as expected by CAVS
+sub hmac_kat($$$$) {
+ my $klen = shift;
+ my $tlen = shift;
+ my $key = shift;
+ my $msg = shift;
+
+ # XXX this is a hack - we need to decipher the HMAC REQ files in a more
+ # sane way
+ #
+ # This is a conversion table from the expected hash output size
+ # to the assumed hash type - we only define here the block size of
+ # the underlying hashes and do not allow any truncation
+ my %hashtype = (
+ 20 => 1,
+ 28 => 224,
+ 32 => 256,
+ 48 => 384,
+ 64 => 512
+ );
+
+ die "Hash output size $tlen is not supported!"
+ if(!defined($hashtype{$tlen}));
+
+ my $out = "";
+ $out .= "Klen = $klen\n";
+ $out .= "Tlen = $tlen\n";
+ $out .= "Key = $key\n";
+ $out .= "Msg = $msg\n";
+ $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n";
+
+ return $out;
+}
+
+
+# Cipher Monte Carlo Testing
+# $1: the string that we have to put in front of the key
+# when printing the key
+# $2: crypto key1 in hex form
+# $3: crypto key2 in hex form (TDES, undef otherwise)
+# $4: crypto key3 in hex form (TDES, undef otherwise)
+# $5: IV in hex form
+# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
+# $7: cipher
+# $8: encrypt=1/decrypt=0
+# return: string formatted as expected by CAVS
+sub crypto_mct($$$$$$$$) {
+ my $keytype = shift;
+ my $key1 = hex2bin(shift);
+ my $key2 = shift;
+ my $key3 = shift;
+ my $iv = hex2bin(shift);
+ my $source_data = hex2bin(shift);
+ my $cipher = shift;
+ my $enc = shift;
+
+ my $out = "";
+
+ $key2 = hex2bin($key2) if (defined($key2));
+ $key3 = hex2bin($key3) if (defined($key3));
+ my $bufsize = length($source_data);
+
+ # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests
+ # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests
+ # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests
+ my $ciph = substr($cipher,0,3);
+ my $oloop=100;
+ my $iloop=1000;
+ if ($ciph =~ /des/) {$oloop=400;$iloop=10000;}
+
+ for (my $i=0; $i<$oloop; ++$i) {
+ $out .= "COUNT = $i\n";
+ if (defined($key2)) {
+ $out .= "$keytype = ". bin2hex($key1). "\n";
+ $out .= "KEY2 = ". bin2hex($key2). "\n";
+ $key1 = $key1 . $key2;
+ } else {
+ $out .= "$keytype = ". bin2hex($key1). "\n";
+ }
+ if(defined($key3)) {
+ $out .= "KEY3 = ". bin2hex($key3). "\n";
+ $key1 = $key1 . $key3;
+ }
+ my $keylen = length($key1);
+
+ $out .= "IV = ". bin2hex($iv) . "\n"
+ if (defined($iv) && $iv ne "");
+
+ if ($enc) {
+ $out .= "PLAINTEXT = ". bin2hex($source_data). "\n";
+ } else {
+ $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n";
+ }
+ my ($CO, $CI);
+ my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv);
+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/);
+ my $pid = open2($CO, $CI, $cipher_imp);
+
+ my $calc_data = $iv; # CT[j]
+ my $old_calc_data; # CT[j-1]
+ my $old_old_calc_data; # CT[j-2]
+ my $next_source;
+
+ # TDES inner loop implements logic within driver
+ if ($cipher =~ /des/) {
+ # Need to provide a dummy IV in case of ECB mode.
+ my $iv_arg = (defined($iv) && $iv ne "")
+ ? bin2hex($iv)
+ : "00"x(length($source_data));
+ print $CI "1\n"
+ .$iloop."\n"
+ .bin2hex($key1)."\n"
+ .$iv_arg."\n"
+ .bin2hex($source_data)."\n\n" or die;
+ chomp(my $line = <$CO>);
+ $calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $old_calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $old_old_calc_data = hex2bin($line);
+ chomp($line = <$CO>);
+ $iv = hex2bin($line) if (defined($iv) && $iv ne "");
+ chomp($line = <$CO>);
+ $next_source = hex2bin($line);
+ # Skip over empty line.
+ $line = <$CO>;
+ } else {
+ for (my $j = 0; $j < $iloop; ++$j) {
+ $old_old_calc_data = $old_calc_data;
+ $old_calc_data = $calc_data;
+
+ #print STDERR "source_data=", bin2hex($source_data), "\n";
+ syswrite $CI, $source_data or die $!;
+ my $len = sysread $CO, $calc_data, $bufsize;
+
+ #print STDERR "len=$len, bufsize=$bufsize\n";
+ die if $len ne $bufsize;
+ #print STDERR "calc_data=", bin2hex($calc_data), "\n";
+
+ if ( (!$enc && $ciph =~ /des/) ||
+ $ciph =~ /rc4/ ||
+ $cipher =~ /ecb/ ) {
+ #TDES in decryption mode, RC4 and ECB mode
+ #have a special rule
+ $source_data = $calc_data;
+ } else {
+ $source_data = $old_calc_data;
+ }
+ }
+ }
+ close $CO;
+ close $CI;
+ waitpid $pid, 0;
+
+ if ($enc) {
+ $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n";
+ } else {
+ $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n";
+ }
+
+ if ( $ciph =~ /aes/ ) {
+ $key1 ^= substr($old_calc_data . $calc_data, -$keylen);
+ #print STDERR bin2hex($key1)."\n";
+ } elsif ( $ciph =~ /des/ ) {
+ die "Wrong keylen $keylen" if ($keylen != 24);
+
+ # $nkey needed as $key holds the concatenation of the
+ # old key atm
+ my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data);
+ #print STDERR "KEY1 = ". bin2hex($nkey)."\n";
+ if (substr($key1,0,8) ne substr($key1,8,8)) {
+ #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n";
+ $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data));
+ } else {
+ #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n";
+ $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data));
+ }
+ #print STDERR "KEY2 = ". bin2hex($key2)."\n";
+ if ( substr($key1,0,8) eq substr($key1,16)) {
+ #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n";
+ $key3 = fix_key_parity((substr($key1,16) ^ $calc_data));
+ } else {
+ #print STDERR "KEY3 recalc: all KEYs are independent\n";
+ $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data));
+ }
+ #print STDERR "KEY3 = ". bin2hex($key3)."\n";
+
+ # reset the first key - concardination happens at
+ # beginning of loop
+ $key1=$nkey;
+ } elsif ($ciph =~ /rc4/ ) {
+ $key1 ^= substr($calc_data, 0, 16);
+ #print STDERR bin2hex($key1)."\n";
+ } else {
+ die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing";
+ }
+
+ if ($cipher =~ /des-ede3-ofb/) {
+ $source_data = $source_data ^ $next_source;
+ } elsif (!$enc && $cipher =~ /des-ede3-cfb/) {
+ #TDES decryption CFB has a special rule
+ $source_data = $next_source;
+ } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) {
+ #No resetting of IV as the IV is all zero set initially (i.e. no IV)
+ $source_data = $calc_data;
+ } elsif (! $enc && $ciph =~ /des/ ) {
+ #TDES in decryption mode has a special rule
+ $iv = $old_calc_data;
+ $source_data = $calc_data;
+ } else {
+ $iv = $calc_data;
+ $source_data = $old_calc_data;
+ }
+ }
+
+ return $out;
+}
+
+# Hash Monte Carlo Testing
+# $1: Plaintext in hex form
+# $2: hash
+# return: string formatted as expected by CAVS
+sub hash_mct($$) {
+ my $pt = shift;
+ my $cipher = shift;
+
+ my $out = "";
+
+ $out .= "Seed = $pt\n\n";
+
+ for (my $j=0; $j<100; ++$j) {
+ $out .= "COUNT = $j\n";
+ my $md0=$pt;
+ my $md1=$pt;
+ my $md2=$pt;
+ for (my $i=0; $i<1000; ++$i) {
+ #print STDERR "outer loop $j; inner loop $i\n";
+ my $mi= $md0 . $md1 . $md2;
+ $md0=$md1;
+ $md1=$md2;
+ $md2 = &$hash($mi, $cipher);
+ $md2 =~ s/\n//;
+ }
+ $out .= "MD = $md2\n\n";
+ $pt=$md2;
+ }
+
+ return $out;
+}
+
+# RSA SigGen test
+# $1: Message to be signed in hex form
+# $2: Hash algorithm
+# $3: file name with RSA key in PEM form
+# return: string formatted as expected by CAVS
+sub rsa_siggen($$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $keyfile = shift;
+
+ my $out = "";
+
+ $out .= "SHAAlg = $cipher\n";
+ $out .= "Msg = $data\n";
+ $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n";
+
+ return $out;
+}
+
+# RSA SigVer test
+# $1: Message to be verified in hex form
+# $2: Hash algoritm
+# $3: Signature of message in hex form
+# $4: n of the RSA key in hex in hex form
+# $5: e of the RSA key in hex in hex form
+# return: string formatted as expected by CAVS
+sub rsa_sigver($$$$$) {
+ my $data = shift;
+ my $cipher = shift;
+ my $signature = shift;
+ my $n = shift;
+ my $e = shift;
+
+ my $out = "";
+
+ $out .= "SHAAlg = $cipher\n";
+ $out .= "e = $e\n";
+ $out .= "Msg = $data\n";
+ $out .= "S = $signature\n";
+
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ my $keyfile = "rsa_sigver.tmp.$$";
+ gen_pubrsakey($keyfile, $n, $e);
+
+ my $sigfile = "$keyfile.sig";
+ open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
+ print FH hex2bin($signature);
+ close FH;
+
+ $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n");
+
+ unlink($keyfile);
+ unlink($sigfile);
+
+ return $out;
+}
+
+# RSA X9.31 key generation test
+# $1 modulus size
+# $2 e
+# $3 xp1
+# $4 xp2
+# $5 Xp
+# $6 xq1
+# $7 xq2
+# $8 Xq
+# return: string formatted as expected by CAVS
+sub rsa_keygen($$$$$$$$) {
+ my $modulus = shift;
+ my $e = shift;
+ my $xp1 = shift;
+ my $xp2 = shift;
+ my $Xp = shift;
+ my $xq1 = shift;
+ my $xq2 = shift;
+ my $Xq = shift;
+
+ my $out = "";
+
+ my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq);
+
+ my ($P, $Q, $N, $D) = split(/\n/, $ret);
+
+ $out .= "e = $e\n";
+ $out .= "xp1 = $xp1\n";
+ $out .= "xp2 = $xp2\n";
+ $out .= "Xp = $Xp\n";
+ $out .= "p = $P\n";
+ $out .= "xq1 = $xq1\n";
+ $out .= "xq2 = $xq2\n";
+ $out .= "Xq = $Xq\n";
+ $out .= "q = $Q\n";
+ $out .= "n = $N\n";
+ $out .= "d = $D\n\n";
+
+ return $out;
+
+}
+
+# X9.31 RNG test
+# $1 key for the AES cipher
+# $2 DT value
+# $3 V value
+# $4 type ("VST", "MCT")
+# return: string formatted as expected by CAVS
+sub rngx931($$$$) {
+ my $key=shift;
+ my $dt=shift;
+ my $v=shift;
+ my $type=shift;
+
+ my $out = "Key = $key\n";
+ $out .= "DT = $dt\n";
+ $out .= "V = $v\n";
+
+ my $count = 1;
+ $count = 10000 if ($type eq "MCT");
+
+ my $rnd_val = "";
+
+ # we read 16 bytes from RNG
+ my $bufsize = 16;
+
+ my ($CO, $CI);
+ my $rng_imp = &$state_rng($key, $dt, $v);
+ my $pid = open2($CO, $CI, $rng_imp);
+ for (my $i = 0; $i < $count; ++$i) {
+ my $len = sysread $CO, $rnd_val, $bufsize;
+ #print STDERR "len=$len, bufsize=$bufsize\n";
+ die "len=$len != bufsize=$bufsize" if $len ne $bufsize;
+ #print STDERR "calc_data=", bin2hex($rnd_val), "\n";
+ }
+ close $CO;
+ close $CI;
+ waitpid $pid, 0;
+
+ $out .= "R = " . bin2hex($rnd_val) . "\n\n";
+
+ return $out;
+}
+
+# DSA PQGGen test
+# $1 modulus size
+# $2 number of rounds to perform the test
+# return: string formatted as expected by CAVS
+sub dsa_pqggen_driver($$) {
+ my $mod = shift;
+ my $rounds = shift;
+
+ my $out = "";
+ for(my $i=0; $i<$rounds; $i++) {
+ my $ret = &$dsa_pqggen($mod);
+ my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret);
+ die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen"
+ if (!defined($P) || !defined($Q) || !defined($G) ||
+ !defined($Seed) || !defined($c) || !defined($H));
+
+ # now change the counter to decimal as CAVS wants decimal
+ # counter value although all other is HEX
+ $c = hex($c);
+
+ $out .= "P = $P\n";
+ $out .= "Q = $Q\n";
+ $out .= "G = $G\n";
+ $out .= "Seed = $Seed\n";
+ $out .= "c = $c\n";
+ $out .= "H = $H\n\n";
+ }
+
+ return $out;
+}
+
+
+# DSA SigGen test
+# $1: Message to be signed in hex form
+# $2: file name with DSA key in PEM form
+# return: string formatted as expected by CAVS
+sub dsa_siggen($$) {
+ my $data = shift;
+ my $keyfile = shift;
+
+ my $out = "";
+
+ my %ret = &$dsa_sign($data, $keyfile);
+
+ $out .= "Msg = $data\n";
+ $out .= "Y = " . $ret{'Y'} . "\n";
+ $out .= "R = " . $ret{'R'} . "\n";
+ $out .= "S = " . $ret{'S'} . "\n";
+
+ return $out;
+}
+
+
+# DSA signature verification
+# $1 modulus
+# $2 P
+# $3 Q
+# $4 G
+# $5 Y - public key
+# $6 r
+# $7 s
+# $8 message to be verified
+# return: string formatted as expected by CAVS
+sub dsa_sigver($$$$$$$$) {
+ my $modulus = shift;
+ my $p = shift;
+ my $q = shift;
+ my $g = shift;
+ my $y = shift;
+ my $r = shift;
+ my $s = shift;
+ my $msg = shift;
+
+ my $out = "";
+
+ #PQG are already printed - do not print them here
+
+ $out .= "Msg = $msg\n";
+ $out .= "Y = $y\n";
+ $out .= "R = $r\n";
+ $out .= "S = $s\n";
+
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ my $keyfile = "dsa_sigver.tmp.$$";
+ &$dsa_genpubkey($keyfile, $p, $q, $g, $y);
+
+ $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n");
+
+ unlink($keyfile);
+
+ return $out;
+}
+
+##############################################################
+# Parser of input file and generator of result file
+#
+
+sub usage() {
+
+ print STDERR "Usage:
+$0 [-R] [-D] [-I name] <CAVS-test vector file>
+
+-R execution of ARCFOUR instead of OpenSSL
+-I NAME Use interface style NAME:
+ openssl OpenSSL (default)
+ libgcrypt Libgcrypt
+-D SigGen and SigVer are executed with DSA
+ Please note that the DSA CAVS vectors do not allow distinguishing
+ them from the RSA vectors. As the RSA test is the default, you have
+ to supply this option to apply the DSA logic";
+}
+
+# Parser of CAVS test vector file
+# $1: Test vector file
+# $2: Output file for test results
+# return: nothing
+sub parse($$) {
+ my $infile = shift;
+ my $outfile = shift;
+
+ my $out = "";
+
+ # this is my cipher/hash type
+ my $cipher = "";
+
+ # Test type
+ # 1 - cipher known answer test
+ # 2 - cipher Monte Carlo test
+ # 3 - hash known answer test
+ # 4 - hash Monte Carlo test
+ # 5 - RSA signature generation
+ # 6 - RSA signature verification
+ my $tt = 0;
+
+ # Variables for tests
+ my $keytype = ""; # we can have "KEY", "KEYs", "KEY1"
+ my $key1 = "";
+ my $key2 = undef; #undef needed for allowing
+ my $key3 = undef; #the use of them as input variables
+ my $pt = "";
+ my $enc = 1;
+ my $iv = "";
+ my $len = undef; #see key2|3
+ my $n = "";
+ my $e = "";
+ my $signature = "";
+ my $rsa_keyfile = "";
+ my $dsa_keyfile = "";
+ my $dt = "";
+ my $v = "";
+ my $klen = "";
+ my $tlen = "";
+ my $modulus = "";
+ my $capital_n = 0;
+ my $capital_p = "";
+ my $capital_q = "";
+ my $capital_g = "";
+ my $capital_y = "";
+ my $capital_r = "";
+ my $xp1 = "";
+ my $xp2 = "";
+ my $Xp = "";
+ my $xq1 = "";
+ my $xq2 = "";
+ my $Xq = "";
+
+ my $mode = "";
+
+ open(IN, "<$infile");
+ while(<IN>) {
+
+ my $line = $_;
+ chomp($line);
+ $line =~ s/\r//;
+
+ my $keylen = "";
+
+ # Mode and type check
+ # consider the following parsed line
+ # '# AESVS MCT test data for CBC'
+ # '# TDES Multi block Message Test for CBC'
+ # '# INVERSE PERMUTATION - KAT for CBC'
+ # '# SUBSTITUTION TABLE - KAT for CBC'
+ # '# TDES Monte Carlo (Modes) Test for CBC'
+ # '# "SHA-1 Monte" information for "IBMRHEL5"'
+ # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"'
+ # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"'
+ # '#RC4VS MCT test data'
+
+ # avoid false positives from user specified 'for "PRODUCT"' strings
+ my $tmpline = $line;
+ $tmpline =~ s/ for ".*"//;
+
+ ##### Extract cipher
+ # XXX there may be more - to be added
+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
+ if ($tmpline =~ /CBC/) { $mode="cbc"; }
+ elsif ($tmpline =~ /ECB/) { $mode="ecb"; }
+ elsif ($tmpline =~ /OFB/) { $mode="ofb"; }
+ elsif ($tmpline =~ /CFB/) { $mode="cfb"; }
+ #we do not need mode as the cipher is already clear
+ elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; }
+ elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; }
+ elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; }
+ elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; }
+ elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; }
+ #we do not need mode as the cipher is already clear
+ elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; }
+ elsif ($tmpline =~ /SigGen|SigVer/) {
+ die "Error: X9.31 is not supported"
+ if ($tmpline =~ /X9/);
+ $cipher="sha1"; #place holder - might be overwritten later
+ }
+
+ if ($tmpline =~ /^#.*AESVS/) {
+ # AES cipher (part of it)
+ $cipher="aes";
+ }
+ if ($tmpline =~ /^#.*(TDES|KAT)/) {
+ # TDES cipher (full definition)
+ # the FIPS-140 test generator tool does not produce
+ # machine readable output!
+ if ($mode eq "cbc") { $cipher="des-ede3-cbc"; }
+ if ($mode eq "ecb") { $cipher="des-ede3"; }
+ if ($mode eq "ofb") { $cipher="des-ede3-ofb"; }
+ if ($mode eq "cfb") { $cipher="des-ede3-cfb"; }
+ }
+
+ # check for RNG
+ if ($tmpline =~ /ANSI X9\.31/) {
+ # change the tmpline to add the type of the
+ # test which is ONLY visible from the file
+ # name :-(
+ if ($infile =~ /MCT\.req/) {
+ $tmpline .= " MCT";
+ } elsif ($infile =~ /VST\.req/) {
+ $tmpline .= " VST";
+ } else {
+ die "Unexpected cipher type with $infile";
+ }
+ }
+
+ if ($tt == 0) {
+ ##### Identify the test type
+ if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
+ $tt = 13;
+ die "Interface function rsa_derive for RSA key generation not defined for tested library"
+ if (!defined($rsa_derive));
+ } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) {
+ $tt = 12;
+ die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library"
+ if (!defined($dsa_verify) || !defined($dsa_genpubkey));
+ } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
+ $tt = 11;
+ die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library"
+ if (!defined($dsa_sign) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /PQGGen/) {
+ $tt = 10;
+ die "Interface function for DSA PQGGen testing not defined for tested library"
+ if (!defined($dsa_pqggen));
+ } elsif ($tmpline =~ /Hash sizes tested/) {
+ $tt = 9;
+ die "Interface function hmac for HMAC testing not defined for tested library"
+ if (!defined($hmac));
+ } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) {
+ $tt = 8;
+ die "Interface function state_rng for RNG MCT not defined for tested library"
+ if (!defined($state_rng));
+ } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) {
+ $tt = 7;
+ die "Interface function state_rng for RNG KAT not defined for tested library"
+ if (!defined($state_rng));
+ } elsif ($tmpline =~ /SigVer/ ) {
+ $tt = 6;
+ die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library"
+ if (!defined($rsa_verify) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /SigGen/ ) {
+ $tt = 5;
+ die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library"
+ if (!defined($rsa_sign) || !defined($gen_rsakey));
+ } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) {
+ $tt = 4;
+ die "Interface function hash for Hashing not defined for tested library"
+ if (!defined($hash));
+ } elsif ($tmpline =~ /Monte|MCT|Carlo/) {
+ $tt = 2;
+ die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
+ if (!defined($state_cipher) || !defined($state_cipher_des));
+ } elsif ($cipher =~ /^sha/) {
+ $tt = 3;
+ die "Interface function hash for Hashing not defined for tested library"
+ if (!defined($hash));
+ } else {
+ $tt = 1;
+ die "Interface function encdec for Encryption/Decryption not defined for tested library"
+ if (!defined($encdec));
+ }
+ }
+ }
+
+ # This is needed as ARCFOUR does not operate with an IV
+ $iv = "00000000000000000000000000000000" if ($cipher eq "rc4"
+ && $iv eq "" );
+
+ # we are now looking for the string
+ # '# Key Length : 256'
+ # found in AES
+ if ($tmpline =~ /^# Key Length.*?(128|192|256)/) {
+ if ($cipher eq "aes") {
+ $cipher="$cipher-$1-$mode";
+ } else {
+ die "Error: Key length $1 given for cipher $cipher which is unexpected";
+ }
+ }
+
+ # Get the test data
+ if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG
+ die "KEY seen twice - input file crap" if ($key1 ne "");
+ $keytype=$1;
+ $key1=$2;
+ $key1 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG
+ die "KEY seen twice - input file crap" if ($key1 ne "");
+ $keytype=$1;
+ $key1=$2;
+ $key1 =~ s/\s//g; #replace potential white spaces
+ $key2 = $key1;
+ $key3 = $key1;
+ }
+ elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES
+ die "First key not set, but got already second key - input file crap" if ($key1 eq "");
+ die "KEY2 seen twice - input file crap" if (defined($key2));
+ $key2=$1;
+ $key2 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES
+ die "Second key not set, but got already third key - input file crap" if ($key2 eq "");
+ die "KEY3 seen twice - input file crap" if (defined($key3));
+ $key3=$1;
+ $key3 =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers
+ die "IV seen twice - input file crap" if ($iv ne "");
+ $iv=$1;
+ $iv =~ s/\s//g; #replace potential white spaces
+ }
+ elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers
+ if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
+ die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
+ $pt=$1;
+ $pt =~ s/\s//g; #replace potential white spaces
+ $enc=1;
+ }
+ }
+ elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers
+ if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
+ die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
+ $pt=$1;
+ $pt =~ s/\s//g; #replace potential white spaces
+ $enc=0;
+ }
+ }
+ elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs
+ $len=$1;
+ }
+ elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs
+ die "Msg/Seed seen twice - input file crap" if ($pt ne "");
+ $pt=$2;
+ }
+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests
+ $modulus = $1;
+ $out .= $line . "\n\n"; # print it
+ # generate the private key with given bit length now
+ # as we have the required key length in bit
+ if ($tt == 11) {
+ $dsa_keyfile = "dsa_siggen.tmp.$$";
+ my %pqg = &$gen_dsakey($dsa_keyfile);
+ $out .= "P = " . $pqg{'P'} . "\n";
+ $out .= "Q = " . $pqg{'Q'} . "\n";
+ $out .= "G = " . $pqg{'G'} . "\n";
+ } elsif ( $tt == 5 ) {
+ # XXX maybe a secure temp file name is better here
+ # but since it is not run on a security sensitive
+ # system, I hope that this is fine
+ $rsa_keyfile = "rsa_siggen.tmp.$$";
+ &$gen_rsakey($modulus, $rsa_keyfile);
+ my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile");
+ $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/;
+ $out .= "n = $modulus\n";
+ $out .= "\ne = 10001\n"
+ }
+ }
+ elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests
+ $cipher=$1;
+ }
+ elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests
+ $out .= $line . "\n";
+ $n=$1;
+ }
+ elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests
+ $e=$1;
+ }
+ elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests
+ die "S seen twice - input file crap" if ($signature ne "");
+ $signature=$1;
+ }
+ elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests
+ die "DT seen twice - check input file"
+ if ($dt ne "");
+ $dt=$1;
+ }
+ elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests
+ die "V seen twice - check input file"
+ if ($v ne "");
+ $v=$1;
+ }
+ elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests
+ die "Klen seen twice - check input file"
+ if ($klen ne "");
+ $klen=$1;
+ }
+ elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests
+ die "Tlen seen twice - check input file"
+ if ($tlen ne "");
+ $tlen=$1;
+ }
+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen
+ die "N seen twice - check input file"
+ if ($capital_n);
+ $capital_n = $1;
+ }
+ elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer
+ die "P seen twice - check input file"
+ if ($capital_p);
+ $capital_p = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer
+ die "Q seen twice - check input file"
+ if ($capital_q);
+ $capital_q = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer
+ die "G seen twice - check input file"
+ if ($capital_g);
+ $capital_g = $1;
+ $out .= $line . "\n"; # print it
+ }
+ elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer
+ die "Y seen twice - check input file"
+ if ($capital_y);
+ $capital_y = $1;
+ }
+ elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer
+ die "R seen twice - check input file"
+ if ($capital_r);
+ $capital_r = $1;
+ }
+ elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
+ die "xp1 seen twice - check input file"
+ if ($xp1);
+ $xp1 = $1;
+ }
+ elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen
+ die "xp2 seen twice - check input file"
+ if ($xp2);
+ $xp2 = $1;
+ }
+ elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen
+ die "Xp seen twice - check input file"
+ if ($Xp);
+ $Xp = $1;
+ }
+ elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen
+ die "xq1 seen twice - check input file"
+ if ($xq1);
+ $xq1 = $1;
+ }
+ elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen
+ die "xq2 seen twice - check input file"
+ if ($xq2);
+ $xq2 = $1;
+ }
+ elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen
+ die "Xq seen twice - check input file"
+ if ($Xq);
+ $Xq = $1;
+ }
+ else {
+ $out .= $line . "\n";
+ }
+
+ # call tests if all input data is there
+ if ($tt == 1) {
+ if ($key1 ne "" && $pt ne "" && $cipher ne "") {
+ $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
+ $keytype = "";
+ $key1 = "";
+ $key2 = undef;
+ $key3 = undef;
+ $iv = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 2) {
+ if ($key1 ne "" && $pt ne "" && $cipher ne "") {
+ $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
+ $keytype = "";
+ $key1 = "";
+ $key2 = undef;
+ $key3 = undef;
+ $iv = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 3) {
+ if ($pt ne "" && $cipher ne "") {
+ $out .= hash_kat($pt, $cipher, $len);
+ $pt = "";
+ $len = undef;
+ }
+ }
+ elsif ($tt == 4) {
+ if ($pt ne "" && $cipher ne "") {
+ $out .= hash_mct($pt, $cipher);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 5) {
+ if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") {
+ $out .= rsa_siggen($pt, $cipher, $rsa_keyfile);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 6) {
+ if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") {
+ $out .= rsa_sigver($pt, $cipher, $signature, $n, $e);
+ $pt = "";
+ $signature = "";
+ }
+ }
+ elsif ($tt == 7 ) {
+ if ($key1 ne "" && $dt ne "" && $v ne "") {
+ $out .= rngx931($key1, $dt, $v, "VST");
+ $key1 = "";
+ $dt = "";
+ $v = "";
+ }
+ }
+ elsif ($tt == 8 ) {
+ if ($key1 ne "" && $dt ne "" && $v ne "") {
+ $out .= rngx931($key1, $dt, $v, "MCT");
+ $key1 = "";
+ $dt = "";
+ $v = "";
+ }
+ }
+ elsif ($tt == 9) {
+ if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") {
+ $out .= hmac_kat($klen, $tlen, $key1, $pt);
+ $key1 = "";
+ $tlen = "";
+ $klen = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 10) {
+ if ($modulus ne "" && $capital_n > 0) {
+ $out .= dsa_pqggen_driver($modulus, $capital_n);
+ #$mod is not resetted
+ $capital_n = 0;
+ }
+ }
+ elsif ($tt == 11) {
+ if ($pt ne "" && $dsa_keyfile ne "") {
+ $out .= dsa_siggen($pt, $dsa_keyfile);
+ $pt = "";
+ }
+ }
+ elsif ($tt == 12) {
+ if ($modulus ne "" &&
+ $capital_p ne "" &&
+ $capital_q ne "" &&
+ $capital_g ne "" &&
+ $capital_y ne "" &&
+ $capital_r ne "" &&
+ $signature ne "" &&
+ $pt ne "") {
+ $out .= dsa_sigver($modulus,
+ $capital_p,
+ $capital_q,
+ $capital_g,
+ $capital_y,
+ $capital_r,
+ $signature,
+ $pt);
+
+ # We do not clear the domain values PQG and
+ # the modulus value as they
+ # are specified only once in a file
+ # and we do not need to print them as they
+ # are already printed above
+ $capital_y = "";
+ $capital_r = "";
+ $signature = "";
+ $pt = "";
+ }
+ }
+ elsif ($tt == 13) {
+ if($modulus ne "" &&
+ $e ne "" &&
+ $xp1 ne "" &&
+ $xp2 ne "" &&
+ $Xp ne "" &&
+ $xq1 ne "" &&
+ $xq2 ne "" &&
+ $Xq ne "") {
+ $out .= rsa_keygen($modulus,
+ $e,
+ $xp1,
+ $xp2,
+ $Xp,
+ $xq1,
+ $xq2,
+ $Xq);
+ $e = "";
+ $xp1 = "";
+ $xp2 = "";
+ $Xp = "";
+ $xq1 = "";
+ $xq2 = "";
+ $Xq = "";
+ }
+ }
+ elsif ($tt > 0) {
+ die "Test case $tt not defined";
+ }
+ }
+
+ close IN;
+ $out =~ s/\n/\r\n/g; # make it a dos file
+ open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?";
+ print OUT $out;
+ close OUT;
+
+}
+
+# Signalhandler
+sub cleanup() {
+ unlink("rsa_siggen.tmp.$$");
+ unlink("rsa_sigver.tmp.$$");
+ unlink("rsa_sigver.tmp.$$.sig");
+ unlink("rsa_sigver.tmp.$$.der");
+ unlink("rsa_sigver.tmp.$$.cnf");
+ unlink("dsa_siggen.tmp.$$");
+ unlink("dsa_sigver.tmp.$$");
+ unlink("dsa_sigver.tmp.$$.sig");
+ exit;
+}
+
+############################################################
+#
+# let us pretend to be C :-)
+sub main() {
+
+ usage() unless @ARGV;
+
+ getopts("DRI:", \%opt) or die "bad option";
+
+ ##### Set library
+
+ if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
+ print STDERR "Using OpenSSL interface functions\n";
+ $encdec = \&openssl_encdec;
+ $rsa_sign = \&openssl_rsa_sign;
+ $rsa_verify = \&openssl_rsa_verify;
+ $gen_rsakey = \&openssl_gen_rsakey;
+ $hash = \&openssl_hash;
+ $state_cipher = \&openssl_state_cipher;
+ } elsif ( $opt{'I'} eq 'libgcrypt' ) {
+ print STDERR "Using libgcrypt interface functions\n";
+ $encdec = \&libgcrypt_encdec;
+ $rsa_sign = \&libgcrypt_rsa_sign;
+ $rsa_verify = \&libgcrypt_rsa_verify;
+ $gen_rsakey = \&libgcrypt_gen_rsakey;
+ $rsa_derive = \&libgcrypt_rsa_derive;
+ $hash = \&libgcrypt_hash;
+ $state_cipher = \&libgcrypt_state_cipher;
+ $state_cipher_des = \&libgcrypt_state_cipher_des;
+ $state_rng = \&libgcrypt_state_rng;
+ $hmac = \&libgcrypt_hmac;
+ $dsa_pqggen = \&libgcrypt_dsa_pqggen;
+ $gen_dsakey = \&libgcrypt_gen_dsakey;
+ $dsa_sign = \&libgcrypt_dsa_sign;
+ $dsa_verify = \&libgcrypt_dsa_verify;
+ $dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
+ } else {
+ die "Invalid interface option given";
+ }
+
+ my $infile=$ARGV[0];
+ die "Error: Test vector file $infile not found" if (! -f $infile);
+
+ my $outfile = $infile;
+ # let us add .rsp regardless whether we could strip .req
+ $outfile =~ s/\.req$//;
+ if ($opt{'R'}) {
+ $outfile .= ".rc4";
+ } else {
+ $outfile .= ".rsp";
+ }
+ if (-f $outfile) {
+ die "Output file $outfile could not be removed: $?"
+ unless unlink($outfile);
+ }
+ print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n";
+
+ #Signal handler
+ $SIG{HUP} = \&cleanup;
+ $SIG{INT} = \&cleanup;
+ $SIG{QUIT} = \&cleanup;
+ $SIG{TERM} = \&cleanup;
+
+ # Do the job
+ parse($infile, $outfile);
+
+ cleanup();
+
+}
+
+###########################################
+# Call it
+main();
+1;
--- /dev/null
+#!/bin/sh
+# Run FIPS CAVS tests
+# Copyright 2008 Free Software Foundation, Inc.
+#
+# This file is free software; as a special exception the author gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# This file is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Instructions:
+#
+# 1. Cd to the libgcrypt/tests directory
+#
+# 2. Unpack the test vector tarball into subdirectory named "cavs".
+# An example directory layout after unpacking might be:
+# libgcrypt/tests/cavs/AES/req/CBCGFSbox128.req
+# libgcrypt/tests/cavs/AES/req/CFB128MCT128.req
+#
+# Note that below the "cavs" directory there should only be one
+# directory part named "req". Further avoid directory part
+# names "resp".
+#
+# 3. Run this script from the libgcrypt/tests directory:
+# ./cavs_tests.sh
+#
+# 4. Send the result file cavs/CAVS_results-*.zip to the testing lab.
+#
+
+# Stop script if something unexpected happens.
+set -e
+
+# A global flag to keep track of errors.
+errors_seen_file="$(pwd)/.#cavs_test.errors_seen.tmp"
+[ -f "$errors_seen_file" ] && rm "$errors_seen_file"
+continue_mode=no
+[ "$1" = "--continue" ] && continue_mode=yes
+
+
+# Function to run one test.
+# The argument is the request file name.
+function run_one_test () {
+ local reqfile="$1"
+ local rspfile
+ local tmprspfile
+ local respdir
+ local dflag=""
+
+ tmprspfile=$(echo "$reqfile" | sed 's,.req$,.rsp,')
+ rspfile=$(echo "$tmprspfile" | sed 's,/req/,/resp/,' )
+ respdir=$(dirname "$rspfile")
+ [ -f "$tmprspfile" ] && rm "$tmprspfile"
+ [ -d "$respdir" ] || mkdir "$respdir"
+ [ -f "$rspfile" ] && rm "$rspfile"
+
+ if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then
+ dflag="-D"
+ fi
+
+ if ./cavs_driver.pl -I libgcrypt $dflag "$reqfile"; then
+ if [ -f "$tmprspfile" ]; then
+ mv "$tmprspfile" "$rspfile"
+ else
+ echo "failed test: $reqfile" >&2
+ : >"$errors_seen_file"
+ fi
+ else
+ echo "failed test: $reqfile rc=$?" >&2
+ : >"$errors_seen_file"
+ fi
+}
+
+
+
+# Save date and system architecure to construct the output archive name
+DATE=$(date +%Y%m%d)
+ARCH=$(arch || echo unknown)
+result_file="CAVS_results-$ARCH-$DATE.zip"
+
+for f in fipsdrv cavs_driver.pl; do
+ if [ ! -f "./$f" ]; then
+ echo "required program \"$f\" missing in current directory" >&2
+ exit 2
+ fi
+done
+if [ ! -d cavs ]; then
+ echo "required directory \"cavs\" missing below current directory" >&2
+ exit 2
+fi
+if [ ! zip -h >/dev/null 2>&1 ]; then
+ echo "required program \"zip\" is not installed on this system" >&2
+ exit 2
+fi
+
+# Set the PATH to this directory so that the perl script is able to
+# find the test drivers.
+PATH=.:$PATH
+
+# Check whether there are any stale response files
+find cavs -type f -name "*.rsp" | ( while read f ; do
+ echo "Stale response file: $f" >&2
+ any=yes
+done
+if [ "$any" = "yes" ]; then
+ echo "Stale response files found" >&2
+ if [ "$continue_mode" != "yes" ]; then
+ echo "use option --continue if that is not a problem" >&2
+ exit 1
+ fi
+fi
+) || exit 1
+
+
+# Find all test files and run the tests.
+find cavs -type f -name "*.req" | while read f ; do
+ echo "Running test file $f" >&2
+ run_one_test "$f"
+ if [ -f "$errors_seen_file" ]; then
+ break;
+ fi
+done
+
+if [ -f "$errors_seen_file" ]; then
+ rm "$errors_seen_file"
+ echo "Error encountered - not packing up response file" >&2
+ exit 1
+fi
+
+echo "Packing up all response files" >&2
+cd cavs
+find . -type f -name "*rsp" -print | zip -@ "$result_file"
+
+echo "Result file is: cavs/$result_file" >&2
--- /dev/null
+/* curves.c - ECC curves regression tests
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+/* Number of curves defined in ../cipger/ecc.c */
+#define N_CURVES 12
+
+/* A real world sample public key. */
+static char const sample_key_1[] =
+"(public-key\n"
+" (ecdsa\n"
+" (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n"
+" (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n"
+" (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n"
+" (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"
+ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n"
+" (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n"
+" (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE"
+ "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n"
+" ))";
+static char const sample_key_1_curve[] = "NIST P-256";
+static unsigned int sample_key_1_nbits = 256;
+
+/* A made up sample public key. */
+static char const sample_key_2[] =
+"(public-key\n"
+" (ecdh\n"
+" (p #e95e4a5f737059dc60dfc7ad95b3d8139515620f#)\n"
+" (a #340e7be2a280eb74e2be61bada745d97e8f7c300#)\n"
+" (b #1e589a8595423412134faa2dbdec95c8d8675e58#)\n"
+" (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3"
+ "1667cb477a1a8ec338f94741669c976316da6321#)\n"
+" (n #e95e4a5f737059dc60df5991d45029409e60fc09#)\n"
+" (q #041111111111111111111111111111111111111111"
+ "2222222222222222222222222222222222222222#)\n"
+" ))";
+static char const sample_key_2_curve[] = "brainpoolP160r1";
+static unsigned int sample_key_2_nbits = 160;
+
+
+/* Program option flags. */
+static int verbose;
+static int error_count;
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+static void
+list_curves (void)
+{
+ int idx;
+ const char *name;
+ unsigned int nbits;
+
+ for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++)
+ {
+ if (verbose)
+ printf ("%s - %u bits\n", name, nbits);
+ }
+ if (idx != N_CURVES)
+ fail ("expected %d curves but got %d\n", N_CURVES, idx);
+ if (gcry_pk_get_curve (NULL, -1, NULL))
+ fail ("curve iteration failed\n");
+}
+
+
+static void
+check_matching (void)
+{
+ gpg_error_t err;
+ gcry_sexp_t key;
+ const char *name;
+ unsigned int nbits;
+
+ err = gcry_sexp_new (&key, sample_key_1, 0, 1);
+ if (err)
+ die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
+ name = gcry_pk_get_curve (key, 0, &nbits);
+ if (!name)
+ fail ("curve name not found for sample_key_1\n");
+ else if (strcmp (name, sample_key_1_curve))
+ fail ("expected curve name %s but got %s for sample_key_1\n",
+ sample_key_1_curve, name);
+ else if (nbits != sample_key_1_nbits)
+ fail ("expected curve size %u but got %u for sample_key_1\n",
+ sample_key_1_nbits, nbits);
+
+ gcry_sexp_release (key);
+
+ err = gcry_sexp_new (&key, sample_key_2, 0, 1);
+ if (err)
+ die ("parsing s-expression string failed: %s\n", gpg_strerror (err));
+ name = gcry_pk_get_curve (key, 0, &nbits);
+ if (!name)
+ fail ("curve name not found for sample_key_2\n");
+ else if (strcmp (name, sample_key_2_curve))
+ fail ("expected curve name %s but got %s for sample_key_2\n",
+ sample_key_2_curve, name);
+ else if (nbits != sample_key_2_nbits)
+ fail ("expected curve size %u but got %u for sample_key_2\n",
+ sample_key_2_nbits, nbits);
+
+ gcry_sexp_release (key);
+}
+
+
+static void
+check_get_params (void)
+{
+ gcry_sexp_t param;
+ const char *name;
+
+ param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve);
+ if (!param)
+ fail ("error gerring parameters for `%s'\n", sample_key_1_curve);
+
+ name = gcry_pk_get_curve (param, 0, NULL);
+ if (!name)
+ fail ("get_param: curve name not found for sample_key_1\n");
+ else if (strcmp (name, sample_key_1_curve))
+ fail ("get_param: expected curve name %s but got %s for sample_key_1\n",
+ sample_key_1_curve, name);
+
+ gcry_sexp_release (param);
+
+
+ param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve);
+ if (!param)
+ fail ("error gerring parameters for `%s'\n", sample_key_2_curve);
+
+ name = gcry_pk_get_curve (param, 0, NULL);
+ if (!name)
+ fail ("get_param: curve name not found for sample_key_2\n");
+ else if (strcmp (name, sample_key_2_curve))
+ fail ("get_param: expected curve name %s but got %s for sample_key_2\n",
+ sample_key_2_curve, name);
+
+ gcry_sexp_release (param);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ list_curves ();
+ check_matching ();
+ check_get_params ();
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* fips186-dsa.c - FIPS 186 DSA tests
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+static int verbose;
+static int error_count;
+
+static void
+info (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+}
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+static gcry_mpi_t
+mpi_from_string (const char *string)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, string, 0, NULL);
+ if (err)
+ die ("error converting string to mpi: %s\n", gpg_strerror (err));
+ return a;
+}
+
+/* Convert STRING consisting of hex characters into its binary
+ representation and return it as an allocated buffer. The valid
+ length of the buffer is returned at R_LENGTH. The string is
+ delimited by end of string. The function returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static void
+extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ gcry_mpi_t a, b;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ b = mpi_from_string (expected);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( gcry_mpi_cmp (a, b) )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+ gcry_sexp_release (l1);
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( alen != blen || memcmp (a, b, alen) )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_free (b);
+ gcry_sexp_release (l1);
+}
+
+static void
+extract_cmp_int (gcry_sexp_t sexp, const char *name, int expected)
+{
+ gcry_sexp_t l1;
+ char *a;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_string (l1, 1);
+ if (!a)
+ fail ("parameter \"%s\" missing in key\n", name);
+ else if ( strtoul (a, NULL, 10) != expected )
+ fail ("parameter \"%s\" does not match expected value\n", name);
+ gcry_free (a);
+ gcry_sexp_release (l1);
+}
+
+
+static void
+check_dsa_gen_186_2 (void)
+{
+ static struct {
+ int nbits;
+ const char *p, *q, *g;
+ const char *seed;
+ int counter;
+ const char *h;
+ } tbl[] = {
+ /* These tests are from FIPS 186-2, B.3.1. */
+ {
+ 1024,
+ "d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69",
+ "9c916d121de9a03f71fb21bc2e1c0d116f065a4f",
+ "8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44",
+ "0cb1990c1fd3626055d7a0096f8fa99807399871",
+ 98,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002"
+ },
+ {
+ 1024,
+ "f5c73304080353357de1b5967597c27d65f70aa2fe9b6aed1d0afc2b499adf22f"
+ "8e37937096d88548ac36c4a067f8353c7fed73f96f0d688b19b0624aedbae5dbb"
+ "0ee8835a4c269288c0e1d69479e701ee266bb767af39d748fe7d6afc73fdf44be"
+ "3eb6e661e599670061203e75fc8b3dbd59e40b54f358d0097013a0f3867f9",
+ "f8751166cf4f6f3b07c081fd2a9071f23ca1988d",
+ "1e288a442e02461c418ed67a66d24cacbeb8936fbde62ff995f5fd569dee6be62"
+ "4e4f0f9f8c8093f5d192ab3b3f9ae3f2665d95d27fb10e382f45cd356e7f4eb7a"
+ "665db432113ed06478f93b7cf188ec7a1ee97aec8f91ea7bfceaf8b6e7e5a349c"
+ "4ad3225362ef440c57cbc6e69df15b6699caac85f733555075f04781b2b33",
+ "34b3520d45d240a8861b82c8b61ffa16e67b5cce",
+ 622,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "c6c6f4f4eed927fb1c3b0c81010967e530658e6f9698ebe058b4f47b2dc8fcbc7"
+ "b69296b9e8b6cf55681181fe72492668061b262b0046a0d409902e269b0cb69a4"
+ "55ed1a086caf41927f5912bf0e0cbc45ee81a4f98bf6146f6168a228aec80e9cc"
+ "1162d6f6aa412efe82d4f18b95e34ab790daac5bd7aef0b22fa08ba5dbaad",
+ "d32b29f065c1394a30490b6fcbf812a32a8634ab",
+ "06f973c879e2e89345d0ac04f9c34ad69b9eff1680f18d1c8f3e1596c2e8fa8e1"
+ "ecef6830409e9012d4788bef6ec7414d09c981b47c941b77f39dfc49caff5e714"
+ "c97abe25a7a8b5d1fe88700bb96eff91cca64d53700a28b1146d81bad1212d231"
+ "80154c95a01f5aeebb553a8365c38a5ebe05539b51734233776ce9aff98b2",
+ "b6ec750da2f824cb42c5f7e28c81350d97f75125",
+ 185,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "b827a9dc9221a6ed1bec7b64d61232aacb2812f888b0a0b3a95033d7a22e77d0b"
+ "ff23bfeed0fb1281b21b8ff7421f0c727d1fb8aa2b843d6885f067e763f83d41f"
+ "d800ab15a7e2b12f71ec2058ee7bd62cd72c26989b272e519785da57bfa1f974b"
+ "c652e1a2d6cfb68477de5635fd019b37add656cff0b802558b31b6d2851e5",
+ "de822c03445b77cec4ad3a6fb0ca39ff97059ddf",
+ "65a9e2d43a378d7063813104586868cacf2fccd51aec1e0b6af8ba3e66dee6371"
+ "681254c3fb5e3929d65e3c4bcd20abd4ddc7cf815623e17b9fc92f02b8d44278b"
+ "848480ffd193104cf5612639511e45bd247708ff6028bd3824f8844c263b46c69"
+ "1f2076f8cd13c5d0be95f1f2a1a17ab1f7e5bc73500bac27d57b473ba9748",
+ "cd2221dd73815a75224e9fde7faf52829b81ac7a",
+ 62,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+ {
+ 1024,
+ "898a8d93e295c8ef2ffd46976225a1543640640d155a576fafa0be32136165803"
+ "ba2eff2782a2be75cc9ec65db6bd3238cca695b3a5a14726a2a314775c377d891"
+ "354b3de6c89e714a05599ca04132c987f889f72c4fe298ccb31f711c03b07e1d9"
+ "8d72af590754cf3847398b60cecd55a4611692b308809560a83880404c227",
+ "c6d786643d2acfc6b8d576863fda8cfbfbd5e03f",
+ "2fd38b8d21c58e8fb5315a177b8d5dc4c450d574e69348b7b9da367c26e72438d"
+ "af8372e7f0bee84ef5dcbbc3727194a2228431192f1779be24837f22a0e14d10d"
+ "5344da1b8b403df9f9b2655095b3d0f67418ed6cd989f35aa4232e4b7001764fb"
+ "e85d6b2c716980f13272fc4271ac1e234f7e24c023cfc2d2dc0aa1e9af2fb",
+ "73483e697599871af983a281e3afa22e0ed86b68",
+ 272,
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "00000000000000000000000000000000000000000000000000000000000000000"
+ "0000000000000000000000000000000000000000000000000000000000002",
+ },
+
+ /* These tests are generated by the OpenSSL FIPS version. */
+ {
+ 1024,
+ "A404363903FDCE86839BCFD953AAD2DA2B0E70CAED3B5FF5D68F15A1C4BB0A793C"
+ "A9D58FC956804C5901DE0AF99F345ED1A8617C687864BAC044B7C3C3E732A2B255"
+ "EC986AA76EA8CB0E0815B3E0E605650AF7D8058EE7E8EBCDEFFDAB8100D3FC1033"
+ "11BA3AB232EF06BB74BA9A949EC0C7ED324C19B202F4AB725BBB4080C9",
+ "C643946CEA8748E12D430C48DB038F9165814389",
+ "59B7E7BA0033CCE8E6837173420FBB382A784D4154A3C166043F5A68CB92945D16"
+ "892D4CC5585F2D28C780E75A6C20A379E2B58304C1E5FC0D8C15E4E89C4498C8BC"
+ "B90FB36ED8DC0489B9D0BC09EC4411FB0BFADF25485EEAB6700BE0ACF5C44A6ED7"
+ "44A015382FF9B8DA7EAA00DEA135FADC59212DBBFFC1537336FA4B7225",
+ "02708ab36e3f0bfd67ec3b8bd8829d03b84f56bd",
+ 50,
+ "02"
+ },
+ {
+ 1024,
+ "9C664033DB8B203D826F896D2293C62EF9351D5CFD0F4C0AD7EFDA4DDC7F15987"
+ "6A3C68CAB2586B44FD1BD4DEF7A17905D88D321DD77C4E1720D848CA21D79F9B3"
+ "D8F537338E09B44E9F481E8DA3C56569F63146596A050EF8FAEE8ACA32C666450"
+ "04F675C8806EB4025B0A5ECC39CE89983EA40A183A7CF5208BA958045ABD5",
+ "AD0D8CBA369AF6CD0D2BAC0B4CFCAF0A1F9BCDF7",
+ "74D717F7092A2AF725FDD6C2561D1DBE5AEE40203C638BA8B9F49003857873701"
+ "95A44E515C4E8B344F5CDC7F4A6D38097CD57675E7643AB9700692C69F0A99B0E"
+ "039FDDDFCA8CEB607BDB4ADF2834DE1690F5823FC8199FB8F6F29E5A583B6786A"
+ "C14C7E67106C3B30568CBB9383F89287D578159778EB18216799D16D46498",
+ "6481a12a50384888ee84b61024f7c9c685d6ac96",
+ 289,
+ "02"
+ },
+ {
+ 1024,
+
+ "B0DFB602EB8462B1DC8C2214A52B587D3E6842CCF1C38D0F7C7F967ED30CF6828"
+ "1E2675B3BAB594755FB1634E66B4C23936F0725A358F8DFF3C307E2601FD66D63"
+ "5B17270450C50BD2BEC29E0E9A471DF1C15B0191517952268A2763D4BD28B8503"
+ "B3399686272B76B11227F693D7833105EF70C2289C3194CF4527024B272DF",
+ "EA649C04911FAB5A41440287A517EF752A40354B",
+ "88C5A4563ECB949763E0B696CD04B21321360F54C0EE7B23E2CEDC30E9E486162"
+ "01BFB1619E7C54B653D1F890C50E04B29205F5E3E2F93A13B0751AF25491C5194"
+ "93C09DDF6B9C173B3846DFB0E7A5C870BBFC78419260C90E20315410691C8326C"
+ "858D7063E7921F3F601158E912C7EE487FF259202BEEB10F6D9E99190F696",
+ "5bf9d17bc62fbbf3d569c92bd4505586b2e5ef1a",
+ 626,
+ "02"
+ },
+ {
+ 1024,
+ "F783C08D7F9463E48BA87893805C4B34B63C85DF7EBDD9EBEE94DB4AF4E4A415C"
+ "F0F3793AE55096BA1199598798FA8403B28DED7F7C7AFD54FD535861A0150EF4D"
+ "5871465B13837CCF46BEB0A22F8D38DC7D6AE0E14A3845FD0C027CFA97791B977"
+ "CE2808BAD9B43CE69390C0F40016056722D82C0D7B1B27413D026A39D7DAD",
+ "A40D9EE456AED4C8A653FDB47B6629C0B843FE8F",
+ "DF876263E21F263AE6DA57409BD517DCEADB9216048F066D6B58867F8E59A5EEE"
+ "700283A946C1455534618979BE6C227673C1B803910262BD93BC94D5089850614"
+ "F3E29AB64E8C989A7E3E28FE670FFA3EE21DEEEC1AB0B60E1D8E2AA39663BADD7"
+ "2C9F957D7F3D4F17D9FDAD050EB373A6DEFD09F5DA752EAFE046836E14B67",
+ "8a9a57706f69f4f566252cdf6d5cbfdf2020150b",
+ 397,
+ "02"
+ },
+ {
+ 1024,
+ "D40E4F6461E145859CCF60FD57962840BD75FFF12C22F76626F566842252AD068"
+ "29745F0147056354F6C016CF12762B0E331787925B8128CF5AF81F9B176A51934"
+ "96D792430FF83C7B79BD595BDA10787B34600787FA552EFE3662F37B99AAD3F3A"
+ "093732680A01345192A19BECCE6BF5D498E44ED6BED5B0BA72AAD49E8276B",
+ "D12F1BD0AA78B99247FD9F18EAFEE5C136686EA5",
+ "468EBD20C99449C1E440E6F8E452C6A6BC7551C555FE5E94996E20CFD4DA3B9CC"
+ "58499D6CC2374CCF9C392715A537DE10CFCA8A6A37AFBD187CF6B88D26881E5F5"
+ "7521D9D2C9BBA51E7B87B070BBE73F5C5FE31E752CAF88183516D8503BAAC1159"
+ "928EF50DEE52D96F396B93FB4138D786464C315401A853E57C9A0F9D25839",
+ "30b3599944a914a330a3f49d11ec88f555422aef",
+ 678,
+ "02"
+ }
+ };
+ gpg_error_t err;
+ int tno;
+ gcry_sexp_t key_spec, key, pub_key, sec_key, seed_values;
+ gcry_sexp_t l1;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ if (verbose)
+ info ("generating FIPS 186-2 test key %d\n", tno);
+
+ {
+ void *data;
+ size_t datalen;
+
+ data = data_from_hex (tbl[tno].seed, &datalen);
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (dsa (nbits %d)(use-fips186-2)"
+ "(derive-parms(seed %b))))",
+ tbl[tno].nbits, (int)datalen, data);
+ gcry_free (data);
+ }
+ if (err)
+ die ("error creating S-expression %d: %s\n", tno, gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (err)
+ {
+ fail ("error generating key %d: %s\n", tno, gpg_strerror (err));
+ continue;
+ }
+
+ if (verbose > 1)
+ show_sexp ("generated key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ fail ("public part missing in key %d\n", tno);
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ fail ("private part missing in key %d\n", tno);
+
+ l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
+ if (!l1)
+ fail ("misc_key_info part missing in key %d\n", tno);
+ seed_values = gcry_sexp_find_token (l1, "seed-values", 0);
+ if (!seed_values)
+ fail ("seed-values part missing in key %d\n", tno);
+ gcry_sexp_release (l1);
+
+ extract_cmp_mpi (sec_key, "p", tbl[tno].p);
+ extract_cmp_mpi (sec_key, "q", tbl[tno].q);
+ extract_cmp_mpi (sec_key, "g", tbl[tno].g);
+
+ extract_cmp_data (seed_values, "seed", tbl[tno].seed);
+ extract_cmp_int (seed_values, "counter", tbl[tno].counter);
+ extract_cmp_mpi (seed_values, "h", tbl[tno].h);
+
+ gcry_sexp_release (seed_values);
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ gcry_sexp_release (key);
+ }
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ }
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version ("1.4.4"))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+
+ check_dsa_gen_186_2 ();
+
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* fipsdrv.c - A driver to help with FIPS CAVS tests.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_W32_SYSTEM
+# include <fcntl.h> /* We need setmode(). */
+#else
+# include <signal.h>
+#endif
+#include <assert.h>
+#include <unistd.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+#else
+# include <gcrypt.h>
+# define PACKAGE_BUGREPORT "devnull@example.org"
+# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
+#endif
+
+
+#define PGM "fipsdrv"
+
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+
+#define PRIV_CTL_INIT_EXTRNG_TEST 58
+#define PRIV_CTL_RUN_EXTRNG_TEST 59
+#define PRIV_CTL_DEINIT_EXTRNG_TEST 60
+#define PRIV_CTL_DISABLE_WEAK_KEY 61
+#define PRIV_CTL_GET_INPUT_VECTOR 62
+
+
+/* Verbose mode flag. */
+static int verbose;
+
+/* Binary input flag. */
+static int binary_input;
+
+/* Binary output flag. */
+static int binary_output;
+
+/* Base64 output flag. */
+static int base64_output;
+
+/* We need to know whether we are in loop_mode. */
+static int loop_mode;
+
+/* If true some functions are modified to print the output in the CAVS
+ response file format. */
+static int standalone_mode;
+
+
+/* ASN.1 classes. */
+enum
+{
+ UNIVERSAL = 0,
+ APPLICATION = 1,
+ ASNCONTEXT = 2,
+ PRIVATE = 3
+};
+
+
+/* ASN.1 tags. */
+enum
+{
+ TAG_NONE = 0,
+ TAG_BOOLEAN = 1,
+ TAG_INTEGER = 2,
+ TAG_BIT_STRING = 3,
+ TAG_OCTET_STRING = 4,
+ TAG_NULL = 5,
+ TAG_OBJECT_ID = 6,
+ TAG_OBJECT_DESCRIPTOR = 7,
+ TAG_EXTERNAL = 8,
+ TAG_REAL = 9,
+ TAG_ENUMERATED = 10,
+ TAG_EMBEDDED_PDV = 11,
+ TAG_UTF8_STRING = 12,
+ TAG_REALTIVE_OID = 13,
+ TAG_SEQUENCE = 16,
+ TAG_SET = 17,
+ TAG_NUMERIC_STRING = 18,
+ TAG_PRINTABLE_STRING = 19,
+ TAG_TELETEX_STRING = 20,
+ TAG_VIDEOTEX_STRING = 21,
+ TAG_IA5_STRING = 22,
+ TAG_UTC_TIME = 23,
+ TAG_GENERALIZED_TIME = 24,
+ TAG_GRAPHIC_STRING = 25,
+ TAG_VISIBLE_STRING = 26,
+ TAG_GENERAL_STRING = 27,
+ TAG_UNIVERSAL_STRING = 28,
+ TAG_CHARACTER_STRING = 29,
+ TAG_BMP_STRING = 30
+};
+
+/* ASN.1 Parser object. */
+struct tag_info
+{
+ int class; /* Object class. */
+ unsigned long tag; /* The tag of the object. */
+ unsigned long length; /* Length of the values. */
+ int nhdr; /* Length of the header (TL). */
+ unsigned int ndef:1; /* The object has an indefinite length. */
+ unsigned int cons:1; /* This is a constructed object. */
+};
+
+
+
+/* Print a error message and exit the process with an error code. */
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+static void
+showhex (const char *prefix, const void *buffer, size_t length)
+{
+ const unsigned char *p = buffer;
+
+ if (prefix)
+ fprintf (stderr, PGM ": %s: ", prefix);
+ while (length-- )
+ fprintf (stderr, "%02X", *p++);
+ if (prefix)
+ putc ('\n', stderr);
+}
+
+/* static void */
+/* show_sexp (const char *prefix, gcry_sexp_t a) */
+/* { */
+/* char *buf; */
+/* size_t size; */
+
+/* if (prefix) */
+/* fputs (prefix, stderr); */
+/* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */
+/* buf = gcry_xmalloc (size); */
+
+/* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */
+/* fprintf (stderr, "%.*s", (int)size, buf); */
+/* gcry_free (buf); */
+/* } */
+
+
+/* Convert STRING consisting of hex characters into its binary
+ representation and store that at BUFFER. BUFFER needs to be of
+ LENGTH bytes. The function checks that the STRING will convert
+ exactly to LENGTH bytes. The string is delimited by either end of
+ string or a white space character. The function returns -1 on
+ error or the length of the parsed string. */
+static int
+hex2bin (const char *string, void *buffer, size_t length)
+{
+ int i;
+ const char *s = string;
+
+ for (i=0; i < length; )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ return -1; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[i++] = xtoi_2 (s);
+ s += 2;
+ }
+ if (*s && (!my_isascii (*s) || !isspace (*s)) )
+ return -1; /* Not followed by Nul or white space. */
+ if (i != length)
+ return -1; /* Not of expected length. */
+ if (*s)
+ s++; /* Skip the delimiter. */
+ return s - string;
+}
+
+
+/* Convert STRING consisting of hex characters into its binary
+ representation and return it as an allocated buffer. The valid
+ length of the buffer is returned at R_LENGTH. The string is
+ delimited by end of string. The function returns NULL on
+ error. */
+static void *
+hex2buffer (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ return NULL; /* Invalid hex digits. */
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static char *
+read_textline (FILE *fp)
+{
+ char line[256];
+ char *p;
+ int any = 0;
+
+ /* Read line but skip over initial empty lines. */
+ do
+ {
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p = 0;
+ p = line + (*line? (strlen (line)-1):0);
+ for ( ;p > line; p--)
+ if (my_isascii (*p) && isspace (*p))
+ *p = 0;
+ }
+ while (!any && !*line);
+ any = 1;
+ }
+ while (*line == '#'); /* Always skip comment lines. */
+ if (verbose > 1)
+ fprintf (stderr, PGM ": received line: %s\n", line);
+ return gcry_xstrdup (line);
+}
+
+static char *
+read_hexline (FILE *fp, size_t *retlen)
+{
+ char *line, *p;
+
+ line = read_textline (fp);
+ if (!line)
+ return NULL;
+ p = hex2buffer (line, retlen);
+ if (!p)
+ die ("error decoding hex string on input\n");
+ gcry_free (line);
+ return p;
+}
+
+static void
+skip_to_empty_line (FILE *fp)
+{
+ char line[256];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p =0;
+ }
+ while (*line);
+}
+
+
+
+/* Read a file from stream FP into a newly allocated buffer and return
+ that buffer. The valid length of the buffer is stored at R_LENGTH.
+ Returns NULL on failure. If decode is set, the file is assumed to
+ be hex encoded and the decoded content is returned. */
+static void *
+read_file (FILE *fp, int decode, size_t *r_length)
+{
+ char *buffer;
+ size_t buflen;
+ size_t nread, bufsize = 0;
+
+ *r_length = 0;
+#define NCHUNK 8192
+#ifdef HAVE_DOSISH_SYSTEM
+ setmode (fileno(fp), O_BINARY);
+#endif
+ buffer = NULL;
+ buflen = 0;
+ do
+ {
+ bufsize += NCHUNK;
+ if (!buffer)
+ buffer = gcry_xmalloc (bufsize);
+ else
+ buffer = gcry_xrealloc (buffer, bufsize);
+
+ nread = fread (buffer + buflen, 1, NCHUNK, fp);
+ if (nread < NCHUNK && ferror (fp))
+ {
+ gcry_free (buffer);
+ return NULL;
+ }
+ buflen += nread;
+ }
+ while (nread == NCHUNK);
+#undef NCHUNK
+ if (decode)
+ {
+ const char *s;
+ char *p;
+
+ for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ {
+ gcry_free (buffer);
+ return NULL; /* Invalid hex digits. */
+ }
+ *(unsigned char*)p++ = xtoi_2 (s);
+ }
+ if (nread != buflen)
+ {
+ gcry_free (buffer);
+ return NULL; /* Odd number of hex digits. */
+ }
+ buflen = p - buffer;
+ }
+
+ *r_length = buflen;
+ return buffer;
+}
+
+/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns
+ the new length of the buffer. Dies on error. */
+static size_t
+base64_decode (char *buffer, size_t length)
+{
+ static unsigned char const asctobin[128] =
+ {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
+ 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
+ 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
+ 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
+ };
+
+ int idx = 0;
+ unsigned char val = 0;
+ int c = 0;
+ char *d, *s;
+ int lfseen = 1;
+
+ /* Find BEGIN line. */
+ for (s=buffer; length; length--, s++)
+ {
+ if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11))
+ {
+ for (; length && *s != '\n'; length--, s++)
+ ;
+ break;
+ }
+ lfseen = (*s == '\n');
+ }
+
+ /* Decode until pad character or END line. */
+ for (d=buffer; length; length--, s++)
+ {
+ if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9))
+ break;
+ if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t')
+ continue;
+ if (*s == '=')
+ {
+ /* Pad character: stop */
+ if (idx == 1)
+ *d++ = val;
+ break;
+ }
+
+ if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff)
+ die ("invalid base64 character %02X at pos %d detected\n",
+ *(unsigned char*)s, (int)(s-buffer));
+
+ switch (idx)
+ {
+ case 0:
+ val = c << 2;
+ break;
+ case 1:
+ val |= (c>>4)&3;
+ *d++ = val;
+ val = (c<<4)&0xf0;
+ break;
+ case 2:
+ val |= (c>>2)&15;
+ *d++ = val;
+ val = (c<<6)&0xc0;
+ break;
+ case 3:
+ val |= c&0x3f;
+ *d++ = val;
+ break;
+ }
+ idx = (idx+1) % 4;
+ }
+
+ return d - buffer;
+}
+
+
+/* Parse the buffer at the address BUFFER which consists of the number
+ of octets as stored at BUFLEN. Return the tag and the length part
+ from the TLV triplet. Update BUFFER and BUFLEN on success. Checks
+ that the encoded length does not exhaust the length of the provided
+ buffer. */
+static int
+parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti)
+{
+ int c;
+ unsigned long tag;
+ const unsigned char *buf = *buffer;
+ size_t length = *buflen;
+
+ ti->length = 0;
+ ti->ndef = 0;
+ ti->nhdr = 0;
+
+ /* Get the tag */
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+
+ ti->class = (c & 0xc0) >> 6;
+ ti->cons = !!(c & 0x20);
+ tag = (c & 0x1f);
+
+ if (tag == 0x1f)
+ {
+ tag = 0;
+ do
+ {
+ tag <<= 7;
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+ tag |= (c & 0x7f);
+ }
+ while ( (c & 0x80) );
+ }
+ ti->tag = tag;
+
+ /* Get the length */
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+
+ if ( !(c & 0x80) )
+ ti->length = c;
+ else if (c == 0x80)
+ ti->ndef = 1;
+ else if (c == 0xff)
+ return -1; /* Forbidden length value. */
+ else
+ {
+ unsigned long len = 0;
+ int count = c & 0x7f;
+
+ for (; count; count--)
+ {
+ len <<= 8;
+ if (!length)
+ return -1; /* Premature EOF. */
+ c = *buf++; length--;
+ ti->nhdr++;
+ len |= (c & 0xff);
+ }
+ ti->length = len;
+ }
+
+ if (ti->class == UNIVERSAL && !ti->tag)
+ ti->length = 0;
+
+ if (ti->length > length)
+ return -1; /* Data larger than buffer. */
+
+ *buffer = buf;
+ *buflen = length;
+ return 0;
+}
+
+
+/* Read the file FNAME assuming it is a PEM encoded private key file
+ and return an S-expression. With SHOW set, the key parameters are
+ printed. */
+static gcry_sexp_t
+read_private_key_file (const char *fname, int show)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ const unsigned char *der;
+ size_t derlen;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[8];
+ int n_keyparms = 8;
+ int idx;
+ gcry_sexp_t s_key;
+
+ fp = fopen (fname, binary_input?"rb":"r");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ buflen = base64_decode (buffer, buflen);
+
+ /* Parse the ASN.1 structure. */
+ der = (const unsigned char*)buffer;
+ derlen = buflen;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (ti.length != 1 || *der)
+ goto bad_asn1; /* The value of the first integer is no 0. */
+ der += ti.length; derlen -= ti.length;
+
+ for (idx=0; idx < n_keyparms; idx++)
+ {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (show)
+ {
+ char prefix[2];
+
+ prefix[0] = idx < 8? "nedpq12u"[idx] : '?';
+ prefix[1] = 0;
+ showhex (prefix, der, ti.length);
+ }
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err)
+ die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+ der += ti.length; derlen -= ti.length;
+ }
+ if (idx != n_keyparms)
+ die ("not enough RSA key parameters\n");
+
+ gcry_free (buffer);
+
+ /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
+ /* First check that p < q; if not swap p and q and recompute u. */
+ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
+ {
+ gcry_mpi_swap (keyparms[3], keyparms[4]);
+ gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+ }
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(private-key(rsa(n%m)(e%m)"
+ /**/ "(d%m)(p%m)(q%m)(u%m)))",
+ keyparms[0], keyparms[1], keyparms[2],
+ keyparms[3], keyparms[4], keyparms[7] );
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+
+ for (idx=0; idx < n_keyparms; idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ return s_key;
+
+ bad_asn1:
+ die ("invalid ASN.1 structure in `%s'\n", fname);
+ return NULL; /*NOTREACHED*/
+}
+
+
+/* Read the file FNAME assuming it is a PEM encoded public key file
+ and return an S-expression. With SHOW set, the key parameters are
+ printed. */
+static gcry_sexp_t
+read_public_key_file (const char *fname, int show)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ const unsigned char *der;
+ size_t derlen;
+ struct tag_info ti;
+ gcry_mpi_t keyparms[2];
+ int n_keyparms = 2;
+ int idx;
+ gcry_sexp_t s_key;
+
+ fp = fopen (fname, binary_input?"rb":"r");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ buflen = base64_decode (buffer, buflen);
+
+ /* Parse the ASN.1 structure. */
+ der = (const unsigned char*)buffer;
+ derlen = buflen;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+ /* We skip the description of the key parameters and assume it is RSA. */
+ der += ti.length; derlen -= ti.length;
+
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (ti.length < 1 || *der)
+ goto bad_asn1; /* The number of unused bits needs to be 0. */
+ der += 1; derlen -= 1;
+
+ /* Parse the BIT string. */
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+ goto bad_asn1;
+
+ for (idx=0; idx < n_keyparms; idx++)
+ {
+ if ( parse_tag (&der, &derlen, &ti)
+ || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+ goto bad_asn1;
+ if (show)
+ {
+ char prefix[2];
+
+ prefix[0] = idx < 2? "ne"[idx] : '?';
+ prefix[1] = 0;
+ showhex (prefix, der, ti.length);
+ }
+ err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+ if (err)
+ die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+ der += ti.length; derlen -= ti.length;
+ }
+ if (idx != n_keyparms)
+ die ("not enough RSA key parameters\n");
+
+ gcry_free (buffer);
+
+ /* Build the S-expression. */
+ err = gcry_sexp_build (&s_key, NULL,
+ "(public-key(rsa(n%m)(e%m)))",
+ keyparms[0], keyparms[1] );
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+
+ for (idx=0; idx < n_keyparms; idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ return s_key;
+
+ bad_asn1:
+ die ("invalid ASN.1 structure in `%s'\n", fname);
+ return NULL; /*NOTREACHED*/
+}
+
+
+
+/* Read the file FNAME assuming it is a binary signature result and
+ return an an S-expression suitable for gcry_pk_verify. */
+static gcry_sexp_t
+read_sig_file (const char *fname)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ gcry_mpi_t tmpmpi;
+ gcry_sexp_t s_sig;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL);
+ if (!err)
+ err = gcry_sexp_build (&s_sig, NULL,
+ "(sig-val(rsa(s %m)))", tmpmpi);
+ if (err)
+ die ("error building S-expression: %s\n", gpg_strerror (err));
+ gcry_mpi_release (tmpmpi);
+ gcry_free (buffer);
+
+ return s_sig;
+}
+
+
+/* Read an S-expression from FNAME. */
+static gcry_sexp_t
+read_sexp_from_file (const char *fname)
+{
+ gcry_error_t err;
+ FILE *fp;
+ char *buffer;
+ size_t buflen;
+ gcry_sexp_t sexp;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ die ("can't open `%s': %s\n", fname, strerror (errno));
+ buffer = read_file (fp, 0, &buflen);
+ if (!buffer)
+ die ("error reading `%s'\n", fname);
+ fclose (fp);
+ if (!buflen)
+ die ("error: file `%s' is empty\n", fname);
+
+ err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free);
+ if (err)
+ die ("error parsing `%s': %s\n", fname, gpg_strerror (err));
+
+ return sexp;
+}
+
+
+static void
+print_buffer (const void *buffer, size_t length)
+{
+ int writerr = 0;
+
+ if (base64_output)
+ {
+ static const unsigned char bintoasc[64+1] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ const unsigned char *p;
+ unsigned char inbuf[4];
+ char outbuf[4];
+ int idx, quads;
+
+ idx = quads = 0;
+ for (p = buffer; length; p++, length--)
+ {
+ inbuf[idx++] = *p;
+ if (idx > 2)
+ {
+ outbuf[0] = bintoasc[(*inbuf>>2)&077];
+ outbuf[1] = bintoasc[(((*inbuf<<4)&060)
+ |((inbuf[1] >> 4)&017))&077];
+ outbuf[2] = bintoasc[(((inbuf[1]<<2)&074)
+ |((inbuf[2]>>6)&03))&077];
+ outbuf[3] = bintoasc[inbuf[2]&077];
+ if (fwrite (outbuf, 4, 1, stdout) != 1)
+ writerr = 1;
+ idx = 0;
+ if (++quads >= (64/4))
+ {
+ if (fwrite ("\n", 1, 1, stdout) != 1)
+ writerr = 1;
+ quads = 0;
+ }
+ }
+ }
+ if (idx)
+ {
+ outbuf[0] = bintoasc[(*inbuf>>2)&077];
+ if (idx == 1)
+ {
+ outbuf[1] = bintoasc[((*inbuf<<4)&060)&077];
+ outbuf[2] = outbuf[3] = '=';
+ }
+ else
+ {
+ outbuf[1] = bintoasc[(((*inbuf<<4)&060)
+ |((inbuf[1]>>4)&017))&077];
+ outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077];
+ outbuf[3] = '=';
+ }
+ if (fwrite (outbuf, 4, 1, stdout) != 1)
+ writerr = 1;
+ quads++;
+ }
+ if (quads && fwrite ("\n", 1, 1, stdout) != 1)
+ writerr = 1;
+ }
+ else if (binary_output)
+ {
+ if (fwrite (buffer, length, 1, stdout) != 1)
+ writerr++;
+ }
+ else
+ {
+ const unsigned char *p = buffer;
+
+ if (verbose > 1)
+ showhex ("sent line", buffer, length);
+ while (length-- && !ferror (stdout) )
+ printf ("%02X", *p++);
+ if (ferror (stdout))
+ writerr++;
+ }
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ {
+#ifndef HAVE_W32_SYSTEM
+ if (loop_mode && errno == EPIPE)
+ loop_mode = 0;
+ else
+#endif
+ die ("writing output failed: %s\n", strerror (errno));
+ }
+}
+
+
+/* Print an MPI on a line. */
+static void
+print_mpi_line (gcry_mpi_t a, int no_lz)
+{
+ unsigned char *buf, *p;
+ gcry_error_t err;
+ int writerr = 0;
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+
+ p = buf;
+ if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
+ p += 2;
+
+ printf ("%s\n", p);
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+/* Print some data on hex format on a line. */
+static void
+print_data_line (const void *data, size_t datalen)
+{
+ const unsigned char *p = data;
+ int writerr = 0;
+
+ while (data && datalen-- && !ferror (stdout) )
+ printf ("%02X", *p++);
+ putchar ('\n');
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+}
+
+/* Print the S-expression A to the stream FP. */
+static void
+print_sexp (gcry_sexp_t a, FILE *fp)
+{
+ char *buf;
+ size_t size;
+
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ if (fwrite (buf, size, 1, fp) != 1)
+ die ("error writing to stream: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+
+
+static gcry_error_t
+init_external_rng_test (void **r_context,
+ unsigned int flags,
+ const void *key, size_t keylen,
+ const void *seed, size_t seedlen,
+ const void *dt, size_t dtlen)
+{
+ return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST,
+ r_context, flags,
+ key, keylen,
+ seed, seedlen,
+ dt, dtlen);
+}
+
+static gcry_error_t
+run_external_rng_test (void *context, void *buffer, size_t buflen)
+{
+ return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
+}
+
+static void
+deinit_external_rng_test (void *context)
+{
+ gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context);
+}
+
+
+/* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm
+ identified and store the libgcrypt mode at R_MODE. Returns 0 on
+ error. */
+static int
+map_openssl_cipher_name (const char *name, int *r_mode)
+{
+ static struct {
+ const char *name;
+ int algo;
+ int mode;
+ } table[] =
+ {
+ { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
+ { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC },
+ { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB },
+ { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB },
+ { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB },
+
+ { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC },
+ { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
+ { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB },
+ { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
+
+ { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
+ { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC },
+ { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB },
+ { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB },
+ { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB },
+
+ { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
+ { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
+ { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC },
+ { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
+ { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB },
+
+ { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM },
+
+ { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
+ { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC },
+ { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB },
+ { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB },
+ { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB },
+
+ { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
+ { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC },
+ { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB },
+ { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB },
+ { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB },
+
+ { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
+ { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC },
+ { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB },
+ { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB },
+ { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB },
+
+ { NULL, 0 , 0 }
+ };
+ int idx;
+
+ for (idx=0; table[idx].name; idx++)
+ if (!strcmp (name, table[idx].name))
+ {
+ *r_mode = table[idx].mode;
+ return table[idx].algo;
+ }
+ *r_mode = 0;
+ return 0;
+}
+
+
+\f
+/* Run an encrypt or decryption operations. If DATA is NULL the
+ function reads its input in chunks of size DATALEN from fp and
+ processes it and writes it out until EOF. */
+static void
+run_encrypt_decrypt (int encrypt_mode,
+ int cipher_algo, int cipher_mode,
+ const void *iv_buffer, size_t iv_buflen,
+ const void *key_buffer, size_t key_buflen,
+ const void *data, size_t datalen, FILE *fp)
+{
+ gpg_error_t err;
+ gcry_cipher_hd_t hd;
+ void *outbuf;
+ size_t outbuflen;
+ void *inbuf;
+ size_t inbuflen;
+ size_t blocklen;
+
+ err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
+ if (err)
+ die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
+ cipher_algo, cipher_mode, gpg_strerror (err));
+
+ blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
+ assert (blocklen);
+
+ gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
+
+ err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
+ if (err)
+ die ("gcry_cipher_setkey failed with keylen %u: %s\n",
+ (unsigned int)key_buflen, gpg_strerror (err));
+
+ if (iv_buffer)
+ {
+ err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
+ if (err)
+ die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
+ (unsigned int)iv_buflen, gpg_strerror (err));
+ }
+
+ inbuf = data? NULL : gcry_xmalloc (datalen);
+ outbuflen = datalen;
+ outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
+
+ do
+ {
+ if (inbuf)
+ {
+ int nread = fread (inbuf, 1, datalen, fp);
+ if (nread < (int)datalen && ferror (fp))
+ die ("error reading input\n");
+ data = inbuf;
+ inbuflen = nread;
+ }
+ else
+ inbuflen = datalen;
+
+ if (encrypt_mode)
+ err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
+ else
+ err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
+ if (err)
+ die ("gcry_cipher_%scrypt failed: %s\n",
+ encrypt_mode? "en":"de", gpg_strerror (err));
+
+ print_buffer (outbuf, outbuflen);
+ }
+ while (inbuf);
+
+ gcry_cipher_close (hd);
+ gcry_free (outbuf);
+ gcry_free (inbuf);
+}
+
+
+static void
+get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen)
+{
+ unsigned char tmp[17];
+
+ if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp))
+ die ("error getting current input vector\n");
+ if (buflen > *tmp)
+ die ("buffer too short to store the current input vector\n");
+ memcpy (buffer, tmp+1, *tmp);
+}
+
+/* Run the inner loop of the CAVS monte carlo test. */
+static void
+run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode,
+ const void *iv_buffer, size_t iv_buflen,
+ const void *key_buffer, size_t key_buflen,
+ const void *data, size_t datalen, int iterations)
+{
+ gpg_error_t err;
+ gcry_cipher_hd_t hd;
+ size_t blocklen;
+ int count;
+ char input[16];
+ char output[16];
+ char last_output[16];
+ char last_last_output[16];
+ char last_iv[16];
+
+
+ err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
+ if (err)
+ die ("gcry_cipher_open failed for algo %d, mode %d: %s\n",
+ cipher_algo, cipher_mode, gpg_strerror (err));
+
+ blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
+ if (!blocklen || blocklen > sizeof output)
+ die ("invalid block length %d\n", blocklen);
+
+
+ gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
+
+ err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
+ if (err)
+ die ("gcry_cipher_setkey failed with keylen %u: %s\n",
+ (unsigned int)key_buflen, gpg_strerror (err));
+
+ if (iv_buffer)
+ {
+ err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen);
+ if (err)
+ die ("gcry_cipher_setiv failed with ivlen %u: %s\n",
+ (unsigned int)iv_buflen, gpg_strerror (err));
+ }
+
+ if (datalen != blocklen)
+ die ("length of input (%u) does not match block length (%u)\n",
+ (unsigned int)datalen, (unsigned int)blocklen);
+ memcpy (input, data, datalen);
+ memset (output, 0, sizeof output);
+ for (count=0; count < iterations; count++)
+ {
+ memcpy (last_last_output, last_output, sizeof last_output);
+ memcpy (last_output, output, sizeof output);
+
+ get_current_iv (hd, last_iv, blocklen);
+
+ if (encrypt_mode)
+ err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen);
+ else
+ err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen);
+ if (err)
+ die ("gcry_cipher_%scrypt failed: %s\n",
+ encrypt_mode? "en":"de", gpg_strerror (err));
+
+
+ if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB
+ || cipher_mode == GCRY_CIPHER_MODE_CBC))
+ memcpy (input, last_iv, blocklen);
+ else if (cipher_mode == GCRY_CIPHER_MODE_OFB)
+ memcpy (input, last_iv, blocklen);
+ else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB)
+ {
+ /* Reconstruct the output vector. */
+ int i;
+ for (i=0; i < blocklen; i++)
+ input[i] ^= output[i];
+ }
+ else
+ memcpy (input, output, blocklen);
+ }
+
+ print_buffer (output, blocklen);
+ putchar ('\n');
+ print_buffer (last_output, blocklen);
+ putchar ('\n');
+ print_buffer (last_last_output, blocklen);
+ putchar ('\n');
+ get_current_iv (hd, last_iv, blocklen);
+ print_buffer (last_iv, blocklen); /* Last output vector. */
+ putchar ('\n');
+ print_buffer (input, blocklen); /* Next input text. */
+ putchar ('\n');
+ if (verbose > 1)
+ showhex ("sent line", "", 0);
+ putchar ('\n');
+ fflush (stdout);
+
+ gcry_cipher_close (hd);
+}
+
+
+\f
+/* Run a digest operation. */
+static void
+run_digest (int digest_algo, const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+ unsigned int digestlen;
+
+ err = gcry_md_open (&hd, digest_algo, 0);
+ if (err)
+ die ("gcry_md_open failed for algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_write (hd, data, datalen);
+ digest = gcry_md_read (hd, digest_algo);
+ digestlen = gcry_md_get_algo_dlen (digest_algo);
+ print_buffer (digest, digestlen);
+ gcry_md_close (hd);
+}
+
+\f
+/* Run a HMAC operation. */
+static void
+run_hmac (int digest_algo, const void *key, size_t keylen,
+ const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_md_hd_t hd;
+ const unsigned char *digest;
+ unsigned int digestlen;
+
+ err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC);
+ if (err)
+ die ("gcry_md_open failed for HMAC algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_setkey (hd, key, keylen);
+ if (err)
+ die ("gcry_md_setkey failed for HMAC algo %d: %s\n",
+ digest_algo, gpg_strerror (err));
+
+ gcry_md_write (hd, data, datalen);
+ digest = gcry_md_read (hd, digest_algo);
+ digestlen = gcry_md_get_algo_dlen (digest_algo);
+ print_buffer (digest, digestlen);
+ gcry_md_close (hd);
+}
+
+
+\f
+/* Derive an RSA key using the S-expression in (DATA,DATALEN). This
+ S-expression is used directly as input to gcry_pk_genkey. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: p, q, n, d. */
+static void
+run_rsa_derive (const void *data, size_t datalen)
+{
+ gpg_error_t err;
+ gcry_sexp_t s_keyspec, s_key, s_top, l1;
+ gcry_mpi_t mpi;
+ const char *parmlist;
+ int idx;
+
+ if (!datalen)
+ err = gpg_error (GPG_ERR_NO_DATA);
+ else
+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1);
+ if (err)
+ die ("gcry_sexp_new failed for RSA key derive: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&s_key, s_keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_keyspec);
+
+ /* P and Q might have been swapped but we need to to return them in
+ the proper order. Build the parameter list accordingly. */
+ parmlist = "pqnd";
+ s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0);
+ if (s_top)
+ {
+ l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0);
+ if (l1)
+ parmlist = "qpnd";
+ gcry_sexp_release (l1);
+ gcry_sexp_release (s_top);
+ }
+
+ /* Parse and print the parameters. */
+ l1 = gcry_sexp_find_token (s_key, "private-key", 0);
+ s_top = gcry_sexp_find_token (l1, "rsa", 0);
+ gcry_sexp_release (l1);
+ if (!s_top)
+ die ("private-key part not found in result\n");
+
+ for (idx=0; parmlist[idx]; idx++)
+ {
+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1);
+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l1);
+ if (!mpi)
+ die ("parameter %c missing in private-key\n", parmlist[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+
+ gcry_sexp_release (s_top);
+ gcry_sexp_release (s_key);
+}
+
+
+\f
+static size_t
+compute_tag_length (size_t n)
+{
+ int needed = 0;
+
+ if (n < 128)
+ needed += 2; /* Tag and one length byte. */
+ else if (n < 256)
+ needed += 3; /* Tag, number of length bytes, 1 length byte. */
+ else if (n < 65536)
+ needed += 4; /* Tag, number of length bytes, 2 length bytes. */
+ else
+ die ("DER object too long to encode\n");
+
+ return needed;
+}
+
+static unsigned char *
+store_tag_length (unsigned char *p, int tag, size_t n)
+{
+ if (tag == TAG_SEQUENCE)
+ tag |= 0x20; /* constructed */
+
+ *p++ = tag;
+ if (n < 128)
+ *p++ = n;
+ else if (n < 256)
+ {
+ *p++ = 0x81;
+ *p++ = n;
+ }
+ else if (n < 65536)
+ {
+ *p++ = 0x82;
+ *p++ = n >> 8;
+ *p++ = n;
+ }
+
+ return p;
+}
+
+
+/* Generate an RSA key of size KEYSIZE using the public exponent
+ PUBEXP and print it to stdout in the OpenSSL format. The format
+ is:
+
+ SEQUENCE {
+ INTEGER (0) -- Unknown constant.
+ INTEGER -- n
+ INTEGER -- e
+ INTEGER -- d
+ INTEGER -- p
+ INTEGER -- q (with p < q)
+ INTEGER -- dmp1 = d mod (p-1)
+ INTEGER -- dmq1 = d mod (q-1)
+ INTEGER -- u = p^{-1} mod q
+ }
+
+*/
+static void
+run_rsa_gen (int keysize, int pubexp)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key, l1;
+ const char keyelems[] = "nedpq..u";
+ gcry_mpi_t keyparms[8];
+ size_t keyparmslen[8];
+ int idx;
+ size_t derlen, needed, n;
+ unsigned char *derbuf, *der;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey (rsa (nbits %d)(rsa-use-e %d)))",
+ keysize, pubexp);
+ if (err)
+ die ("gcry_sexp_build failed for RSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ l1 = gcry_sexp_find_token (key, "private-key", 0);
+ if (!l1)
+ die ("private key not found in genkey result\n");
+ gcry_sexp_release (key);
+ key = l1;
+
+ l1 = gcry_sexp_find_token (key, "rsa", 0);
+ if (!l1)
+ die ("returned private key not formed as expected\n");
+ gcry_sexp_release (key);
+ key = l1;
+
+ /* Extract the parameters from the S-expression and store them in a
+ well defined order in KEYPARMS. */
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ if (keyelems[idx] == '.')
+ {
+ keyparms[idx] = gcry_mpi_new (0);
+ continue;
+ }
+ l1 = gcry_sexp_find_token (key, keyelems+idx, 1);
+ if (!l1)
+ die ("no %c parameter in returned private key\n", keyelems[idx]);
+ keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ if (!keyparms[idx])
+ die ("no value for %c parameter in returned private key\n",
+ keyelems[idx]);
+ gcry_sexp_release (l1);
+ }
+
+ gcry_sexp_release (key);
+
+ /* Check that p < q; if not swap p and q and recompute u. */
+ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
+ {
+ gcry_mpi_swap (keyparms[3], keyparms[4]);
+ gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+ }
+
+ /* Compute the additional parameters. */
+ gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1);
+ gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]);
+ gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1);
+ gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]);
+
+ /* Compute the length of the DER encoding. */
+ needed = compute_tag_length (1) + 1;
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]);
+ if (err)
+ die ("error formatting parameter: %s\n", gpg_strerror (err));
+ keyparmslen[idx] = n;
+ needed += compute_tag_length (n) + n;
+ }
+
+ /* Store the key parameters. */
+ derlen = compute_tag_length (needed) + needed;
+ der = derbuf = gcry_xmalloc (derlen);
+
+ der = store_tag_length (der, TAG_SEQUENCE, needed);
+ der = store_tag_length (der, TAG_INTEGER, 1);
+ *der++ = 0;
+ for (idx=0; idx < DIM(keyparms); idx++)
+ {
+ der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]);
+ err = gcry_mpi_print (GCRYMPI_FMT_STD, der,
+ keyparmslen[idx], NULL, keyparms[idx]);
+ if (err)
+ die ("error formatting parameter: %s\n", gpg_strerror (err));
+ der += keyparmslen[idx];
+ }
+
+ /* Print the stuff. */
+ for (idx=0; idx < DIM(keyparms); idx++)
+ gcry_mpi_release (keyparms[idx]);
+
+ assert (der - derbuf == derlen);
+
+ if (base64_output)
+ puts ("-----BEGIN RSA PRIVATE KEY-----");
+ print_buffer (derbuf, derlen);
+ if (base64_output)
+ puts ("-----END RSA PRIVATE KEY-----");
+
+ gcry_free (derbuf);
+}
+
+
+\f
+/* Sign DATA of length DATALEN using the key taken from the PEM
+ encoded KEYFILE and the hash algorithm HASHALGO. */
+static void
+run_rsa_sign (const void *data, size_t datalen,
+ int hashalgo, int pkcs1, const char *keyfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig, s_tmp;
+ gcry_mpi_t sig_mpi = NULL;
+ unsigned char *outbuf;
+ size_t outlen;
+
+/* showhex ("D", data, datalen); */
+ if (pkcs1)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else
+ {
+ gcry_mpi_t tmp;
+
+ err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmp);
+ gcry_mpi_release (tmp);
+ }
+ }
+ if (err)
+ die ("gcry_sexp_build failed for RSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_private_key_file (keyfile, 0);
+
+ err = gcry_pk_sign (&s_sig, s_data, s_key);
+ if (err)
+ {
+ gcry_sexp_release (read_private_key_file (keyfile, 1));
+ die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
+ (int)datalen, keyfile, gpg_strerror (err));
+ }
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+ if (s_tmp)
+ {
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG);
+ }
+ }
+ }
+ gcry_sexp_release (s_sig);
+
+ if (!sig_mpi)
+ die ("no value in returned S-expression\n");
+ err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+ gcry_mpi_release (sig_mpi);
+
+ print_buffer (outbuf, outlen);
+ gcry_free (outbuf);
+}
+
+
+\f
+/* Verify DATA of length DATALEN using the public key taken from the
+ PEM encoded KEYFILE and the hash algorithm HASHALGO against the
+ binary signature in SIGFILE. */
+static void
+run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1,
+ const char *keyfile, const char *sigfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig;
+
+ if (pkcs1)
+ {
+ unsigned char hash[64];
+ unsigned int hashsize;
+
+ hashsize = gcry_md_get_algo_dlen (hashalgo);
+ if (!hashsize || hashsize > sizeof hash)
+ die ("digest too long for buffer or unknown hash algorithm\n");
+ gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags pkcs1)(hash %s %b))",
+ gcry_md_algo_name (hashalgo),
+ (int)hashsize, hash);
+ }
+ else
+ {
+ gcry_mpi_t tmp;
+
+ err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmp);
+ gcry_mpi_release (tmp);
+ }
+ }
+ if (err)
+ die ("gcry_sexp_build failed for RSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_public_key_file (keyfile, 0);
+
+ s_sig = read_sig_file (sigfile);
+
+ err = gcry_pk_verify (s_sig, s_data, s_key);
+ if (!err)
+ puts ("GOOD signature");
+ else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+ puts ("BAD signature");
+ else
+ printf ("ERROR (%s)\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+}
+
+
+\f
+/* Generate a DSA key of size KEYSIZE and return the complete
+ S-expression. */
+static gcry_sexp_t
+dsa_gen (int keysize)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey (dsa (nbits %d)(use-fips186-2)))",
+ keysize);
+ if (err)
+ die ("gcry_sexp_build failed for DSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ return key;
+}
+
+
+/* Generate a DSA key of size KEYSIZE and return the complete
+ S-expression. */
+static gcry_sexp_t
+dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen)
+{
+ gpg_error_t err;
+ gcry_sexp_t keyspec, key;
+
+ err = gcry_sexp_build (&keyspec, NULL,
+ "(genkey"
+ " (dsa"
+ " (nbits %d)"
+ " (use-fips186-2)"
+ " (derive-parms"
+ " (seed %b))))",
+ keysize, (int)seedlen, seed);
+ if (err)
+ die ("gcry_sexp_build failed for DSA key generation: %s\n",
+ gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, keyspec);
+ if (err)
+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
+
+ gcry_sexp_release (keyspec);
+
+ return key;
+}
+
+
+/* Print the domain parameter as well as the derive information. KEY
+ is the complete key as returned by dsa_gen. We print to stdout
+ with one parameter per line in hex format using this order: p, q,
+ g, seed, counter, h. */
+static void
+print_dsa_domain_parameters (gcry_sexp_t key)
+{
+ gcry_sexp_t l1, l2;
+ gcry_mpi_t mpi;
+ int idx;
+ const void *data;
+ size_t datalen;
+ char *string;
+
+ l1 = gcry_sexp_find_token (key, "public-key", 0);
+ if (!l1)
+ die ("public key not found in genkey result\n");
+
+ l2 = gcry_sexp_find_token (l1, "dsa", 0);
+ if (!l2)
+ die ("returned public key not formed as expected\n");
+ gcry_sexp_release (l1);
+ l1 = l2;
+
+ /* Extract the parameters from the S-expression and print them to stdout. */
+ for (idx=0; "pqg"[idx]; idx++)
+ {
+ l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1);
+ if (!l2)
+ die ("no %c parameter in returned public key\n", "pqg"[idx]);
+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!mpi)
+ die ("no value for %c parameter in returned public key\n","pqg"[idx]);
+ gcry_sexp_release (l2);
+ if (standalone_mode)
+ printf ("%c = ", "PQG"[idx]);
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ }
+ gcry_sexp_release (l1);
+
+ /* Extract the seed values. */
+ l1 = gcry_sexp_find_token (key, "misc-key-info", 0);
+ if (!l1)
+ die ("misc-key-info not found in genkey result\n");
+
+ l2 = gcry_sexp_find_token (l1, "seed-values", 0);
+ if (!l2)
+ die ("no seed-values in returned key\n");
+ gcry_sexp_release (l1);
+ l1 = l2;
+
+ l2 = gcry_sexp_find_token (l1, "seed", 0);
+ if (!l2)
+ die ("no seed value in returned key\n");
+ data = gcry_sexp_nth_data (l2, 1, &datalen);
+ if (!data)
+ die ("no seed value in returned key\n");
+ if (standalone_mode)
+ printf ("Seed = ");
+ print_data_line (data, datalen);
+ gcry_sexp_release (l2);
+
+ l2 = gcry_sexp_find_token (l1, "counter", 0);
+ if (!l2)
+ die ("no counter value in returned key\n");
+ string = gcry_sexp_nth_string (l2, 1);
+ if (!string)
+ die ("no counter value in returned key\n");
+ if (standalone_mode)
+ printf ("c = %ld\n", strtoul (string, NULL, 10));
+ else
+ printf ("%lX\n", strtoul (string, NULL, 10));
+ gcry_free (string);
+ gcry_sexp_release (l2);
+
+ l2 = gcry_sexp_find_token (l1, "h", 0);
+ if (!l2)
+ die ("no n value in returned key\n");
+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ if (!mpi)
+ die ("no h value in returned key\n");
+ if (standalone_mode)
+ printf ("H = ");
+ print_mpi_line (mpi, 1);
+ gcry_mpi_release (mpi);
+ gcry_sexp_release (l2);
+
+ gcry_sexp_release (l1);
+}
+
+
+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The
+ result is printed to stdout with one parameter per line in hex
+ format and in this order: p, q, g, seed, counter, h. If SEED is
+ not NULL this seed value will be used for the generation. */
+static void
+run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen)
+{
+ gcry_sexp_t key;
+
+ if (seed)
+ key = dsa_gen_with_seed (keysize, seed, seedlen);
+ else
+ key = dsa_gen (keysize);
+ print_dsa_domain_parameters (key);
+ gcry_sexp_release (key);
+}
+
+
+/* Generate a DSA key of size of KEYSIZE and write the private key to
+ FILENAME. Also write the parameters to stdout in the same way as
+ run_dsa_pqg_gen. */
+static void
+run_dsa_gen (int keysize, const char *filename)
+{
+ gcry_sexp_t key, private_key;
+ FILE *fp;
+
+ key = dsa_gen (keysize);
+ private_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!private_key)
+ die ("private key not found in genkey result\n");
+ print_dsa_domain_parameters (key);
+
+ fp = fopen (filename, "wb");
+ if (!fp)
+ die ("can't create `%s': %s\n", filename, strerror (errno));
+ print_sexp (private_key, fp);
+ fclose (fp);
+
+ gcry_sexp_release (private_key);
+ gcry_sexp_release (key);
+}
+
+
+\f
+/* Sign DATA of length DATALEN using the key taken from the S-expression
+ encoded KEYFILE. */
+static void
+run_dsa_sign (const void *data, size_t datalen, const char *keyfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2;
+ char hash[20];
+ gcry_mpi_t tmpmpi;
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for DSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_sexp_from_file (keyfile);
+
+ err = gcry_pk_sign (&s_sig, s_data, s_key);
+ if (err)
+ {
+ gcry_sexp_release (read_private_key_file (keyfile, 1));
+ die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
+ (int)datalen, keyfile, gpg_strerror (err));
+ }
+ gcry_sexp_release (s_data);
+
+ /* We need to return the Y parameter first. */
+ s_tmp = gcry_sexp_find_token (s_key, "private-key", 0);
+ if (!s_tmp)
+ die ("private key part not found in provided key\n");
+
+ s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0);
+ if (!s_tmp2)
+ die ("private key part is not a DSA key\n");
+ gcry_sexp_release (s_tmp);
+
+ s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no y parameter in DSA key\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ gcry_sexp_release (s_key);
+
+
+ /* Now return the actual signature. */
+ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+ if (!s_tmp)
+ die ("no sig-val element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+ s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0);
+ if (!s_tmp)
+ die ("no dsa element in returned S-expression\n");
+
+ gcry_sexp_release (s_sig);
+ s_sig = s_tmp;
+
+ s_tmp = gcry_sexp_find_token (s_sig, "r", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no r parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ s_tmp = gcry_sexp_find_token (s_sig, "s", 0);
+ tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG);
+ if (!tmpmpi)
+ die ("no s parameter in returned S-expression\n");
+ print_mpi_line (tmpmpi, 1);
+ gcry_mpi_release (tmpmpi);
+ gcry_sexp_release (s_tmp);
+
+ gcry_sexp_release (s_sig);
+}
+
+
+\f
+/* Verify DATA of length DATALEN using the public key taken from the
+ S-expression in KEYFILE against the S-expression formatted
+ signature in SIGFILE. */
+static void
+run_dsa_verify (const void *data, size_t datalen,
+ const char *keyfile, const char *sigfile)
+
+{
+ gpg_error_t err;
+ gcry_sexp_t s_data, s_key, s_sig;
+ char hash[20];
+ gcry_mpi_t tmpmpi;
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
+ /* Note that we can't simply use %b with HASH to build the
+ S-expression, because that might yield a negative value. */
+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
+ if (!err)
+ {
+ err = gcry_sexp_build (&s_data, NULL,
+ "(data (flags raw)(value %m))", tmpmpi);
+ gcry_mpi_release (tmpmpi);
+ }
+ if (err)
+ die ("gcry_sexp_build failed for DSA data input: %s\n",
+ gpg_strerror (err));
+
+ s_key = read_sexp_from_file (keyfile);
+ s_sig = read_sexp_from_file (sigfile);
+
+ err = gcry_pk_verify (s_sig, s_data, s_key);
+ if (!err)
+ puts ("GOOD signature");
+ else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
+ puts ("BAD signature");
+ else
+ printf ("ERROR (%s)\n", gpg_strerror (err));
+
+ gcry_sexp_release (s_sig);
+ gcry_sexp_release (s_key);
+ gcry_sexp_release (s_data);
+}
+
+
+
+\f
+static void
+usage (int show_help)
+{
+ if (!show_help)
+ {
+ fputs ("usage: " PGM
+ " [OPTION] [FILE] (try --help for more information)\n", stderr);
+ exit (2);
+ }
+ fputs
+ ("Usage: " PGM " [OPTIONS] MODE [FILE]\n"
+ "Run a crypto operation using hex encoded input and output.\n"
+ "MODE:\n"
+ " encrypt, decrypt, digest, random, hmac-sha,\n"
+ " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n"
+ "OPTIONS:\n"
+ " --verbose Print additional information\n"
+ " --binary Input and output is in binary form\n"
+ " --no-fips Do not force FIPS mode\n"
+ " --key KEY Use the hex encoded KEY\n"
+ " --iv IV Use the hex encoded IV\n"
+ " --dt DT Use the hex encoded DT for the RNG\n"
+ " --algo NAME Use algorithm NAME\n"
+ " --keysize N Use a keysize of N bits\n"
+ " --signature NAME Take signature from file NAME\n"
+ " --chunk N Read in chunks of N bytes (implies --binary)\n"
+ " --pkcs1 Use PKCS#1 encoding\n"
+ " --mct-server Run a monte carlo test server\n"
+ " --loop Enable random loop mode\n"
+ " --progress Print pogress indicators\n"
+ " --help Print this text\n"
+ "With no FILE, or when FILE is -, read standard input.\n"
+ "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
+ exit (0);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ gpg_error_t err;
+ int no_fips = 0;
+ int progress = 0;
+ int use_pkcs1 = 0;
+ const char *mode_string;
+ const char *key_string = NULL;
+ const char *iv_string = NULL;
+ const char *dt_string = NULL;
+ const char *algo_string = NULL;
+ const char *keysize_string = NULL;
+ const char *signature_string = NULL;
+ FILE *input;
+ void *data;
+ size_t datalen;
+ size_t chunksize = 0;
+ int mct_server = 0;
+
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ usage (1);
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--binary"))
+ {
+ binary_input = binary_output = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--no-fips"))
+ {
+ no_fips++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--loop"))
+ {
+ loop_mode = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--progress"))
+ {
+ progress = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--key"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ key_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--iv"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ iv_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--dt"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ dt_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--algo"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ algo_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--keysize"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ keysize_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--signature"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ signature_string = *argv;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--chunk"))
+ {
+ argc--; argv++;
+ if (!argc)
+ usage (0);
+ chunksize = atoi (*argv);
+ binary_input = binary_output = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pkcs1"))
+ {
+ use_pkcs1 = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--mct-server"))
+ {
+ mct_server = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--standalone"))
+ {
+ standalone_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (!argc || argc > 2)
+ usage (0);
+ mode_string = *argv;
+
+ if (!strcmp (mode_string, "rsa-derive"))
+ binary_input = 1;
+
+ if (argc == 2 && strcmp (argv[1], "-"))
+ {
+ input = fopen (argv[1], binary_input? "rb":"r");
+ if (!input)
+ die ("can't open `%s': %s\n", argv[1], strerror (errno));
+ }
+ else
+ input = stdin;
+
+#ifndef HAVE_W32_SYSTEM
+ if (loop_mode)
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (verbose)
+ fprintf (stderr, PGM ": started (mode=%s)\n", mode_string);
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+ if (!no_fips)
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+ if (!gcry_check_version ("1.4.3"))
+ die ("Libgcrypt is not sufficient enough\n");
+ if (verbose)
+ fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL));
+ if (no_fips)
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ /* Most operations need some input data. */
+ if (!chunksize
+ && !mct_server
+ && strcmp (mode_string, "random")
+ && strcmp (mode_string, "rsa-gen")
+ && strcmp (mode_string, "dsa-gen") )
+ {
+ data = read_file (input, !binary_input, &datalen);
+ if (!data)
+ die ("error reading%s input\n", binary_input?"":" and decoding");
+ if (verbose)
+ fprintf (stderr, PGM ": %u bytes of input data\n",
+ (unsigned int)datalen);
+ }
+ else
+ {
+ data = NULL;
+ datalen = 0;
+ }
+
+
+ if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt"))
+ {
+ int cipher_algo, cipher_mode;
+ void *iv_buffer = NULL;
+ void *key_buffer = NULL;
+ size_t iv_buflen, key_buflen;
+
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode);
+ if (!cipher_algo)
+ die ("cipher algorithm `%s' is not supported\n", algo_string);
+ if (mct_server)
+ {
+ int iterations;
+
+ for (;;)
+ {
+ gcry_free (key_buffer); key_buffer = NULL;
+ gcry_free (iv_buffer); iv_buffer = NULL;
+ gcry_free (data); data = NULL;
+ if (!(key_buffer = read_textline (input)))
+ {
+ if (feof (input))
+ break;
+ die ("no version info in input\n");
+ }
+ if (atoi (key_buffer) != 1)
+ die ("unsupported input version %s\n", key_buffer);
+ gcry_free (key_buffer);
+ if (!(key_buffer = read_textline (input)))
+ die ("no iteration count in input\n");
+ iterations = atoi (key_buffer);
+ gcry_free (key_buffer);
+ if (!(key_buffer = read_hexline (input, &key_buflen)))
+ die ("no key in input\n");
+ if (!(iv_buffer = read_hexline (input, &iv_buflen)))
+ die ("no IV in input\n");
+ if (!(data = read_hexline (input, &datalen)))
+ die ("no data in input\n");
+ skip_to_empty_line (input);
+
+ run_cipher_mct_loop ((*mode_string == 'e'),
+ cipher_algo, cipher_mode,
+ iv_buffer, iv_buflen,
+ key_buffer, key_buflen,
+ data, datalen, iterations);
+ }
+ }
+ else
+ {
+ if (cipher_mode != GCRY_CIPHER_MODE_ECB)
+ {
+ if (!iv_string)
+ die ("option --iv is required in this mode\n");
+ iv_buffer = hex2buffer (iv_string, &iv_buflen);
+ if (!iv_buffer)
+ die ("invalid value for IV\n");
+ }
+ else
+ {
+ iv_buffer = NULL;
+ iv_buflen = 0;
+ }
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ key_buffer = hex2buffer (key_string, &key_buflen);
+ if (!key_buffer)
+ die ("invalid value for KEY\n");
+
+ run_encrypt_decrypt ((*mode_string == 'e'),
+ cipher_algo, cipher_mode,
+ iv_buffer, iv_buflen,
+ key_buffer, key_buflen,
+ data, data? datalen:chunksize, input);
+ }
+ gcry_free (key_buffer);
+ gcry_free (iv_buffer);
+ }
+ else if (!strcmp (mode_string, "digest"))
+ {
+ int algo;
+
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_digest (algo, data, datalen);
+ }
+ else if (!strcmp (mode_string, "random"))
+ {
+ void *context;
+ unsigned char key[16];
+ unsigned char seed[16];
+ unsigned char dt[16];
+ unsigned char buffer[16];
+ size_t count = 0;
+
+ if (hex2bin (key_string, key, 16) < 0 )
+ die ("value for --key are not 32 hex digits\n");
+ if (hex2bin (iv_string, seed, 16) < 0 )
+ die ("value for --iv are not 32 hex digits\n");
+ if (hex2bin (dt_string, dt, 16) < 0 )
+ die ("value for --dt are not 32 hex digits\n");
+
+ /* The flag value 1 disables the dup check, so that the RNG
+ returns all generated data. */
+ err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16);
+ if (err)
+ die ("init external RNG test failed: %s\n", gpg_strerror (err));
+
+ do
+ {
+ err = run_external_rng_test (context, buffer, sizeof buffer);
+ if (err)
+ die ("running external RNG test failed: %s\n", gpg_strerror (err));
+ print_buffer (buffer, sizeof buffer);
+ if (progress)
+ {
+ if (!(++count % 1000))
+ fprintf (stderr, PGM ": %lu random bytes so far\n",
+ (unsigned long int)count * sizeof buffer);
+ }
+ }
+ while (loop_mode);
+
+ if (progress)
+ fprintf (stderr, PGM ": %lu random bytes\n",
+ (unsigned long int)count * sizeof buffer);
+
+ deinit_external_rng_test (context);
+ }
+ else if (!strcmp (mode_string, "hmac-sha"))
+ {
+ int algo;
+ void *key_buffer;
+ size_t key_buflen;
+
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ switch (atoi (algo_string))
+ {
+ case 1: algo = GCRY_MD_SHA1; break;
+ case 224: algo = GCRY_MD_SHA224; break;
+ case 256: algo = GCRY_MD_SHA256; break;
+ case 384: algo = GCRY_MD_SHA384; break;
+ case 512: algo = GCRY_MD_SHA512; break;
+ default: algo = 0; break;
+ }
+ if (!algo)
+ die ("no digest algorithm found for hmac type `%s'\n", algo_string);
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ key_buffer = hex2buffer (key_string, &key_buflen);
+ if (!key_buffer)
+ die ("invalid value for KEY\n");
+
+ run_hmac (algo, key_buffer, key_buflen, data, datalen);
+
+ gcry_free (key_buffer);
+ }
+ else if (!strcmp (mode_string, "rsa-derive"))
+ {
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ run_rsa_derive (data, datalen);
+ }
+ else if (!strcmp (mode_string, "rsa-gen"))
+ {
+ int keysize;
+
+ if (!binary_output)
+ base64_output = 1;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 128 || keysize > 16384)
+ die ("invalid keysize specified; needs to be 128 .. 16384\n");
+ run_rsa_gen (keysize, 65537);
+ }
+ else if (!strcmp (mode_string, "rsa-sign"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_rsa_sign (data, datalen, algo, use_pkcs1, key_string);
+
+ }
+ else if (!strcmp (mode_string, "rsa-verify"))
+ {
+ int algo;
+
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!algo_string)
+ die ("option --algo is required in this mode\n");
+ algo = gcry_md_map_name (algo_string);
+ if (!algo)
+ die ("digest algorithm `%s' is not supported\n", algo_string);
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!signature_string)
+ die ("option --signature is required in this mode\n");
+ if (access (signature_string, R_OK))
+ die ("option --signature needs to specify an existing file\n");
+
+ run_rsa_verify (data, datalen, algo, use_pkcs1, key_string,
+ signature_string);
+
+ }
+ else if (!strcmp (mode_string, "dsa-pqg-gen"))
+ {
+ int keysize;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 1024 || keysize > 3072)
+ die ("invalid keysize specified; needs to be 1024 .. 3072\n");
+ run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
+ }
+ else if (!strcmp (mode_string, "dsa-gen"))
+ {
+ int keysize;
+
+ keysize = keysize_string? atoi (keysize_string) : 0;
+ if (keysize < 1024 || keysize > 3072)
+ die ("invalid keysize specified; needs to be 1024 .. 3072\n");
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ run_dsa_gen (keysize, key_string);
+ }
+ else if (!strcmp (mode_string, "dsa-sign"))
+ {
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+
+ run_dsa_sign (data, datalen, key_string);
+ }
+ else if (!strcmp (mode_string, "dsa-verify"))
+ {
+ if (!key_string)
+ die ("option --key is required in this mode\n");
+ if (access (key_string, R_OK))
+ die ("option --key needs to specify an existing keyfile\n");
+ if (!data)
+ die ("no data available (do not use --chunk)\n");
+ if (!signature_string)
+ die ("option --signature is required in this mode\n");
+ if (access (signature_string, R_OK))
+ die ("option --signature needs to specify an existing file\n");
+
+ run_dsa_verify (data, datalen, key_string, signature_string);
+ }
+ else
+ usage (0);
+
+ gcry_free (data);
+
+ /* Because Libgcrypt does not enforce FIPS mode in all cases we let
+ the process die if Libgcrypt is not anymore in FIPS mode after
+ the actual operation. */
+ if (!no_fips && !gcry_fips_mode_active ())
+ die ("FIPS mode is not anymore active\n");
+
+ if (verbose)
+ fputs (PGM ": ready\n", stderr);
+
+ return 0;
+}
--- /dev/null
+/* hmac.c - HMAC regression tests
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+static int error_count;
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+
+static void
+check_one_mac (int algo,
+ const void *key, size_t keylen,
+ const void *data, size_t datalen,
+ const char *expect)
+{
+ gcry_md_hd_t hd;
+ unsigned char *p;
+ int mdlen;
+ int i;
+ gcry_error_t err = 0;
+
+ err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ mdlen = gcry_md_get_algo_dlen (algo);
+ if (mdlen < 1 || mdlen > 500)
+ {
+ fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen);
+ return;
+ }
+
+ err = gcry_md_setkey (hd, key, keylen);
+ if (err)
+ {
+ fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err));
+ return;
+ }
+
+ gcry_md_write (hd, data, datalen);
+
+ p = gcry_md_read (hd, 0);
+
+ if (memcmp (p, expect, mdlen))
+ {
+ printf ("computed: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", p[i] & 0xFF);
+ printf ("\nexpected: ");
+ for (i = 0; i < mdlen; i++)
+ printf ("%02x ", expect[i] & 0xFF);
+ printf ("\n");
+
+ fail ("algo %d, MAC does not match\n", algo);
+ }
+
+ gcry_md_close (hd);
+}
+
+static void
+check_hmac (void)
+{
+ unsigned char key[128];
+ int i, j;
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.1\n");
+ for (i=0; i < 64; i++)
+ key[i] = i;
+ check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9,
+ "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+ "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.2\n");
+ for (i=0, j=0x30; i < 20; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9,
+ "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82"
+ "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.3\n");
+ for (i=0, j=0x50; i < 100; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9,
+ "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0"
+ "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa");
+
+ if (verbose)
+ fprintf (stderr, "checking FIPS-198a, A.4\n");
+ for (i=0, j=0x70; i < 49; i++)
+ key[i] = j++;
+ check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9,
+ "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42"
+ "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26");
+
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ check_hmac ();
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* keygen.c - key generation regression tests
+ * Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../src/gcrypt.h"
+
+
+
+static int verbose;
+static int debug;
+static int error_count;
+
+static void
+fail ( const char *format, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ error_count++;
+}
+
+static void
+die ( const char *format, ... )
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+ char *buf;
+ void *bufaddr = &buf;
+ gcry_error_t rc;
+
+ rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+ if (rc)
+ fprintf (stderr, "%s=[error printing number: %s]\n",
+ text, gpg_strerror (rc));
+ else
+ {
+ fprintf (stderr, "%s=0x%s\n", text, buf);
+ gcry_free (buf);
+ }
+}
+
+
+static void
+check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
+{
+ gcry_sexp_t skey, pkey, list;
+
+ pkey = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pkey)
+ fail ("public part missing in return value\n");
+ else
+ {
+ gcry_mpi_t e = NULL;
+
+ list = gcry_sexp_find_token (pkey, "e", 0);
+ if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
+ fail ("public exponent not found\n");
+ else if (!expected_e)
+ {
+ if (verbose)
+ print_mpi ("e", e);
+ }
+ else if ( gcry_mpi_cmp_ui (e, expected_e))
+ {
+ print_mpi ("e", e);
+ fail ("public exponent is not %lu\n", expected_e);
+ }
+ gcry_sexp_release (list);
+ gcry_mpi_release (e);
+ gcry_sexp_release (pkey);
+ }
+
+ skey = gcry_sexp_find_token (key, "private-key", 0);
+ if (!skey)
+ fail ("private part missing in return value\n");
+ else
+ {
+ int rc = gcry_pk_testkey (skey);
+ if (rc)
+ fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
+ gcry_sexp_release (skey);
+ }
+
+ }
+
+static void
+check_rsa_keys (void)
+{
+ gcry_sexp_t keyparm, key;
+ int rc;
+ int i;
+
+ /* Check that DSA generation works and that it can grok the qbits
+ argument. */
+ if (verbose)
+ fprintf (stderr, "creating 5 1024 bit DSA keys\n");
+ for (i=0; i < 5; i++)
+ {
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:1024)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ gcry_sexp_release (key);
+ if (verbose)
+ fprintf (stderr, " done\n");
+ }
+
+ if (verbose)
+ fprintf (stderr, "creating 1536 bit DSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (dsa\n"
+ " (nbits 4:1536)\n"
+ " (qbits 3:224)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating DSA key: %s\n", gpg_strerror (rc));
+ if (debug)
+ {
+ char buffer[20000];
+ gcry_sexp_sprint (key, GCRYSEXP_FMT_ADVANCED, buffer, sizeof buffer);
+ if (verbose)
+ printf ("=============================\n%s\n"
+ "=============================\n", buffer);
+ }
+ gcry_sexp_release (key);
+
+ if (verbose)
+ fprintf (stderr, "creating 1024 bit RSA key\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ check_generated_rsa_key (key, 65537);
+ gcry_sexp_release (key);
+
+
+ if (verbose)
+ fprintf (stderr, "creating 512 bit RSA key with e=257\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 3:512)\n"
+ " (rsa-use-e 3:257)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ check_generated_rsa_key (key, 257);
+ gcry_sexp_release (key);
+
+ if (verbose)
+ fprintf (stderr, "creating 512 bit RSA key with default e\n");
+ rc = gcry_sexp_new (&keyparm,
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 3:512)\n"
+ " (rsa-use-e 1:0)\n"
+ " ))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gpg_strerror (rc));
+ rc = gcry_pk_genkey (&key, keyparm);
+ gcry_sexp_release (keyparm);
+ if (rc)
+ die ("error generating RSA key: %s\n", gpg_strerror (rc));
+
+ check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
+ gcry_sexp_release (key);
+
+}
+
+
+static void
+check_nonce (void)
+{
+ char a[32], b[32];
+ int i,j;
+ int oops=0;
+
+ if (verbose)
+ fprintf (stderr, "checking gcry_create_nonce\n");
+
+ gcry_create_nonce (a, sizeof a);
+ for (i=0; i < 10; i++)
+ {
+ gcry_create_nonce (b, sizeof b);
+ if (!memcmp (a, b, sizeof a))
+ die ("identical nounce found\n");
+ }
+ for (i=0; i < 10; i++)
+ {
+ gcry_create_nonce (a, sizeof a);
+ if (!memcmp (a, b, sizeof a))
+ die ("identical nounce found\n");
+ }
+
+ again:
+ for (i=1,j=0; i < sizeof a; i++)
+ if (a[0] == a[i])
+ j++;
+ if (j+1 == sizeof (a))
+ {
+ if (oops)
+ die ("impossible nonce found\n");
+ oops++;
+ gcry_create_nonce (a, sizeof a);
+ goto again;
+ }
+}
+
+
+static void
+progress_cb (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+ (void)what;
+ (void)current;
+ (void)total;
+
+ if (printchar == '\n')
+ fputs ( "<LF>", stdout);
+ else
+ putchar (printchar);
+ fflush (stdout);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ if (verbose)
+ gcry_set_progress_handler ( progress_cb, NULL );
+
+ check_rsa_keys ();
+ check_nonce ();
+
+ return error_count? 1:0;
+}
--- /dev/null
+/* keygrip.c - verifies that keygrips are calculated as expected
+ * Copyright (C) 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+static int repetitions;
+
+\f
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+static void
+print_hex (const char *text, const void *buf, size_t n)
+{
+ const unsigned char *p = buf;
+
+ fputs (text, stdout);
+ for (; n; n--, p++)
+ printf ("%02X", *p);
+ putchar ('\n');
+}
+
+
+\f
+
+static struct
+{
+ int algo;
+ const char *key;
+ const unsigned char grip[20];
+} key_grips[] =
+ {
+ {
+ GCRY_PK_RSA,
+ "(private-key"
+ " (rsa"
+ " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)"
+ " (e #010001#)"
+ " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)"
+ " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)"
+ " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)"
+ " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))",
+ "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25"
+ },
+ {
+ GCRY_PK_DSA,
+ " (public-key"
+ " (dsa"
+ " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)"
+ " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)"
+ " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)"
+ " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))",
+ "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10"
+
+ },
+ {
+ GCRY_PK_DSA,
+ "(private-key"
+ " (dsa"
+ " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)"
+ " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)"
+ " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)"
+ " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)"
+ " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))",
+ "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa"
+ " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+ " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)"
+ " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+ " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+ " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa"
+ " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+ " (curve \"NIST P-256\")"
+ " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+ " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+ " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ },
+ {
+ GCRY_PK_ECDSA,
+ "(public-key"
+ " (ecdsa"
+ " (curve secp256r1)"
+ " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+ "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+ }
+
+ };
+
+static void
+check (void)
+{
+ unsigned char buf[20];
+ unsigned char *ret;
+ gcry_error_t err;
+ gcry_sexp_t sexp;
+ unsigned int i;
+ int repn;
+
+ for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++)
+ {
+ if (gcry_pk_test_algo (key_grips[i].algo))
+ {
+ if (verbose)
+ fprintf (stderr, "algo %d not available; test skipped\n",
+ key_grips[i].algo);
+ continue;
+ }
+ err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key,
+ strlen (key_grips[i].key));
+ if (err)
+ die ("scanning data %d failed: %s\n", i, gpg_strerror (err));
+
+ for (repn=0; repn < repetitions; repn++)
+ {
+ ret = gcry_pk_get_keygrip (sexp, buf);
+ if (!ret)
+ die ("gcry_pk_get_keygrip failed for %d\n", i);
+
+ if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) )
+ {
+ print_hex ("keygrip: ", buf, sizeof buf);
+ die ("keygrip for %d does not match\n", i);
+ }
+ }
+
+ gcry_sexp_release (sexp);
+ }
+}
+
+\f
+
+static void
+progress_handler (void *cb_data, const char *what, int printchar,
+ int current, int total)
+{
+ (void)cb_data;
+ (void)what;
+ (void)current;
+ (void)total;
+
+ putchar (printchar);
+}
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int debug = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = 1;
+ debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--repetitions"))
+ {
+ argc--; argv++;
+ if (argc)
+ {
+ repetitions = atoi(*argv);
+ argc--; argv++;
+ }
+ }
+ }
+
+ if (repetitions < 1)
+ repetitions = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_set_progress_handler (progress_handler, NULL);
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ check ();
+
+ return 0;
+}
--- /dev/null
+/* mpitests.c - basic mpi tests
+ * Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+static int verbose;
+static int debug;
+
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+
+/* Set up some test patterns */
+
+/* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char ones[] = {
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
+};
+
+/* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char twos[] = {
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02
+};
+
+/* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char threes[] = {
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
+};
+
+/* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char eighties[] = {
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80
+};
+
+/* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
+unsigned char manyff[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+
+
+static int
+test_add (void)
+{
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t ff;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL);
+ result = gcry_mpi_new(0);
+
+ gcry_mpi_add(result, one, two);
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (verbose)
+ printf("Result of one plus two:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_add(result, ff, one);
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (verbose)
+ printf("Result of ff plus one:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(one);
+ gcry_mpi_release(two);
+ gcry_mpi_release(ff);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+static int
+test_sub (void)
+{
+ gcry_mpi_t one;
+ gcry_mpi_t two;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ result = gcry_mpi_new(0);
+ gcry_mpi_sub(result, two, one);
+
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (verbose)
+ printf("Result of two minus one:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(one);
+ gcry_mpi_release(two);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+static int
+test_mul (void)
+{
+ gcry_mpi_t two;
+ gcry_mpi_t three;
+ gcry_mpi_t result;
+ unsigned char* pc;
+
+ gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL);
+ gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL);
+ result = gcry_mpi_new(0);
+ gcry_mpi_mul(result, two, three);
+
+ gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
+ if (verbose)
+ printf("Result of two mul three:\n%s\n", pc);
+ gcry_free(pc);
+
+ gcry_mpi_release(two);
+ gcry_mpi_release(three);
+ gcry_mpi_release(result);
+ return 1;
+}
+
+
+/* What we test here is that we don't overwrite our args and that
+ using thne same mpi for several args works. */
+static int
+test_powm (void)
+{
+ int b_int = 17;
+ int e_int = 3;
+ int m_int = 19;
+ gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int);
+ gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int);
+ gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int);
+ gcry_mpi_t res = gcry_mpi_new (0);
+
+ gcry_mpi_powm (res, base, exp, mod);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using base for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (base, base, exp, mod);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using exp for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (exp, base, exp, mod);
+ if (gcry_mpi_cmp (res, exp))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check using mod for the result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui (exp, e_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (mod, base, exp, mod);
+ if (gcry_mpi_cmp (res, mod))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (exp, e_int))
+ die ("test_powm_ui failed for exp at %d\n", __LINE__);
+
+ /* Now check base ^ base mod mod. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (res, base, base, mod);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check base ^ base mod mod with base as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (base, base, base, mod);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (mod, m_int))
+ die ("test_powm failed for mod at %d\n", __LINE__);
+
+ /* Check base ^ base mod mod with mod as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_set_ui(mod, m_int);
+ gcry_mpi_powm (mod, base, base, mod);
+ if (gcry_mpi_cmp (res, mod))
+ die ("test_powm failed at %d\n", __LINE__);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+
+ /* Now check base ^ base mod base. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_powm (res, base, base, base);
+ if (gcry_mpi_cmp_ui (base, b_int))
+ die ("test_powm failed for base at %d\n", __LINE__);
+
+ /* Check base ^ base mod base with base as result. */
+ gcry_mpi_set_ui (base, b_int);
+ gcry_mpi_powm (base, base, base, base);
+ if (gcry_mpi_cmp (res, base))
+ die ("test_powm failed at %d\n", __LINE__);
+
+ /* Fixme: We should add the rest of the cases of course. */
+
+
+
+ return 1;
+}
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fputs ("version mismatch\n", stderr);
+ exit (1);
+ }
+ gcry_control(GCRYCTL_DISABLE_SECMEM);
+
+ test_add ();
+ test_sub ();
+ test_mul ();
+ test_powm ();
+
+ return 0;
+}
--- /dev/null
+/* pkbench.c - Pubkey menchmarking
+ * Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <gcrypt.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#ifndef HAVE_W32_SYSTEM
+# include <sys/times.h>
+#endif /*HAVE_W32_SYSTEM*/
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+
+#define PGM "pkbench"
+
+
+static int verbose;
+static int debug;
+static int error_count;
+
+
+typedef struct context
+{
+ gcry_sexp_t key_secret;
+ gcry_sexp_t key_public;
+ gcry_sexp_t data;
+ gcry_sexp_t data_encrypted;
+ gcry_sexp_t data_signed;
+} *context_t;
+
+typedef int (*work_t) (context_t context, unsigned int final);
+
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fputs ( PGM ": ", stderr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ putchar ('\n');
+ fputs ( PGM ": ", stderr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+static void *
+read_file (const char *fname, size_t *r_length)
+{
+ FILE *fp;
+ struct stat st;
+ char *buf;
+ size_t buflen;
+
+ fp = fopen (fname, "rb");
+ if (!fp)
+ {
+ fail ("can't open `%s': %s\n", fname, strerror (errno));
+ return NULL;
+ }
+
+ if (fstat (fileno(fp), &st))
+ {
+ fail ("can't stat `%s': %s\n", fname, strerror (errno));
+ fclose (fp);
+ return NULL;
+ }
+
+ buflen = st.st_size;
+ buf = gcry_xmalloc (buflen+1);
+ if (fread (buf, buflen, 1, fp) != 1)
+ {
+ fail ("error reading `%s': %s\n", fname, strerror (errno));
+ fclose (fp);
+ gcry_free (buf);
+ return NULL;
+ }
+ fclose (fp);
+
+ if (r_length)
+ *r_length = buflen;
+ return buf;
+}
+
+
+
+static void
+benchmark (work_t worker, context_t context)
+{
+ clock_t timer_start, timer_stop;
+ unsigned int loop = 10;
+ unsigned int i = 0;
+ struct tms timer;
+ int ret = 0;
+
+#ifdef HAVE_W32_SYSTEM
+ timer_start = clock ();
+#else
+ times (&timer);
+ timer_start = timer.tms_utime;
+#endif
+ for (i = 0; i < loop; i++)
+ {
+ ret = (*worker) (context, (i + 1) == loop);
+ if (! ret)
+ break;
+ }
+#ifdef HAVE_W32_SYSTEM
+ timer_stop = clock ();
+#else
+ times (&timer);
+ timer_stop = timer.tms_utime;
+#endif
+
+ if (ret)
+ printf ("%.0f ms\n",
+ (((double) ((timer_stop - timer_start) / loop)) / CLOCKS_PER_SEC)
+ * 10000000);
+ else
+ printf ("[skipped]\n");
+}
+
+static int
+work_encrypt (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t data_encrypted = NULL;
+ int ret = 1;
+
+ err = gcry_pk_encrypt (&data_encrypted,
+ context->data, context->key_public);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+ {
+ err = GPG_ERR_NO_ERROR;
+ ret = 0;
+ }
+ else
+ {
+ assert (! err);
+
+ if (final)
+ context->data_encrypted = data_encrypted;
+ else
+ gcry_sexp_release (data_encrypted);
+ }
+
+ return ret;
+}
+
+static int
+work_decrypt (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ int ret = 1;
+
+ if (! context->data_encrypted)
+ ret = 0;
+ else
+ {
+ gcry_sexp_t data_decrypted = NULL;
+
+ err = gcry_pk_decrypt (&data_decrypted,
+ context->data_encrypted,
+ context->key_secret);
+ assert (! err);
+ if (final)
+ {
+ gcry_sexp_release (context->data_encrypted);
+ context->data_encrypted = NULL;
+ }
+ gcry_sexp_release (data_decrypted);
+ }
+
+ return ret;
+}
+
+static int
+work_sign (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_sexp_t data_signed = NULL;
+ int ret = 1;
+
+ err = gcry_pk_sign (&data_signed,
+ context->data, context->key_secret);
+ if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED)
+ {
+ err = GPG_ERR_NO_ERROR;
+ ret = 0;
+ }
+ else if (err)
+ {
+ fail ("pk_sign failed: %s\n", gpg_strerror (err));
+ ret = 0;
+ }
+ else
+ {
+ if (final)
+ context->data_signed = data_signed;
+ else
+ gcry_sexp_release (data_signed);
+ }
+
+ return ret;
+}
+
+static int
+work_verify (context_t context, unsigned int final)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ int ret = 1;
+
+ if (!context->data_signed)
+ return 0;
+
+ err = gcry_pk_verify (context->data_signed,
+ context->data,
+ context->key_public);
+ if (err)
+ {
+ show_sexp ("data_signed:\n", context->data_signed);
+ show_sexp ("data:\n", context->data);
+ fail ("pk_verify failed: %s\n", gpg_strerror (err));
+ ret = 0;
+ }
+ else if (final)
+ {
+ gcry_sexp_release (context->data_signed);
+ context->data_signed = NULL;
+ }
+
+ return ret;
+}
+
+static void
+process_key_pair (context_t context)
+{
+ struct
+ {
+ work_t worker;
+ const char *identifier;
+ } worker_functions[] = { { work_encrypt, "encrypt" },
+ { work_decrypt, "decrypt" },
+ { work_sign, "sign" },
+ { work_verify, "verify" } };
+ unsigned int i = 0;
+
+ for (i = 0; i < (sizeof (worker_functions) / sizeof (*worker_functions)); i++)
+ {
+ printf ("%s: ", worker_functions[i].identifier);
+ benchmark (worker_functions[i].worker, context);
+ }
+}
+
+static void
+context_init (context_t context, gcry_sexp_t key_secret, gcry_sexp_t key_public)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ unsigned int key_size = 0;
+ gcry_mpi_t data = NULL;
+ gcry_sexp_t data_sexp = NULL;
+
+ key_size = gcry_pk_get_nbits (key_secret);
+ assert (key_size);
+
+ data = gcry_mpi_new (key_size);
+ assert (data);
+
+ gcry_mpi_randomize (data, key_size, GCRY_STRONG_RANDOM);
+ gcry_mpi_clear_bit (data, key_size - 1);
+ err = gcry_sexp_build (&data_sexp, NULL,
+ "(data (flags raw) (value %m))",
+ data);
+ assert (! err);
+ gcry_mpi_release (data);
+
+ context->key_secret = key_secret;
+ context->key_public = key_public;
+ context->data = data_sexp;
+ context->data_encrypted = NULL;
+ context->data_signed = NULL;
+}
+
+static void
+context_destroy (context_t context)
+{
+ gcry_sexp_release (context->key_secret);
+ gcry_sexp_release (context->key_public);
+ gcry_sexp_release (context->data);
+}
+
+static void
+process_key_pair_file (const char *key_pair_file)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ void *key_pair_buffer = NULL;
+ gcry_sexp_t key_pair_sexp = NULL;
+ gcry_sexp_t key_secret_sexp = NULL;
+ gcry_sexp_t key_public_sexp = NULL;
+ struct context context = { NULL };
+ size_t file_length;
+
+ key_pair_buffer = read_file (key_pair_file, &file_length);
+ if (!key_pair_buffer)
+ die ("failed to open `%s'\n", key_pair_file);
+
+ err = gcry_sexp_sscan (&key_pair_sexp, NULL,
+ key_pair_buffer, file_length);
+ if (err)
+ die ("gcry_sexp_sscan failed\n");
+
+ key_secret_sexp = gcry_sexp_find_token (key_pair_sexp, "private-key", 0);
+ assert (key_secret_sexp);
+ key_public_sexp = gcry_sexp_find_token (key_pair_sexp, "public-key", 0);
+ assert (key_public_sexp);
+
+ gcry_sexp_release (key_pair_sexp);
+
+ context_init (&context, key_secret_sexp, key_public_sexp);
+
+ printf ("Key file: %s\n", key_pair_file);
+ process_key_pair (&context);
+ printf ("\n");
+
+ context_destroy (&context);
+ gcry_free (key_pair_buffer);
+}
+
+
+static void
+generate_key (const char *algorithm, const char *key_size)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ size_t key_pair_buffer_size = 0;
+ char *key_pair_buffer = NULL;
+ gcry_sexp_t key_spec = NULL;
+ gcry_sexp_t key_pair = NULL;
+
+ if (isdigit ((unsigned int)*key_size))
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (%s (nbits %s)))",
+ algorithm, key_size);
+ else
+ err = gcry_sexp_build (&key_spec, NULL,
+ "(genkey (%s (curve %s)))",
+ algorithm, key_size);
+ if (err)
+ die ("sexp_build failed: %s\n", gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key_pair, key_spec);
+ if (err)
+ {
+ show_sexp ("request:\n", key_spec);
+ die ("pk_genkey failed: %s\n", gpg_strerror (err));
+ }
+
+ key_pair_buffer_size = gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+ NULL, 0);
+ key_pair_buffer = gcry_xmalloc (key_pair_buffer_size);
+
+ gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED,
+ key_pair_buffer, key_pair_buffer_size);
+
+ printf ("%.*s", (int)key_pair_buffer_size, key_pair_buffer);
+ gcry_free (key_pair_buffer);
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int genkey_mode = 0;
+ int fips_mode = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ puts ("Usage: " PGM " [OPTIONS] [FILES]\n"
+ "Various public key tests:\n\n"
+ " Default is to process all given key files\n\n"
+ " --genkey ALGONAME SIZE Generate a public key\n"
+ "\n"
+ " --verbose enable extra informational output\n"
+ " --debug enable additional debug output\n"
+ " --help display this help and exit\n\n");
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--genkey"))
+ {
+ genkey_mode = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--fips"))
+ {
+ fips_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
+ if (fips_mode)
+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ {
+ fprintf (stderr, PGM ": version mismatch\n");
+ exit (1);
+ }
+
+ if (genkey_mode)
+ {
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ }
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+
+ if (genkey_mode && argc == 2)
+ {
+ generate_key (argv[0], argv[1]);
+ }
+ else if (!genkey_mode && argc)
+ {
+ int i;
+
+ for (i = 0; i < argc; i++)
+ process_key_pair_file (argv[i]);
+ }
+ else
+ {
+ fprintf (stderr, "usage: " PGM
+ " [OPTIONS] [FILES] (try --help for more information)\n");
+ exit (1);
+ }
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* pkcs1v2-oaep.h - OAEP test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the OAEP file in
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip
+ */
+
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *seed;
+ const char *encr;
+ } m[6];
+ } tbl[] = {
+ {
+ "Example 1: A 1024-bit RSA key pair",
+ "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0ab"
+ "c4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72"
+ "f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb514"
+ "8ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb",
+ "010001",
+ "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd"
+ "8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55"
+ "fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbf"
+ "b78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1",
+ {
+ {
+ "OAEP Example 1.1",
+ "6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34",
+ "18b776ea21069d69776a33e96bad48e1dda0a5ef",
+ "354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb"
+ "21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535f"
+ "a9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426"
+ "d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"
+ },{
+ "OAEP Example 1.2",
+ "750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5",
+ "0cc742ce4a9b7f32f951bcb251efd925fe4fe35f",
+ "640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c11"
+ "65988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352"
+ "d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74b"
+ "bbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44"
+ },{
+ "OAEP Example 1.3",
+ "d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c245"
+ "1fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051",
+ "2514df4695755a67b288eaf4905c36eec66fd2fd",
+ "423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603"
+ "595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4"
+ "360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3"
+ "066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb"
+ },{
+ "OAEP Example 1.4",
+ "52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85",
+ "c4435a3e1a18a68b6820436290a37cefb85db3fb",
+ "45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e"
+ "22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646f"
+ "d0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4"
+ "bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755"
+ },{
+ "OAEP Example 1.5",
+ "8da89fd9e5f974a29feffb462b49180f6cf9e802",
+ "b318c42df3be0f83fea823f5a7b47ed5e425a3b5",
+ "36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e2"
+ "19005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea"
+ "0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6d"
+ "d18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439"
+ },{
+ "OAEP Example 1.6",
+ "26521050844271",
+ "e4ec0982c2336f3a677f6a356174eb0ce887abc2",
+ "42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4"
+ "ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3d"
+ "f06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded2"
+ "43b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255"
+ }
+ }
+ },
+ {
+ "Example 2: A 1025-bit RSA key pair",
+ "01947c7fce90425f47279e70851f25d5e62316fe8a1df19371e3e628e260543e"
+ "4901ef6081f68c0b8141190d2ae8daba7d1250ec6db636e944ec3722877c7c1d"
+ "0a67f14b1694c5f0379451a43e49a32dde83670b73da91a1c99bc23b436a6005"
+ "5c610f0baf99c1a079565b95a3f1526632d1d4da60f20eda25e653c4f002766f"
+ "45",
+ "010001",
+ "0823f20fadb5da89088a9d00893e21fa4a1b11fbc93c64a3be0baaea97fb3b93"
+ "c3ff713704c19c963c1d107aae99054739f79e02e186de86f87a6ddefea6d8cc"
+ "d1d3c81a47bfa7255be20601a4a4b2f08a167b5e279d715b1b455bdd7eab2459"
+ "41d9768b9acefb3ccda5952da3cee72525b4501663a8ee15c9e992d92462fe39",
+ {
+ {
+ "OAEP Example 2.1",
+ "8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7",
+ "8c407b5ec2899e5099c53e8ce793bf94e71b1782",
+ "0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a"
+ "5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df34"
+ "56653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8a"
+ "bb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe72"
+ "0e"
+ },{
+ "OAEP Example 2.2",
+ "2d",
+ "b600cf3c2e506d7f16778c910d3a8b003eee61d5",
+ "018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165ee"
+ "e33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b0709939"
+ "98e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc"
+ "95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba102"
+ "45"
+ },{
+ "OAEP Example 2.3",
+ "74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e",
+ "a73768aeeaa91f9d8c1ed6f9d2b63467f07ccae3",
+ "018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c7"
+ "9f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651"
+ "bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8b"
+ "b2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be20"
+ "53"
+ },{
+ "OAEP Example 2.4",
+ "a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721"
+ "dfe885072c78a203b151739be540fa8c153a10f00a",
+ "9a7b3b0e708bd96f8190ecab4fb9b2b3805a8156",
+ "00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c"
+ "649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b"
+ "31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa0876"
+ "36965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc76"
+ "41"
+ },{
+ "OAEP Example 2.5",
+ "2ef2b066f854c33f3bdcbb5994a435e73d6c6c",
+ "eb3cebbc4adc16bb48e88c8aec0e34af7f427fd3",
+ "00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d"
+ "931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da0"
+ "8bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806"
+ "e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7a"
+ "ec",
+ },{
+ "OAEP Example 2.6",
+ "8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0",
+ "4c45cf4d57c98e3d6d2095adc51c489eb50dff84",
+ "010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd"
+ "5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5"
+ "a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765"
+ "cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef"
+ "3a"
+ }
+ }
+ },
+ {
+ "Example 3: A 1026-bit RSA key pair",
+ "02b58fec039a860700a4d7b6462f93e6cdd491161ddd74f4e810b40e3c165200"
+ "6a5c277b2774c11305a4cbab5a78efa57e17a86df7a3fa36fc4b1d2249f22ec7"
+ "c2dd6a463232accea906d66ebe80b5704b10729da6f833234abb5efdd4a292cb"
+ "fad33b4d33fa7a14b8c397b56e3acd21203428b77cdfa33a6da706b3d8b0fc43"
+ "e9",
+ "010001",
+ "15b48a5b5683a94670e23b5718f814fa0e13f85038f50711182cba61510581f3"
+ "d22c7e232ef937e22e551d68b86e2f8cb1aad8be2e488f5df7efd279e3f568d4"
+ "eaf36f80cf7141ace60fcc9113fb6c4a841fd50bbc7c512ffcbeff21487aa811"
+ "eb3ca8c62005346a86de86bfa1d8a948fd3f348c22eaadf333c3ce6ce13208fd",
+ {
+ {
+ "OAEP Example 3.1",
+ "087820b569e8fa8d",
+ "8ced6b196290805790e909074015e6a20b0c4894",
+ "026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d"
+ "5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2"
+ "b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d3"
+ "7e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae"
+ "80"
+ },{
+ "OAEP Example 3.2",
+ "4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04",
+ "b4291d6567550848cc156967c809baab6ca507f0",
+ "024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da"
+ "72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca206"
+ "9d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3"
+ "e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4b"
+ "f5"
+ },{
+ "OAEP Example 3.3",
+ "d94cd0e08fa404ed89",
+ "ce8928f6059558254008badd9794fadcd2fd1f65",
+ "0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844"
+ "ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950"
+ "fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962be"
+ "c22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a"
+ "3a"
+ },{
+ "OAEP Example 3.4",
+ "6cc641b6b61e6f963974dad23a9013284ef1",
+ "6e2979f52d6814a57d83b090054888f119a5b9a3",
+ "02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b"
+ "42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9d"
+ "ec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8"
+ "d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9"
+ "a0"
+ },{
+ "OAEP Example 3.5",
+ "df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca69"
+ "18017cfda1153bf7a6af87593223",
+ "2d760bfe38c59de34cdc8b8c78a38e66284a2d27",
+ "0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee6"
+ "7f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545"
+ "fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943a"
+ "b8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c"
+ "60",
+ },{
+ "OAEP Example 3.6",
+ "3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e"
+ "1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1",
+ "f174779c5fd3cfe007badcb7a36c9b55bfcfbf0e",
+ "00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490"
+ "b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e5"
+ "74744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac37"
+ "85d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d0057"
+ "30"
+ }
+ }
+ },
+ {
+ "Example 4: A 1027-bit RSA key pair",
+ "051240b6cc0004fa48d0134671c078c7c8dec3b3e2f25bc2564467339db38853"
+ "d06b85eea5b2de353bff42ac2e46bc97fae6ac9618da9537a5c8f553c1e35762"
+ "5991d6108dcd7885fb3a25413f53efcad948cb35cd9b9ae9c1c67626d113d57d"
+ "de4c5bea76bb5bb7de96c00d07372e9685a6d75cf9d239fa148d70931b5f3fb0"
+ "39",
+ "010001",
+ "0411ffca3b7ca5e9e9be7fe38a85105e353896db05c5796aecd2a725161eb365"
+ "1c8629a9b862b904d7b0c7b37f8cb5a1c2b54001018a00a1eb2cafe4ee4e9492"
+ "c348bc2bedab4b9ebbf064e8eff322b9009f8eec653905f40df88a3cdc49d456"
+ "7f75627d41aca624129b46a0b7c698e5e65f2b7ba102c749a10135b6540d0401",
+ {
+ {
+ "OAEP Example 4.1",
+ "4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d"
+ "7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2",
+ "1cac19ce993def55f98203f6852896c95ccca1f3",
+ "04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5"
+ "781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96f"
+ "e155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896"
+ "935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1"
+ "a8"
+ },{
+ "OAEP Example 4.2",
+ "b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98"
+ "f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8",
+ "f545d5897585e3db71aa0cb8da76c51d032ae963",
+ "0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b1"
+ "3b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186"
+ "c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18"
+ "381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed1"
+ "5e"
+ },{
+ "OAEP Example 4.3",
+ "bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b"
+ "0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99",
+ "ad997feef730d6ea7be60d0dc52e72eacbfdd275",
+ "0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77"
+ "319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd0"
+ "01dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193"
+ "302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d0"
+ "65"
+ },{
+ "OAEP Example 4.4",
+ "fb2ef112f5e766eb94019297934794f7be2f6fc1c58e",
+ "136454df5730f73c807a7e40d8c1a312ac5b9dd3",
+ "02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a"
+ "796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e4"
+ "4fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c6"
+ "8e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11"
+ "e4"
+ },{
+ "OAEP Example 4.5",
+ "28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c"
+ "2284",
+ "bca8057f824b2ea257f2861407eef63d33208681",
+ "00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a4431079"
+ "9066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f1"
+ "8ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a8324756"
+ "8292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1e"
+ "c2"
+ },{
+ "OAEP Example 4.6",
+ "f22242751ec6b1",
+ "2e7e1e17f647b5ddd033e15472f90f6812f3ac4e",
+ "00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e1"
+ "7cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83"
+ "b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc825"
+ "0c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619"
+ "a9"
+ }
+ }
+ },
+ {
+ "Example 5: A 1028-bit RSA key pair",
+ "0aadf3f9c125e5d891f31ac448e993defe580f802b45f9d7f22ba5021e9c4757"
+ "6b5a1e68031ba9db4e6dabe4d96a1d6f3d267268cff408005f118efcadb99888"
+ "d1c234467166b2a2b849a05a889c060ac0da0c5fae8b55f309ba62e703742fa0"
+ "326f2d10b011021489ff497770190d895fd39f52293c39efd73a698bdab9f10e"
+ "d9",
+ "010001",
+ "0256eb4cba7067f2d2be540dcdff4582a36b7d31d1c9099bb214b79848466a26"
+ "8f80f58a49ac04c0e3648934a0206c04537c19b236643a6082732144df75fa21"
+ "7588f794682be89168276dc726c5c0cbdb84d31bbf26d0a43af495717f7d528a"
+ "cfee341561f6ff3cae05c578f8470d9682f9c0d072f9f6068b56d5880f682be2"
+ "c5",
+ {
+ {
+ "OAEP Example 5.1",
+ "af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8",
+ "44c92e283f77b9499c603d963660c87d2f939461",
+ "036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a6"
+ "8651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df79"
+ "9f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a"
+ "519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000"
+ "e5"
+ },{
+ "OAEP Example 5.2",
+ "a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b"
+ "4ac3303ec73f0f87cfb32399",
+ "cb28f5860659fceee49c3eeafce625a70803bd32",
+ "03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f"
+ "54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399"
+ "fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a283"
+ "7a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7"
+ "ad"
+ },{
+ "OAEP Example 5.3",
+ "308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a31"
+ "4bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7",
+ "2285f40d770482f9a9efa2c72cb3ac55716dc0ca",
+ "0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2c"
+ "a7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325"
+ "a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c"
+ "9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b69"
+ "67"
+ },{
+ "OAEP Example 5.4",
+ "15c5b9ee1185",
+ "49fa45d3a78dd10dfd577399d1eb00af7eed5513",
+ "0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588f"
+ "f59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671"
+ "a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2"
+ "e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719a"
+ "bf"
+ },{
+ "OAEP Example 5.5",
+ "21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a673"
+ "7277365d3fea11db8923a2029a",
+ "f0287413234cc5034724a094c4586b87aff133fc",
+ "07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241"
+ "c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51de"
+ "b507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0e"
+ "e3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc25097"
+ "23"
+ },{
+ "OAEP Example 5.6",
+ "541e37b68b6c8872b84c02",
+ "d9fba45c96f21e6e26d29eb2cdcb6585be9cb341",
+ "08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef"
+ "74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701e"
+ "d9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae"
+ "277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f2"
+ "4a"
+ }
+ }
+ },
+ {
+ "Example 6: A 1029-bit RSA key pair",
+ "12b17f6dad2ecd19ff46dc13f7860f09e0e0cfb677b38a52592305ceaf022c16"
+ "6db90d04ac29e33f7dd12d9faf66e0816bb63ead267cc7d46c17c37be214bca2"
+ "a22d723a64e44407436b6fc965729aefc2554f376cd5dcea68293780a62bf39d"
+ "0029485a160bbb9e5dc0972d21a504f52e5ee028aa416332f510b2e9cff5f722"
+ "af",
+ "010001",
+ "0295eca3560618369559cecd303aa9cfdafc1d9f06959df75ffef929aa896961"
+ "bcd190dc6997eda7f5963e724d07b4dc11f3065e5ae97d96835112280b9084bb"
+ "14f2a21ebd4e889d41b9c4132ec1956fcab8bb2fed0575884936522c5ff7d332"
+ "61904824e7cadee4e0bb372d2457cf78e2bd1286228ff83f10731ce63c90cff3"
+ "f9",
+ {
+ {
+ "OAEP Example 6.1",
+ "4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4",
+ "dd0f6cfe415e88e5a469a51fbba6dfd40adb4384",
+ "0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ac"
+ "e583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc"
+ "3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34d"
+ "ebdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1"
+ "a3"
+ },{
+ "OAEP Example 6.2",
+ "5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92"
+ "b22512214e4be6c914792ddabdf57faa8aa7",
+ "8d14bd946a1351148f5cae2ed9a0c653e85ebd85",
+ "0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c"
+ "436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50"
+ "f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3"
+ "f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e6"
+ "3f"
+ },{
+ "OAEP Example 6.3",
+ "b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d8"
+ "31f2ab068b23b149879c002f6bf3feee97591112562c",
+ "6c075bc45520f165c0bf5ea4c5df191bc9ef0e44",
+ "0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844"
+ "202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350"
+ "c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c"
+ "7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d"
+ "65"
+ },{
+ "OAEP Example 6.4",
+ "684e3038c5c041f7",
+ "3bbc3bd6637dfe12846901029bf5b0c07103439c",
+ "008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e6"
+ "95263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa3997"
+ "4b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c560"
+ "90267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52"
+ "f8"
+ },{
+ "OAEP Example 6.5",
+ "32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693",
+ "b46b41893e8bef326f6759383a83071dae7fcabc",
+ "00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31f"
+ "edf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045"
+ "ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f"
+ "42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384"
+ "ab"
+ },{
+ "OAEP Example 6.6",
+ "50ba14be8462720279c306ba",
+ "0a2403312a41e3d52f060fbc13a67de5cf7609a7",
+ "0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c9"
+ "2c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d7963"
+ "4cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29"
+ "164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab54"
+ "70"
+ }
+ }
+ },
+ {
+ "Example 7: A 1030-bit RSA key pair",
+ "311179f0bcfc9b9d3ca315d00ef30d7bdd3a2cfae9911bfedcb948b3a4782d07"
+ "32b6ab44aa4bf03741a644dc01bec3e69b01a033e675d8acd7c4925c6b1aec31"
+ "19051dfd89762d215d45475ffcb59f908148623f37177156f6ae86dd7a7c5f43"
+ "dc1e1f908254058a284a5f06c0021793a87f1ac5feff7dcaee69c5e51a3789e3"
+ "73",
+ "010001",
+ "070cfcff2feb8276e27432c45dfee48f49b7917d6530e1f0ca3460f32e027617"
+ "4487c56e22a45d2500d7775495219d7d165a9cf3bd92c32af9a98d8dc9cc2968"
+ "00adc94a0a54fb40f34291bf84ee8ea12b6f109359c6d3542a50f9c767f5cfff"
+ "05a681c2e656fb77caaadb4be9468d8abcd4df98f58e86d2053fa1349f748e21"
+ "b1",
+ {
+ {
+ "OAEP Example 7.1",
+ "47aae909",
+ "43dd09a07ff4cac71caa4632ee5e1c1daee4cd8f",
+ "1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97"
+ "b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d28"
+ "2f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223d"
+ "c60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85"
+ "c1"
+ },{
+ "OAEP Example 7.2",
+ "1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7",
+ "3a9c3cec7b84f9bd3adecbc673ec99d54b22bc9b",
+ "1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b973"
+ "6edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451"
+ "f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323"
+ "d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3"
+ "b6"
+ },{
+ "OAEP Example 7.3",
+ "d976fc",
+ "76a75e5b6157a556cf8884bb2e45c293dd545cf5",
+ "2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298"
+ "707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1"
+ "c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85"
+ "018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc5455"
+ "6b"
+ },{
+ "OAEP Example 7.4",
+ "d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5"
+ "f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb",
+ "7866314a6ad6f2b250a35941db28f5864b585859",
+ "0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a"
+ "312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423"
+ "b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c"
+ "1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bf"
+ "ac"
+ },{
+ "OAEP Example 7.5",
+ "bb47231ca5ea1d3ad46c99345d9a8a61",
+ "b2166ed472d58db10cab2c6b000cccf10a7dc509",
+ "028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b241"
+ "84114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8"
+ "e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e"
+ "4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed3474"
+ "78"
+ },{
+ "OAEP Example 7.6",
+ "2184827095d35c3f86f600e8e59754013296",
+ "52673bde2ca166c2aa46131ac1dc808d67d7d3b1",
+ "14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd4"
+ "7d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e3"
+ "46eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2ac"
+ "f7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae6741"
+ "15"
+ }
+ }
+ },
+ {
+ "Example 8: A 1031-bit RSA key pair",
+ "5bdf0e30d321dda5147f882408fa69195480df8f80d3f6e8bf5818504f36427c"
+ "a9b1f5540b9c65a8f6974cf8447a244d9280201bb49fcbbe6378d1944cd227e2"
+ "30f96e3d10f819dcef276c64a00b2a4b6701e7d01de5fabde3b1e9a0df82f463"
+ "1359cd22669647fbb1717246134ed7b497cfffbdc42b59c73a96ed90166212df"
+ "f7",
+ "010001",
+ "0f7d1e9e5aaa25fd13e4a0663ae144e0d15f5cd18bcdb09df2cc7e64e3c5e915"
+ "ad62645304161d098c715bb7ab8bd01d07eaf3fed7c7ed08af2a8a62ef44ab16"
+ "b320e14af72a48f96afe262a0ae4cf65e635e910790cd4ee5cea768a4b2639f7"
+ "e6f677b3f0bb6be32b75747d8909036f0264f58d401cdba131716157a75ecf63"
+ "31",
+ {
+ {
+ "OAEP Example 8.1",
+ "050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c82"
+ "5bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967",
+ "7706ffca1ecfb1ebee2a55e5c6e24cd2797a4125",
+ "09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b3040"
+ "9472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d1291979"
+ "0410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0"
+ "970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b"
+ "61"
+ },{
+ "OAEP Example 8.2",
+ "4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18"
+ "a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc",
+ "a3717da143b4dcffbc742665a8fa950585548343",
+ "2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256"
+ "f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a341165"
+ "6424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df5"
+ "06fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee3"
+ "9d"
+ },{
+ "OAEP Example 8.3",
+ "8604ac56328c1ab5ad917861",
+ "ee06209073cca026bb264e5185bf8c68b7739f86",
+ "4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e"
+ "0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd"
+ "31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2b"
+ "e780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca989"
+ "3f"
+ },{
+ "OAEP Example 8.4",
+ "fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0d"
+ "ddcc",
+ "990ad573dc48a973235b6d82543618f2e955105d",
+ "2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812"
+ "fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175"
+ "a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b"
+ "15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fb"
+ "d0"
+ },{
+ "OAEP Example 8.5",
+ "4a5f4914bee25de3c69341de07",
+ "ecc63b28f0756f22f52ac8e6ec1251a6ec304718",
+ "1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5"
+ "e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923"
+ "359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5"
+ "f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7"
+ "b2"
+ },{
+ "OAEP Example 8.6",
+ "8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be",
+ "3925c71b362d40a0a6de42145579ba1e7dd459fc",
+ "3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5b"
+ "f1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f07"
+ "5aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c9"
+ "8b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c2"
+ "10"
+ }
+ }
+ },
+ {
+ "Example 9: A 1536-bit RSA key pair",
+ "cf2cd41e34ca3a728ea5cb8aff64c36d27bdef5364e336fd68d3123c5a196a8c"
+ "287013e853d5156d58d151954520fb4f6d7b17abb6817765909c576119659d90"
+ "2b1906ed8a2b10c155c24d124528dab9eeae379beac66e4a411786dcb8fd0062"
+ "ebc030de1219a04c2a8c1b7dd3131e4d6b6caee2e31a5ed41ac1509b2ef1ee2a"
+ "b18364be568ca941c25ecc84ff9d643b5ec1aaae102a20d73f479b780fd6da91"
+ "075212d9eac03a0674d899eba2e431f4c44b615b6ba2232bd4b33baed73d625d",
+ "010001",
+ "198c141e23715a92bccf6a119a5bc11389468d2811f548d727e17b4ab0eb986d"
+ "6f211efb53b71f7ccbea87ee69c75ee615008c5332deb52bf390abdfbfe37d72"
+ "05368159b2638c1de326e21d22251f0fb5848b3bf15005d2a74330f0afe916ee"
+ "62ccc1344d1d83a709e60676273840f7f377424a5e0a4da75f01b31ff76819cf"
+ "9cbfdd215243c3917c03ef38199312e567b3bf7aed3ab457f371ef8a1423f45b"
+ "68c6e282ec111bba2833b987fd69fad83bc1b8c613c5e1ea16c11ed125ea7ec1",
+ {
+ {
+ "OAEP Example 9.1",
+ "f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec"
+ "0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6",
+ "8ec965f134a3ec9931e92a1ca0dc8169d5ea705c",
+ "267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4d"
+ "b751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376c"
+ "a7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182"
+ "c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c0"
+ "91ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b554"
+ "90d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72"
+ },{
+ "OAEP Example 9.2",
+ "81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc"
+ "818bf420c54659",
+ "ecb1b8b25fa50cdab08e56042867f4af5826d16c",
+ "93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a1"
+ "4841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f"
+ "5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5f"
+ "cb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d860"
+ "97ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673"
+ "c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8"
+ },{
+ "OAEP Example 9.3",
+ "fd326429df9b890e09b54b18b8f34f1e24",
+ "e89bb032c6ce622cbdb53bc9466014ea77f777c0",
+ "81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba"
+ "5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e"
+ "813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93"
+ "edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f"
+ "20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753e"
+ "aaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3"
+ },{
+ "OAEP Example 9.4",
+ "f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4"
+ "e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e",
+ "606f3b99c0b9ccd771eaa29ea0e4c884f3189ccc",
+ "bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87"
+ "b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446"
+ "ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f497"
+ "7af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b475"
+ "62792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec25"
+ "79c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858"
+ },{
+ "OAEP Example 9.5",
+ "53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef37"
+ "39e7b595abb96e8d55e54f7bd41ab433378ffb911d",
+ "fcbc421402e9ecabc6082afa40ba5f26522c840e",
+ "232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d2"
+ "81b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e"
+ "66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a"
+ "1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6"
+ "cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d"
+ "44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e"
+ },{
+ "OAEP Example 9.6",
+ "b6b28ea2198d0c1008bc64",
+ "23aade0e1e08bb9b9a78d2302a52f9c21b2e1ba2",
+ "438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081"
+ "c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b"
+ "9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235"
+ "b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e9473245"
+ "0434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de55"
+ "89e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f"
+ }
+ }
+ },
+ {
+ "Example 10: A 2048-bit RSA key pair",
+ "ae45ed5601cec6b8cc05f803935c674ddbe0d75c4c09fd7951fc6b0caec313a8"
+ "df39970c518bffba5ed68f3f0d7f22a4029d413f1ae07e4ebe9e4177ce23e7f5"
+ "404b569e4ee1bdcf3c1fb03ef113802d4f855eb9b5134b5a7c8085adcae6fa2f"
+ "a1417ec3763be171b0c62b760ede23c12ad92b980884c641f5a8fac26bdad4a0"
+ "3381a22fe1b754885094c82506d4019a535a286afeb271bb9ba592de18dcf600"
+ "c2aeeae56e02f7cf79fc14cf3bdc7cd84febbbf950ca90304b2219a7aa063aef"
+ "a2c3c1980e560cd64afe779585b6107657b957857efde6010988ab7de417fc88"
+ "d8f384c4e6e72c3f943e0c31c0c4a5cc36f879d8a3ac9d7d59860eaada6b83bb",
+ "010001",
+ "056b04216fe5f354ac77250a4b6b0c8525a85c59b0bd80c56450a22d5f438e59"
+ "6a333aa875e291dd43f48cb88b9d5fc0d499f9fcd1c397f9afc070cd9e398c8d"
+ "19e61db7c7410a6b2675dfbf5d345b804d201add502d5ce2dfcb091ce9997bbe"
+ "be57306f383e4d588103f036f7e85d1934d152a323e4a8db451d6f4a5b1b0f10"
+ "2cc150e02feee2b88dea4ad4c1baccb24d84072d14e1d24a6771f7408ee30564"
+ "fb86d4393a34bcf0b788501d193303f13a2284b001f0f649eaf79328d4ac5c43"
+ "0ab4414920a9460ed1b7bc40ec653e876d09abc509ae45b525190116a0c26101"
+ "848298509c1c3bf3a483e7274054e15e97075036e989f60932807b5257751e79",
+ {
+ {
+ "OAEP Example 10.1",
+ "8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee",
+ "47e1ab7119fee56c95ee5eaad86f40d0aa63bd33",
+ "53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19"
+ "bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e6139614"
+ "4e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfc"
+ "c7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a87"
+ "74a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1"
+ "fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505"
+ "adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464"
+ "739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc"
+ },{
+ "OAEP Example 10.2",
+ "e6ad181f053b58a904f2457510373e57",
+ "6d17f5b4c1ffac351d195bf7b09d09f09a4079cf",
+ "a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f58744001"
+ "10828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2"
+ "a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b577"
+ "6eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0b"
+ "b19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2"
+ "acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e719"
+ "64607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9f"
+ "ccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795"
+ },{
+ "OAEP Example 10.3",
+ "510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124",
+ "385387514deccc7c740dd8cdf9daee49a1cbfd54",
+ "9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6ed"
+ "c56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9"
+ "b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0"
+ "742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8"
+ "fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4a"
+ "fc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002"
+ "f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975"
+ "e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede"
+ },{
+ "OAEP Example 10.4",
+ "bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649"
+ "a94045c9",
+ "5caca6a0f764161a9684f85d92b6e0ef37ca8b65",
+ "6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2"
+ "dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97b"
+ "ad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af49"
+ "9408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa71"
+ "22e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d1"
+ "5bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc8"
+ "55828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6d"
+ "e1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8"
+ },{
+ "OAEP Example 10.5",
+ "a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9",
+ "95bca9e3859894b3dd869fa7ecd5bbc6401bf3e4",
+ "75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee"
+ "464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28"
+ "429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d1"
+ "1b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab1"
+ "31573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d5"
+ "1f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5f"
+ "a6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e72"
+ "2eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0"
+ },{
+ "OAEP Example 10.6",
+ "eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed0"
+ "0b7c39ec6922d7b8ea2c04ebac",
+ "9f47ddf42e97eea856a9bdbc714eb3ac22f6eb32",
+ "2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816"
+ "679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492f"
+ "d6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709"
+ "bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b97"
+ "3f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afd"
+ "d2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce"
+ "58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bf"
+ "d90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46"
+ }
+ }
+ }
+ };
--- /dev/null
+/* pkcs1v2-pss.h - PSS test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the PSS file in
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip
+ */
+
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *salt;
+ const char *sign;
+ } m[6];
+ } tbl[] =
+ {
+ {
+ "Example 1: A 1024-bit RSA key pair",
+ "a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991"
+ "d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1df"
+ "d5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f1"
+ "05acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",
+ "010001",
+ "33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e8"
+ "94a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9a"
+ "e55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c"
+ "31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",
+ {
+ {
+ "PSS Example 1.1",
+ "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b6"
+ "2371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb76"
+ "9757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb0"
+ "61a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d61"
+ "93c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c"
+ "296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16"
+ "be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0",
+ "dee959c7e06411361420ff80185ed57f3e6776af",
+ "9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887"
+ "e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215"
+ "df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65"
+ "984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c"
+ },{
+ "PSS Example 1.2",
+ "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f"
+ "71a1cca582d43ecc72b1bca16dfc7013226b9e",
+ "ef2869fa40c346cb183dab3d7bffc98fd56df42d",
+ "3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04e"
+ "f29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c45"
+ "17832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b935"
+ "90241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843"
+ },{
+ "PSS Example 1.3",
+ "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef"
+ "8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955"
+ "fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c7"
+ "45e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4"
+ "564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c"
+ "031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa"
+ "299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef4169713"
+ "38e7d470",
+ "710b9c4747d800d4de87f12afdce6df18107cc77",
+ "666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c001"
+ "54c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e614"
+ "3c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23a"
+ "a51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1"
+ },{
+ "PSS Example 1.4",
+ "bc656747fa9eafb3f0",
+ "056f00985de14d8ef5cea9e82f8c27bef720335e",
+ "4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c"
+ "178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad"
+ "8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e18"
+ "33b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87",
+ },{
+ "PSS Example 1.5",
+ "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776"
+ "c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575"
+ "480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f"
+ "32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc"
+ "5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4",
+ "80e70ff86a08de3ec60972b39b4fbfdcea67ae8e",
+ "1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73"
+ "479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c59"
+ "60da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db"
+ "4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad"
+ },{
+ "PSS Example 1.6",
+ "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec"
+ "74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4"
+ "352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b7"
+ "05a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb87"
+ "94c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373"
+ "d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb"
+ "3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6"
+ "138d144f8ce4e2da73",
+ "a8ab69dd801f0074c2a1fc60649836c616d99681",
+ "2a34f6125e1f6b0bf971e84fbd41c632be8f2c2ace7de8b6926e31ff93e9af98"
+ "7fbc06e51e9be14f5198f91f3f953bd67da60a9df59764c3dc0fe08e1cbef0b7"
+ "5f868d10ad3fba749fef59fb6dac46a0d6e504369331586f58e4628f39aa2789"
+ "82543bc0eeb537dc61958019b394fb273f215858a0a01ac4d650b955c67f4c58"
+ }
+ }
+ },
+ {
+ "Example 2: A 1025-bit RSA key pair",
+ "01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fe"
+ "d006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c"
+ "7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b47"
+ "2cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33"
+ "c9",
+ "010001",
+ "027d147e4673057377fd1ea201565772176a7dc38358d376045685a2e787c23c"
+ "15576bc16b9f444402d6bfc5d98a3e88ea13ef67c353eca0c0ddba9255bd7b8b"
+ "b50a644afdfd1dd51695b252d22e7318d1b6687a1c10ff75545f3db0fe602d5f"
+ "2b7f294e3601eab7b9d1cecd767f64692e3e536ca2846cb0c2dd486a39fa75b1",
+ {
+ {
+ "PSS Example 2.1",
+ "daba032066263faedb659848115278a52c44faa3a76f37515ed336321072c40a"
+ "9d9b53bc05014078adf520875146aae70ff060226dcb7b1f1fc27e9360",
+ "57bf160bcb02bb1dc7280cf0458530b7d2832ff7",
+ "014c5ba5338328ccc6e7a90bf1c0ab3fd606ff4796d3c12e4b639ed9136a5fec"
+ "6c16d8884bdd99cfdc521456b0742b736868cf90de099adb8d5ffd1deff39ba4"
+ "007ab746cefdb22d7df0e225f54627dc65466131721b90af445363a8358b9f60"
+ "7642f78fab0ab0f43b7168d64bae70d8827848d8ef1e421c5754ddf42c2589b5"
+ "b3"
+ },{
+ "PSS Example 2.2",
+ "e4f8601a8a6da1be34447c0959c058570c3668cfd51dd5f9ccd6ad4411fe8213"
+ "486d78a6c49f93efc2ca2288cebc2b9b60bd04b1e220d86e3d4848d709d032d1"
+ "e8c6a070c6af9a499fcf95354b14ba6127c739de1bb0fd16431e46938aec0cf8"
+ "ad9eb72e832a7035de9b7807bdc0ed8b68eb0f5ac2216be40ce920c0db0eddd3"
+ "860ed788efaccaca502d8f2bd6d1a7c1f41ff46f1681c8f1f818e9c4f6d91a0c"
+ "7803ccc63d76a6544d843e084e363b8acc55aa531733edb5dee5b5196e9f03e8"
+ "b731b3776428d9e457fe3fbcb3db7274442d785890e9cb0854b6444dace791d7"
+ "273de1889719338a77fe",
+ "7f6dd359e604e60870e898e47b19bf2e5a7b2a90",
+ "010991656cca182b7f29d2dbc007e7ae0fec158eb6759cb9c45c5ff87c7635dd"
+ "46d150882f4de1e9ae65e7f7d9018f6836954a47c0a81a8a6b6f83f2944d6081"
+ "b1aa7c759b254b2c34b691da67cc0226e20b2f18b42212761dcd4b908a62b371"
+ "b5918c5742af4b537e296917674fb914194761621cc19a41f6fb953fbcbb649d"
+ "ea"
+ },{
+ "PSS Example 2.3",
+ "52a1d96c8ac39e41e455809801b927a5b445c10d902a0dcd3850d22a66d2bb07"
+ "03e67d5867114595aabf5a7aeb5a8f87034bbb30e13cfd4817a9be7623002360"
+ "6d0286a3faf8a4d22b728ec518079f9e64526e3a0cc7941aa338c437997c680c"
+ "cac67c66bfa1",
+ "fca862068bce2246724b708a0519da17e648688c",
+ "007f0030018f53cdc71f23d03659fde54d4241f758a750b42f185f87578520c3"
+ "0742afd84359b6e6e8d3ed959dc6fe486bedc8e2cf001f63a7abe16256a1b84d"
+ "f0d249fc05d3194ce5f0912742dbbf80dd174f6c51f6bad7f16cf3364eba095a"
+ "06267dc3793803ac7526aebe0a475d38b8c2247ab51c4898df7047dc6adf52c6"
+ "c4"
+ },{
+ "PSS Example 2.4",
+ "a7182c83ac18be6570a106aa9d5c4e3dbbd4afaeb0c60c4a23e1969d79ff",
+ "8070ef2de945c02387684ba0d33096732235d440",
+ "009cd2f4edbe23e12346ae8c76dd9ad3230a62076141f16c152ba18513a48ef6"
+ "f010e0e37fd3df10a1ec629a0cb5a3b5d2893007298c30936a95903b6ba85555"
+ "d9ec3673a06108fd62a2fda56d1ce2e85c4db6b24a81ca3b496c36d4fd06eb7c"
+ "9166d8e94877c42bea622b3bfe9251fdc21d8d5371badad78a488214796335b4"
+ "0b"
+ },{
+ "PSS Example 2.5",
+ "86a83d4a72ee932a4f5630af6579a386b78fe88999e0abd2d49034a4bfc854dd"
+ "94f1094e2e8cd7a179d19588e4aefc1b1bd25e95e3dd461f",
+ "17639a4e88d722c4fca24d079a8b29c32433b0c9",
+ "00ec430824931ebd3baa43034dae98ba646b8c36013d1671c3cf1cf8260c374b"
+ "19f8e1cc8d965012405e7e9bf7378612dfcc85fce12cda11f950bd0ba8876740"
+ "436c1d2595a64a1b32efcfb74a21c873b3cc33aaf4e3dc3953de67f0674c0453"
+ "b4fd9f604406d441b816098cb106fe3472bc251f815f59db2e4378a3addc181e"
+ "cf"
+ },{
+ "PSS Example 2.6",
+
+ "049f9154d871ac4a7c7ab45325ba7545a1ed08f70525b2667cf1",
+ "37810def1055ed922b063df798de5d0aabf886ee",
+ "00475b1648f814a8dc0abdc37b5527f543b666bb6e39d30e5b49d3b876dccc58"
+ "eac14e32a2d55c2616014456ad2f246fc8e3d560da3ddf379a1c0bd200f10221"
+ "df078c219a151bc8d4ec9d2fc2564467811014ef15d8ea01c2ebbff8c2c8efab"
+ "38096e55fcbe3285c7aa558851254faffa92c1c72b78758663ef4582843139d7"
+ "a6"
+ }
+ }
+ },
+ {
+ "Example 3: A 1026-bit RSA key pair",
+ "02f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db67"
+ "4e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d9"
+ "8170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c"
+ "831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a4"
+ "43",
+ "010001",
+ "651451733b56de5ac0a689a4aeb6e6894a69014e076c88dd7a667eab3232bbcc"
+ "d2fc44ba2fa9c31db46f21edd1fdb23c5c128a5da5bab91e7f952b67759c7cff"
+ "705415ac9fa0907c7ca6178f668fb948d869da4cc3b7356f4008dfd5449d32ee"
+ "02d9a477eb69fc29266e5d9070512375a50fbbcc27e238ad98425f6ebbf88991",
+ {
+ {
+ "PSS Example 3.1",
+ "594b37333bbb2c84524a87c1a01f75fcec0e3256f108e38dca36d70d0057",
+ "f31ad6c8cf89df78ed77feacbcc2f8b0a8e4cfaa",
+ "0088b135fb1794b6b96c4a3e678197f8cac52b64b2fe907d6f27de761124964a"
+ "99a01a882740ecfaed6c01a47464bb05182313c01338a8cd097214cd68ca103b"
+ "d57d3bc9e816213e61d784f182467abf8a01cf253e99a156eaa8e3e1f90e3c6e"
+ "4e3aa2d83ed0345b89fafc9c26077c14b6ac51454fa26e446e3a2f153b2b1679"
+ "7f"
+ },{
+ "PSS Example 3.2",
+ "8b769528884a0d1ffd090cf102993e796dadcfbddd38e44ff6324ca451",
+ "fcf9f0e1f199a3d1d0da681c5b8606fc642939f7",
+ "02a5f0a858a0864a4f65017a7d69454f3f973a2999839b7bbc48bf7864116917"
+ "9556f595fa41f6ff18e286c2783079bc0910ee9cc34f49ba681124f923dfa88f"
+ "426141a368a5f5a930c628c2c3c200e18a7644721a0cbec6dd3f6279bde3e8f2"
+ "be5e2d4ee56f97e7ceaf33054be7042bd91a63bb09f897bd41e81197dee99b11"
+ "af"
+ },{
+ "PSS Example 3.3",
+ "1abdba489c5ada2f995ed16f19d5a94d9e6ec34a8d84f84557d26e5ef9b02b22"
+ "887e3f9a4b690ad1149209c20c61431f0c017c36c2657b35d7b07d3f5ad87085"
+ "07a9c1b831df835a56f831071814ea5d3d8d8f6ade40cba38b42db7a2d3d7a29"
+ "c8f0a79a7838cf58a9757fa2fe4c40df9baa193bfc6f92b123ad57b07ace3e6a"
+ "c068c9f106afd9eeb03b4f37c25dbfbcfb3071f6f9771766d072f3bb070af660"
+ "5532973ae25051",
+ "986e7c43dbb671bd41b9a7f4b6afc80e805f2423",
+ "0244bcd1c8c16955736c803be401272e18cb990811b14f72db964124d5fa7606"
+ "49cbb57afb8755dbb62bf51f466cf23a0a1607576e983d778fceffa92df7548a"
+ "ea8ea4ecad2c29dd9f95bc07fe91ecf8bee255bfe8762fd7690aa9bfa4fa0849"
+ "ef728c2c42c4532364522df2ab7f9f8a03b63f7a499175828668f5ef5a29e380"
+ "2c"
+ },{
+ "PSS Example 3.4",
+ "8fb431f5ee792b6c2ac7db53cc428655aeb32d03f4e889c5c25de683c461b53a"
+ "cf89f9f8d3aabdf6b9f0c2a1de12e15b49edb3919a652fe9491c25a7fce1f722"
+ "c2543608b69dc375ec",
+ "f8312d9c8eea13ec0a4c7b98120c87509087c478",
+ "0196f12a005b98129c8df13c4cb16f8aa887d3c40d96df3a88e7532ef39cd992"
+ "f273abc370bc1be6f097cfebbf0118fd9ef4b927155f3df22b904d90702d1f7b"
+ "a7a52bed8b8942f412cd7bd676c9d18e170391dcd345c06a730964b3f30bcce0"
+ "bb20ba106f9ab0eeb39cf8a6607f75c0347f0af79f16afa081d2c92d1ee6f836"
+ "b8"
+ },{
+ "PSS Example 3.5",
+ "fef4161dfaaf9c5295051dfc1ff3810c8c9ec2e866f7075422c8ec4216a9c4ff"
+ "49427d483cae10c8534a41b2fd15fee06960ec6fb3f7a7e94a2f8a2e3e43dc4a"
+ "40576c3097ac953b1de86f0b4ed36d644f23ae14425529622464ca0cbf0b1741"
+ "347238157fab59e4de5524096d62baec63ac64",
+ "50327efec6292f98019fc67a2a6638563e9b6e2d",
+ "021eca3ab4892264ec22411a752d92221076d4e01c0e6f0dde9afd26ba5acf6d"
+ "739ef987545d16683e5674c9e70f1de649d7e61d48d0caeb4fb4d8b24fba84a6"
+ "e3108fee7d0705973266ac524b4ad280f7ae17dc59d96d3351586b5a3bdb895d"
+ "1e1f7820ac6135d8753480998382ba32b7349559608c38745290a85ef4e9f9bd"
+ "83"
+ },{
+ "PSS Example 3.6",
+ "efd237bb098a443aeeb2bf6c3f8c81b8c01b7fcb3feb",
+ "b0de3fc25b65f5af96b1d5cc3b27d0c6053087b3",
+ "012fafec862f56e9e92f60ab0c77824f4299a0ca734ed26e0644d5d222c7f0bd"
+ "e03964f8e70a5cb65ed44e44d56ae0edf1ff86ca032cc5dd4404dbb76ab85458"
+ "6c44eed8336d08d457ce6c03693b45c0f1efef93624b95b8ec169c616d20e553"
+ "8ebc0b6737a6f82b4bc0570924fc6b35759a3348426279f8b3d7744e2d222426"
+ "ce"
+ }
+ }
+ },
+ {
+ "Example 4: A 1027-bit RSA key pair",
+
+ "054adb7886447efe6f57e0368f06cf52b0a3370760d161cef126b91be7f89c42"
+ "1b62a6ec1da3c311d75ed50e0ab5fff3fd338acc3aa8a4e77ee26369acb81ba9"
+ "00fa83f5300cf9bb6c53ad1dc8a178b815db4235a9a9da0c06de4e615ea1277c"
+ "e559e9c108de58c14a81aa77f5a6f8d1335494498848c8b95940740be7bf7c37"
+ "05",
+ "010001",
+ "fa041f8cd9697ceed38ec8caa275523b4dd72b09a301d3541d72f5d31c05cbce"
+ "2d6983b36183af10690bd46c46131e35789431a556771dd0049b57461bf060c1"
+ "f68472e8a67c25f357e5b6b4738fa541a730346b4a07649a2dfa806a69c975b6"
+ "aba64678acc7f5913e89c622f2d8abb1e3e32554e39df94ba60c002e387d9011",
+ {
+ {
+ "PSS Example 4.1",
+ "9fb03b827c8217d9",
+ "ed7c98c95f30974fbe4fbddcf0f28d6021c0e91d",
+ "0323d5b7bf20ba4539289ae452ae4297080feff4518423ff4811a817837e7d82"
+ "f1836cdfab54514ff0887bddeebf40bf99b047abc3ecfa6a37a3ef00f4a0c4a8"
+ "8aae0904b745c846c4107e8797723e8ac810d9e3d95dfa30ff4966f4d75d1376"
+ "8d20857f2b1406f264cfe75e27d7652f4b5ed3575f28a702f8c4ed9cf9b2d449"
+ "48"
+ },{
+ "PSS Example 4.2",
+ "0ca2ad77797ece86de5bf768750ddb5ed6a3116ad99bbd17edf7f782f0db1cd0"
+ "5b0f677468c5ea420dc116b10e80d110de2b0461ea14a38be68620392e7e893c"
+ "b4ea9393fb886c20ff790642305bf302003892e54df9f667509dc53920df583f"
+ "50a3dd61abb6fab75d600377e383e6aca6710eeea27156e06752c94ce25ae99f"
+ "cbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8fe36"
+ "9d90b3ca612f9f",
+ "22d71d54363a4217aa55113f059b3384e3e57e44",
+ "049d0185845a264d28feb1e69edaec090609e8e46d93abb38371ce51f4aa65a5"
+ "99bdaaa81d24fba66a08a116cb644f3f1e653d95c89db8bbd5daac2709c89840"
+ "00178410a7c6aa8667ddc38c741f710ec8665aa9052be929d4e3b16782c16621"
+ "14c5414bb0353455c392fc28f3db59054b5f365c49e1d156f876ee10cb4fd705"
+ "98"
+ },{
+ "PSS Example 4.3",
+ "288062afc08fcdb7c5f8650b29837300461dd5676c17a20a3c8fb5148949e3f7"
+ "3d66b3ae82c7240e27c5b3ec4328ee7d6ddf6a6a0c9b5b15bcda196a9d0c76b1"
+ "19d534d85abd123962d583b76ce9d180bce1ca",
+ "4af870fbc6516012ca916c70ba862ac7e8243617",
+ "03fbc410a2ced59500fb99f9e2af2781ada74e13145624602782e2994813eefc"
+ "a0519ecd253b855fb626a90d771eae028b0c47a199cbd9f8e3269734af416359"
+ "9090713a3fa910fa0960652721432b971036a7181a2bc0cab43b0b598bc62174"
+ "61d7db305ff7e954c5b5bb231c39e791af6bcfa76b147b081321f72641482a2a"
+ "ad"
+ },{
+ "PSS Example 4.4",
+ "6f4f9ab9501199cef55c6cf408fe7b36c557c49d420a4763d2463c8ad44b3cfc"
+ "5be2742c0e7d9b0f6608f08c7f47b693ee",
+ "40d2e180fae1eac439c190b56c2c0e14ddf9a226",
+ "0486644bc66bf75d28335a6179b10851f43f09bded9fac1af33252bb9953ba42"
+ "98cd6466b27539a70adaa3f89b3db3c74ab635d122f4ee7ce557a61e59b82ffb"
+ "786630e5f9db53c77d9a0c12fab5958d4c2ce7daa807cd89ba2cc7fcd02ff470"
+ "ca67b229fcce814c852c73cc93bea35be68459ce478e9d4655d121c8472f371d"
+ "4f"
+ },{
+ "PSS Example 4.5",
+ "e17d20385d501955823c3f666254c1d3dd36ad5168b8f18d286fdcf67a7dad94"
+ "097085fab7ed86fe2142a28771717997ef1a7a08884efc39356d76077aaf8245"
+ "9a7fad45848875f2819b098937fe923bcc9dc442d72d754d812025090c9bc03d"
+ "b3080c138dd63b355d0b4b85d6688ac19f4de15084a0ba4e373b93ef4a555096"
+ "691915dc23c00e954cdeb20a47cd55d16c3d8681d46ed7f2ed5ea42795be17ba"
+ "ed25f0f4d113b3636addd585f16a8b5aec0c8fa9c5f03cbf3b9b73",
+ "2497dc2b4615dfae5a663d49ffd56bf7efc11304",
+ "022a80045353904cb30cbb542d7d4990421a6eec16a8029a8422adfd22d6aff8"
+ "c4cc0294af110a0c067ec86a7d364134459bb1ae8ff836d5a8a2579840996b32"
+ "0b19f13a13fad378d931a65625dae2739f0c53670b35d9d3cbac08e733e4ec2b"
+ "83af4b9196d63e7c4ff1ddeae2a122791a125bfea8deb0de8ccf1f4ffaf6e6fb"
+ "0a"
+ },{
+ "PSS Example 4.6",
+ "afbc19d479249018fdf4e09f618726440495de11ddeee38872d775fcea74a238"
+ "96b5343c9c38d46af0dba224d047580cc60a65e9391cf9b59b36a860598d4e82"
+ "16722f993b91cfae87bc255af89a6a199bca4a391eadbc3a24903c0bd667368f"
+ "6be78e3feabfb4ffd463122763740ffbbefeab9a25564bc5d1c24c93e422f750"
+ "73e2ad72bf45b10df00b52a147128e73fee33fa3f0577d77f80fbc2df1bed313"
+ "290c12777f50",
+ "a334db6faebf11081a04f87c2d621cdec7930b9b",
+ "00938dcb6d583046065f69c78da7a1f1757066a7fa75125a9d2929f0b79a60b6"
+ "27b082f11f5b196f28eb9daa6f21c05e5140f6aef1737d2023075c05ecf04a02"
+ "8c686a2ab3e7d5a0664f295ce12995e890908b6ad21f0839eb65b70393a7b5af"
+ "d9871de0caa0cedec5b819626756209d13ab1e7bb9546a26ff37e9a51af9fd56"
+ "2e"
+ }
+ }
+ },
+ {
+ "Example 5: A 1028-bit RSA key pair",
+ "0d10f661f29940f5ed39aa260966deb47843679d2b6fb25b3de370f3ac7c1991"
+ "6391fd25fb527ebfa6a4b4df45a1759d996c4bb4ebd18828c44fc52d01918717"
+ "40525f47a4b0cc8da325ed8aa676b0d0f626e0a77f07692170acac8082f42faa"
+ "7dc7cd123e730e31a87985204cabcbe6670d43a2dd2b2ddef5e05392fc213bc5"
+ "07",
+ "010001",
+ "03ce08b104fff396a979bd3e4e46925b6319ddb63acbcfd819f17d16b8077b3a"
+ "87101ff34b77fe48b8b205a96e9151ba8ecea64d0cce7b23c3e6a6b83058bc49"
+ "dae816ae736db5a4708e2ad435232b567f9096ce59ff28061e79ab1c02d717e6"
+ "b23cea6db8eb5192fa7c1eab227dba74621c45601896eef13792c8440beb15aa"
+ "c1",
+ {
+ {
+ "PSS Example 5.1",
+ "30c7d557458b436decfdc14d06cb7b96b06718c48d7de57482a868ae7f065870"
+ "a6216506d11b779323dfdf046cf5775129134b4d5689e4d9c0ce1e12d7d4b06c"
+ "b5fc5820decfa41baf59bf257b32f025b7679b445b9499c92555145885992f1b"
+ "76f84891ee4d3be0f5150fd5901e3a4c8ed43fd36b61d022e65ad5008dbf3329"
+ "3c22bfbfd07321f0f1d5fa9fdf0014c2fcb0358aad0e354b0d29",
+ "081b233b43567750bd6e78f396a88b9f6a445151",
+ "0ba373f76e0921b70a8fbfe622f0bf77b28a3db98e361051c3d7cb92ad045291"
+ "5a4de9c01722f6823eeb6adf7e0ca8290f5de3e549890ac2a3c5950ab217ba58"
+ "590894952de96f8df111b2575215da6c161590c745be612476ee578ed384ab33"
+ "e3ece97481a252f5c79a98b5532ae00cdd62f2ecc0cd1baefe80d80b962193ec"
+ "1d"
+ },{
+ "PSS Example 5.2",
+ "e7b32e1556ea1b2795046ac69739d22ac8966bf11c116f614b166740e96b9065"
+ "3e5750945fcf772186c03790a07fda323e1a61916b06ee2157db3dff80d67d5e"
+ "39a53ae268c8f09ed99a732005b0bc6a04af4e08d57a00e7201b3060efaadb73"
+ "113bfc087fd837093aa25235b8c149f56215f031c24ad5bde7f29960df7d5240"
+ "70f7449c6f785084be1a0f733047f336f9154738674547db02a9f44dfc6e6030"
+ "1081e1ce99847f3b5b601ff06b4d5776a9740b9aa0d34058fd3b906e4f7859df"
+ "b07d7173e5e6f6350adac21f27b2307469",
+ "bd0ce19549d0700120cbe51077dbbbb00a8d8b09",
+ "08180de825e4b8b014a32da8ba761555921204f2f90d5f24b712908ff84f3e22"
+ "0ad17997c0dd6e706630ba3e84add4d5e7ab004e58074b549709565d43ad9e97"
+ "b5a7a1a29e85b9f90f4aafcdf58321de8c5974ef9abf2d526f33c0f2f82e95d1"
+ "58ea6b81f1736db8d1af3d6ac6a83b32d18bae0ff1b2fe27de4c76ed8c7980a3"
+ "4e"
+ },{
+ "PSS Example 5.3",
+ "8d8396e36507fe1ef6a19017548e0c716674c2fec233adb2f775665ec41f2bd0"
+ "ba396b061a9daa7e866f7c23fd3531954300a342f924535ea1498c48f6c87993"
+ "2865fc02000c528723b7ad0335745b51209a0afed932af8f0887c219004d2abd"
+ "894ea92559ee3198af3a734fe9b9638c263a728ad95a5ae8ce3eb15839f3aa78"
+ "52bb390706e7760e43a71291a2e3f827237deda851874c517665f545f27238df"
+ "86557f375d09ccd8bd15d8ccf61f5d78ca5c7f5cde782e6bf5d0057056d4bad9"
+ "8b3d2f9575e824ab7a33ff57b0ac100ab0d6ead7aa0b50f6e4d3e5ec0b966b",
+ "815779a91b3a8bd049bf2aeb920142772222c9ca",
+ "05e0fdbdf6f756ef733185ccfa8ced2eb6d029d9d56e35561b5db8e70257ee6f"
+ "d019d2f0bbf669fe9b9821e78df6d41e31608d58280f318ee34f559941c8df13"
+ "287574bac000b7e58dc4f414ba49fb127f9d0f8936638c76e85356c994f79750"
+ "f7fa3cf4fd482df75e3fb9978cd061f7abb17572e6e63e0bde12cbdcf18c68b9"
+ "79"
+ },{
+ "PSS Example 5.4",
+ "328c659e0a6437433cceb73c14",
+ "9aec4a7480d5bbc42920d7ca235db674989c9aac",
+ "0bc989853bc2ea86873271ce183a923ab65e8a53100e6df5d87a24c4194eb797"
+ "813ee2a187c097dd872d591da60c568605dd7e742d5af4e33b11678ccb639032"
+ "04a3d080b0902c89aba8868f009c0f1c0cb85810bbdd29121abb8471ff2d39e4"
+ "9fd92d56c655c8e037ad18fafbdc92c95863f7f61ea9efa28fea401369d19dae"
+ "a1"
+ },{
+ "PSS Example 5.5",
+ "f37b962379a47d415a376eec8973150bcb34edd5ab654041b61430560c214458"
+ "2ba133c867d852d6b8e23321901302ecb45b09ec88b1527178fa043263f3067d"
+ "9ffe973032a99f4cb08ad2c7e0a2456cdd57a7df56fe6053527a5aeb67d7e552"
+ "063c1ca97b1beffa7b39e997caf27878ea0f62cbebc8c21df4c889a202851e94"
+ "9088490c249b6e9acf1d8063f5be2343989bf95c4da01a2be78b4ab6b378015b"
+ "c37957f76948b5e58e440c28453d40d7cfd57e7d690600474ab5e75973b1ea0c"
+ "5f1e45d14190afe2f4eb6d3bdf71f1d2f8bb156a1c295d04aaeb9d689dce79ed"
+ "62bc443e",
+ "e20c1e9878512c39970f58375e1549a68b64f31d",
+ "0aefa943b698b9609edf898ad22744ac28dc239497cea369cbbd84f65c95c0ad"
+ "776b594740164b59a739c6ff7c2f07c7c077a86d95238fe51e1fcf33574a4ae0"
+ "684b42a3f6bf677d91820ca89874467b2c23add77969c80717430d0efc1d3695"
+ "892ce855cb7f7011630f4df26def8ddf36fc23905f57fa6243a485c770d5681f"
+ "cd"
+ },{
+ "PSS Example 5.6",
+ "c6103c330c1ef718c141e47b8fa859be4d5b96259e7d142070ecd485839dba5a"
+ "8369c17c1114035e532d195c74f44a0476a2d3e8a4da210016caced0e367cb86"
+ "7710a4b5aa2df2b8e5daf5fdc647807d4d5ebb6c56b9763ccdae4dea3308eb0a"
+ "c2a89501cb209d2639fa5bf87ce790747d3cb2d295e84564f2f637824f0c1302"
+ "8129b0aa4a422d162282",
+ "23291e4a3307e8bbb776623ab34e4a5f4cc8a8db",
+ "02802dccfa8dfaf5279bf0b4a29ba1b157611faeaaf419b8919d15941900c133"
+ "9e7e92e6fae562c53e6cc8e84104b110bce03ad18525e3c49a0eadad5d3f28f2"
+ "44a8ed89edbafbb686277cfa8ae909714d6b28f4bf8e293aa04c41efe7c0a812"
+ "66d5c061e2575be032aa464674ff71626219bd74cc45f0e7ed4e3ff96eee758e"
+ "8f"
+ }
+ }
+ },
+ {
+ "Example 6: A 1029-bit RSA key pair",
+ "164ca31cff609f3a0e7101b039f2e4fe6dd37519ab98598d179e174996598071"
+ "f47d3a04559158d7be373cf1aa53f0aa6ef09039e5678c2a4c63900514c8c4f8"
+ "aaed5de12a5f10b09c311af8c0ffb5b7a297f2efc63b8d6b0510931f0b98e48b"
+ "f5fc6ec4e7b8db1ffaeb08c38e02adb8f03a48229c99e969431f61cb8c4dc698"
+ "d1",
+ "010001",
+ "03b664ee3b7566723fc6eaf28abb430a3980f1126c81de8ad709eab39ac9dcd0"
+ "b1550b3729d87068e952009df544534c1f50829a78f4591eb8fd57140426a6bb"
+ "0405b6a6f51a57d9267b7bbc653391a699a2a90dac8ae226bcc60fa8cd934c73"
+ "c7b03b1f6b818158631838a8612e6e6ea92be24f8324faf5b1fd8587225267ba"
+ "6f",
+ {
+ {
+ "PSS Example 6.1",
+ "0a20b774addc2fa51245ed7cb9da609e50cac6636a52543f97458eed7340f8d5"
+ "3ffc64918f949078ee03ef60d42b5fec246050bd5505cd8cb597bad3c4e713b0"
+ "ef30644e76adabb0de01a1561efb255158c74fc801e6e919e581b46f0f0ddd08"
+ "e4f34c7810b5ed8318f91d7c8c",
+ "5b4ea2ef629cc22f3b538e016904b47b1e40bfd5",
+ "04c0cfacec04e5badbece159a5a1103f69b3f32ba593cb4cc4b1b7ab455916a9"
+ "6a27cd2678ea0f46ba37f7fc9c86325f29733b389f1d97f43e7201c0f348fc45"
+ "fe42892335362eee018b5b161f2f9393031225c713012a576bc88e2305248986"
+ "8d9010cbf033ecc568e8bc152bdc59d560e41291915d28565208e22aeec9ef85"
+ "d1"
+ },{
+ "PSS Example 6.2",
+ "2aaff6631f621ce615760a9ebce94bb333077ad86488c861d4b76d29c1f48746"
+ "c611ae1e03ced4445d7cfa1fe5f62e1b3f08452bde3b6ef81973bafbb57f97bc"
+ "eef873985395b8260589aa88cb7db50ab469262e551bdcd9a56f275a0ac4fe48"
+ "4700c35f3dbf2b469ede864741b86fa59172a360ba95a02e139be50ddfb7cf0b"
+ "42faeabbfbbaa86a4497699c4f2dfd5b08406af7e14144427c253ec0efa20eaf"
+ "9a8be8cd49ce1f1bc4e93e619cf2aa8ed4fb39bc8590d0f7b96488f7317ac9ab"
+ "f7bee4e3a0e715",
+ "83146a9e782722c28b014f98b4267bda2ac9504f",
+ "0a2314250cf52b6e4e908de5b35646bcaa24361da8160fb0f9257590ab3ace42"
+ "b0dc3e77ad2db7c203a20bd952fbb56b1567046ecfaa933d7b1000c3de9ff05b"
+ "7d989ba46fd43bc4c2d0a3986b7ffa13471d37eb5b47d64707bd290cfd6a9f39"
+ "3ad08ec1e3bd71bb5792615035cdaf2d8929aed3be098379377e777ce79aaa47"
+ "73"
+ },{
+ "PSS Example 6.3",
+ "0f6195d04a6e6fc7e2c9600dbf840c39ea8d4d624fd53507016b0e26858a5e0a"
+ "ecd7ada543ae5c0ab3a62599cba0a54e6bf446e262f989978f9ddf5e9a41",
+ "a87b8aed07d7b8e2daf14ddca4ac68c4d0aabff8",
+ "086df6b500098c120f24ff8423f727d9c61a5c9007d3b6a31ce7cf8f3cbec1a2"
+ "6bb20e2bd4a046793299e03e37a21b40194fb045f90b18bf20a47992ccd799cf"
+ "9c059c299c0526854954aade8a6ad9d97ec91a1145383f42468b231f4d72f237"
+ "06d9853c3fa43ce8ace8bfe7484987a1ec6a16c8daf81f7c8bf42774707a9df4"
+ "56"
+ },{
+ "PSS Example 6.4",
+ "337d25fe9810ebca0de4d4658d3ceb8e0fe4c066aba3bcc48b105d3bf7e0257d"
+ "44fecea6596f4d0c59a08402833678f70620f9138dfeb7ded905e4a6d5f05c47"
+ "3d55936652e2a5df43c0cfda7bacaf3087f4524b06cf42157d01539739f7fdde"
+ "c9d58125df31a32eab06c19b71f1d5bf",
+ "a37932f8a7494a942d6f767438e724d6d0c0ef18",
+ "0b5b11ad549863ffa9c51a14a1106c2a72cc8b646e5c7262509786105a984776"
+ "534ca9b54c1cc64bf2d5a44fd7e8a69db699d5ea52087a4748fd2abc1afed1e5"
+ "d6f7c89025530bdaa2213d7e030fa55df6f34bcf1ce46d2edf4e3ae4f3b01891"
+ "a068c9e3a44bbc43133edad6ecb9f35400c4252a5762d65744b99cb9f4c55932"
+ "9f"
+ },{
+ "PSS Example 6.5",
+ "84ec502b072e8287789d8f9235829ea3b187afd4d4c785611bda5f9eb3cb9671"
+ "7efa7007227f1c08cbcb972e667235e0fb7d431a6570326d2ecce35adb373dc7"
+ "53b3be5f829b89175493193fab16badb41371b3aac0ae670076f24bef420c135"
+ "add7cee8d35fbc944d79fafb9e307a13b0f556cb654a06f973ed22672330197e"
+ "f5a748bf826a5db2383a25364b686b9372bb2339aeb1ac9e9889327d016f1670"
+ "776db06201adbdcaf8a5e3b74e108b73",
+ "7b790c1d62f7b84e94df6af28917cf571018110e",
+ "02d71fa9b53e4654fefb7f08385cf6b0ae3a817942ebf66c35ac67f0b069952a"
+ "3ce9c7e1f1b02e480a9500836de5d64cdb7ecde04542f7a79988787e24c2ba05"
+ "f5fd482c023ed5c30e04839dc44bed2a3a3a4fee01113c891a47d32eb8025c28"
+ "cb050b5cdb576c70fe76ef523405c08417faf350b037a43c379339fcb18d3a35"
+ "6b"
+ },{
+ "PSS Example 6.6",
+ "9906d89f97a9fdedd3ccd824db687326f30f00aa25a7fca2afcb3b0f86cd41e7"
+ "3f0e8ff7d2d83f59e28ed31a5a0d551523374de22e4c7e8ff568b386ee3dc411"
+ "63f10bf67bb006261c9082f9af90bf1d9049a6b9fae71c7f84fbe6e55f02789d"
+ "e774f230f115026a4b4e96c55b04a95da3aacbb2cece8f81764a1f1c99515411"
+ "087cf7d34aeded0932c183",
+ "fbbe059025b69b89fb14ae2289e7aaafe60c0fcd",
+ "0a40a16e2fe2b38d1df90546167cf9469c9e3c3681a3442b4b2c2f581deb385c"
+ "e99fc6188bb02a841d56e76d301891e24560550fcc2a26b55f4ccb26d837d350"
+ "a154bcaca8392d98fa67959e9727b78cad03269f56968fc56b68bd679926d83c"
+ "c9cb215550645ccda31c760ff35888943d2d8a1d351e81e5d07b86182e751081"
+ "ef"
+ }
+ }
+ },
+ {
+ "Example 7: A 1030-bit RSA key pair",
+ "37c9da4a66c8c408b8da27d0c9d79f8ccb1eafc1d2fe48746d940b7c4ef5dee1"
+ "8ad12647cefaa0c4b3188b221c515386759b93f02024b25ab9242f8357d8f3fd"
+ "49640ee5e643eaf6c64deefa7089727c8ff03993333915c6ef21bf5975b6e50d"
+ "118b51008ec33e9f01a0a545a10a836a43ddbca9d8b5c5d3548022d7064ea29a"
+ "b3",
+ "010001",
+ "3bed999052d957bc06d651eef6e3a98094b1621bd38b5449bd6c4aea3de7e084"
+ "679a4484ded25be0f0826cf3377825414b14d4d61db14de626fbb80e5f4faec9"
+ "56f9a0a2d24f99576380f084eb62e46a57d554278b535626193ce02060575eb6"
+ "6c5798d36f6c5d40fb00d809b42a73102c1c74ee95bd71420fffef6318b52c29",
+ {
+ {
+ "PSS Example 7.1",
+ "9ead0e01945640674eb41cad435e2374eaefa8ad7197d97913c44957d8d83f40"
+ "d76ee60e39bf9c0f9eaf3021421a074d1ade962c6e9d3dc3bb174fe4dfe652b0"
+ "9115495b8fd2794174020a0602b5ca51848cfc96ce5eb57fc0a2adc1dda36a7c"
+ "c452641a14911b37e45bfa11daa5c7ecdb74f6d0100d1d3e39e752800e203397"
+ "de0233077b9a88855537fae927f924380d780f98e18dcff39c5ea741b17d6fdd"
+ "1885bc9d581482d771ceb562d78a8bf88f0c75b11363e5e36cd479ceb0545f9d"
+ "a84203e0e6e508375cc9e844b88b7ac7a0a201ea0f1bee9a2c577920ca02c01b"
+ "9d8320e974a56f4efb5763b96255abbf8037bf1802cf018f56379493e569a9",
+ "b7867a59958cb54328f8775e6546ec06d27eaa50",
+ "187f390723c8902591f0154bae6d4ecbffe067f0e8b795476ea4f4d51ccc8105"
+ "20bb3ca9bca7d0b1f2ea8a17d873fa27570acd642e3808561cb9e975ccfd80b2"
+ "3dc5771cdb3306a5f23159dacbd3aa2db93d46d766e09ed15d900ad897a8d274"
+ "dc26b47e994a27e97e2268a766533ae4b5e42a2fcaf755c1c4794b294c605558"
+ "23"
+ },{
+ "PSS Example 7.2",
+ "8d80d2d08dbd19c154df3f14673a14bd03735231f24e86bf153d0e69e74cbff7"
+ "b1836e664de83f680124370fc0f96c9b65c07a366b644c4ab3",
+ "0c09582266df086310821ba7e18df64dfee6de09",
+ "10fd89768a60a67788abb5856a787c8561f3edcf9a83e898f7dc87ab8cce7942"
+ "9b43e56906941a886194f137e591fe7c339555361fbbe1f24feb2d4bcdb80601"
+ "f3096bc9132deea60ae13082f44f9ad41cd628936a4d51176e42fc59cb76db81"
+ "5ce5ab4db99a104aafea68f5d330329ebf258d4ede16064bd1d00393d5e1570e"
+ "b8"
+ },{
+ "PSS Example 7.3",
+ "808405cdfc1a58b9bb0397c720722a81fffb76278f335917ef9c473814b3e016"
+ "ba2973cd2765f8f3f82d6cc38aa7f8551827fe8d1e3884b7e61c94683b8f82f1"
+ "843bdae2257eeec9812ad4c2cf283c34e0b0ae0fe3cb990cf88f2ef9",
+ "28039dcfe106d3b8296611258c4a56651c9e92dd",
+ "2b31fde99859b977aa09586d8e274662b25a2a640640b457f594051cb1e7f7a9"
+ "11865455242926cf88fe80dfa3a75ba9689844a11e634a82b075afbd69c12a0d"
+ "f9d25f84ad4945df3dc8fe90c3cefdf26e95f0534304b5bdba20d3e5640a2ebf"
+ "b898aac35ae40f26fce5563c2f9f24f3042af76f3c7072d687bbfb959a88460a"
+ "f1"
+ },{
+ "PSS Example 7.4",
+ "f337b9bad937de22a1a052dff11134a8ce26976202981939b91e0715ae5e6096"
+ "49da1adfcef3f4cca59b238360e7d1e496c7bf4b204b5acff9bbd6166a1d87a3"
+ "6ef2247373751039f8a800b8399807b3a85f44893497c0d05fb7017b82228152"
+ "de6f25e6116dcc7503c786c875c28f3aa607e94ab0f19863ab1b5073770b0cd5"
+ "f533acde30c6fb953cf3da680264e30fc11bff9a19bffab4779b6223c3fb3fe0"
+ "f71abade4eb7c09c41e24c22d23fa148e6a173feb63984d1bc6ee3a02d915b75"
+ "2ceaf92a3015eceb38ca586c6801b37c34cefb2cff25ea23c08662dcab26a7a9"
+ "3a285d05d3044c",
+ "a77821ebbbef24628e4e12e1d0ea96de398f7b0f",
+ "32c7ca38ff26949a15000c4ba04b2b13b35a3810e568184d7ecabaa166b7ffab"
+ "ddf2b6cf4ba07124923790f2e5b1a5be040aea36fe132ec130e1f10567982d17"
+ "ac3e89b8d26c3094034e762d2e031264f01170beecb3d1439e05846f25458367"
+ "a7d9c02060444672671e64e877864559ca19b2074d588a281b5804d23772fbbe"
+ "19"
+ },{
+ "PSS Example 7.5",
+ "45013cebafd960b255476a8e2598b9aa32efbe6dc1f34f4a498d8cf5a2b4548d"
+ "08c55d5f95f7bcc9619163056f2d58b52fa032",
+ "9d5ad8eb452134b65dc3a98b6a73b5f741609cd6",
+ "07eb651d75f1b52bc263b2e198336e99fbebc4f332049a922a10815607ee2d98"
+ "9db3a4495b7dccd38f58a211fb7e193171a3d891132437ebca44f318b280509e"
+ "52b5fa98fcce8205d9697c8ee4b7ff59d4c59c79038a1970bd2a0d451ecdc5ef"
+ "11d9979c9d35f8c70a6163717607890d586a7c6dc01c79f86a8f28e85235f8c2"
+ "f1"
+ },{
+ "PSS Example 7.6",
+ "2358097086c899323e75d9c90d0c09f12d9d54edfbdf70a9c2eb5a04d8f36b9b"
+ "2bdf2aabe0a5bda1968937f9d6ebd3b6b257efb3136d4131f9acb59b85e2602c"
+ "2a3fcdc835494a1f4e5ec18b226c80232b36a75a45fdf09a7ea9e98efbde1450"
+ "d1194bf12e15a4c5f9eb5c0bce5269e0c3b28cfab655d81a61a20b4be2f54459"
+ "bb25a0db94c52218be109a7426de83014424789aaa90e5056e632a698115e282"
+ "c1a56410f26c2072f193481a9dcd880572005e64f4082ecf",
+ "3f2efc595880a7d47fcf3cba04983ea54c4b73fb",
+ "18da3cdcfe79bfb77fd9c32f377ad399146f0a8e810620233271a6e3ed324890"
+ "3f5cdc92dc79b55d3e11615aa056a795853792a3998c349ca5c457e8ca7d29d7"
+ "96aa24f83491709befcfb1510ea513c92829a3f00b104f655634f320752e130e"
+ "c0ccf6754ff893db302932bb025eb60e87822598fc619e0e981737a9a4c4152d"
+ "33"
+ }
+ }
+ },
+ {
+ "Example 8: A 1031-bit RSA key pair",
+ "495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6f"
+ "bbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2"
+ "d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaa"
+ "dced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada073"
+ "3f",
+ "010001",
+ "6c66ffe98980c38fcdeab5159898836165f4b4b817c4f6a8d486ee4ea9130fe9"
+ "b9092bd136d184f95f504a607eac565846d2fdd6597a8967c7396ef95a6eeebb"
+ "4578a643966dca4d8ee3de842de63279c618159c1ab54a89437b6a6120e4930a"
+ "fb52a4ba6ced8a4947ac64b30a3497cbe701c2d6266d517219ad0ec6d347dbe9",
+ {
+ {
+ "PSS Example 8.1",
+ "81332f4be62948415ea1d899792eeacf6c6e1db1da8be13b5cea41db2fed4670"
+ "92e1ff398914c714259775f595f8547f735692a575e6923af78f22c6997ddb90"
+ "fb6f72d7bb0dd5744a31decd3dc3685849836ed34aec596304ad11843c4f8848"
+ "9f209735f5fb7fdaf7cec8addc5818168f880acbf490d51005b7a8e84e43e542"
+ "87977571dd99eea4b161eb2df1f5108f12a4142a83322edb05a75487a3435c9a"
+ "78ce53ed93bc550857d7a9fb",
+ "1d65491d79c864b373009be6f6f2467bac4c78fa",
+ "0262ac254bfa77f3c1aca22c5179f8f040422b3c5bafd40a8f21cf0fa5a667cc"
+ "d5993d42dbafb409c520e25fce2b1ee1e716577f1efa17f3da28052f40f0419b"
+ "23106d7845aaf01125b698e7a4dfe92d3967bb00c4d0d35ba3552ab9a8b3eef0"
+ "7c7fecdbc5424ac4db1e20cb37d0b2744769940ea907e17fbbca673b20522380"
+ "c5"
+ },{
+ "PSS Example 8.2",
+ "e2f96eaf0e05e7ba326ecca0ba7fd2f7c02356f3cede9d0faabf4fcc8e60a973"
+ "e5595fd9ea08",
+ "435c098aa9909eb2377f1248b091b68987ff1838",
+ "2707b9ad5115c58c94e932e8ec0a280f56339e44a1b58d4ddcff2f312e5f34dc"
+ "fe39e89c6a94dcee86dbbdae5b79ba4e0819a9e7bfd9d982e7ee6c86ee68396e"
+ "8b3a14c9c8f34b178eb741f9d3f121109bf5c8172fada2e768f9ea1433032c00"
+ "4a8aa07eb990000a48dc94c8bac8aabe2b09b1aa46c0a2aa0e12f63fbba775ba"
+ "7e"
+ },{
+ "PSS Example 8.3",
+ "e35c6ed98f64a6d5a648fcab8adb16331db32e5d15c74a40edf94c3dc4a4de79"
+ "2d190889f20f1e24ed12054a6b28798fcb42d1c548769b734c96373142092aed"
+ "277603f4738df4dc1446586d0ec64da4fb60536db2ae17fc7e3c04bbfbbbd907"
+ "bf117c08636fa16f95f51a6216934d3e34f85030f17bbbc5ba69144058aff081"
+ "e0b19cf03c17195c5e888ba58f6fe0a02e5c3bda9719a7",
+ "c6ebbe76df0c4aea32c474175b2f136862d04529",
+ "2ad20509d78cf26d1b6c406146086e4b0c91a91c2bd164c87b966b8faa42aa0c"
+ "a446022323ba4b1a1b89706d7f4c3be57d7b69702d168ab5955ee290356b8c4a"
+ "29ed467d547ec23cbadf286ccb5863c6679da467fc9324a151c7ec55aac6db40"
+ "84f82726825cfe1aa421bc64049fb42f23148f9c25b2dc300437c38d428aa75f"
+ "96"
+ },{
+ "PSS Example 8.4",
+ "dbc5f750a7a14be2b93e838d18d14a8695e52e8add9c0ac733b8f56d2747e529"
+ "a0cca532dd49b902aefed514447f9e81d16195c2853868cb9b30f7d0d495c69d"
+ "01b5c5d50b27045db3866c2324a44a110b1717746de457d1c8c45c3cd2a92970"
+ "c3d59632055d4c98a41d6e99e2a3ddd5f7f9979ab3cd18f37505d25141de2a1b"
+ "ff17b3a7dce9419ecc385cf11d72840f19953fd0509251f6cafde2893d0e75c7"
+ "81ba7a5012ca401a4fa99e04b3c3249f926d5afe82cc87dab22c3c1b105de48e"
+ "34ace9c9124e59597ac7ebf8",
+ "021fdcc6ebb5e19b1cb16e9c67f27681657fe20a",
+ "1e24e6e58628e5175044a9eb6d837d48af1260b0520e87327de7897ee4d5b9f0"
+ "df0be3e09ed4dea8c1454ff3423bb08e1793245a9df8bf6ab3968c8eddc3b532"
+ "8571c77f091cc578576912dfebd164b9de5454fe0be1c1f6385b328360ce67ec"
+ "7a05f6e30eb45c17c48ac70041d2cab67f0a2ae7aafdcc8d245ea3442a6300cc"
+ "c7"
+ },{
+ "PSS Example 8.5",
+ "04dc251be72e88e5723485b6383a637e2fefe07660c519a560b8bc18bdedb86e"
+ "ae2364ea53ba9dca6eb3d2e7d6b806af42b3e87f291b4a8881d5bf572cc9a85e"
+ "19c86acb28f098f9da0383c566d3c0f58cfd8f395dcf602e5cd40e8c7183f714"
+ "996e2297ef",
+ "c558d7167cbb4508ada042971e71b1377eea4269",
+ "33341ba3576a130a50e2a5cf8679224388d5693f5accc235ac95add68e5eb1ee"
+ "c31666d0ca7a1cda6f70a1aa762c05752a51950cdb8af3c5379f18cfe6b5bc55"
+ "a4648226a15e912ef19ad77adeea911d67cfefd69ba43fa4119135ff642117ba"
+ "985a7e0100325e9519f1ca6a9216bda055b5785015291125e90dcd07a2ca9673"
+ "ee"
+ },{
+ "PSS Example 8.6",
+ "0ea37df9a6fea4a8b610373c24cf390c20fa6e2135c400c8a34f5c183a7e8ea4"
+ "c9ae090ed31759f42dc77719cca400ecdcc517acfc7ac6902675b2ef30c50966"
+ "5f3321482fc69a9fb570d15e01c845d0d8e50d2a24cbf1cf0e714975a5db7b18"
+ "d9e9e9cb91b5cb16869060ed18b7b56245503f0caf90352b8de81cb5a1d9c633"
+ "6092f0cd",
+ "76fd4e64fdc98eb927a0403e35a084e76ba9f92a",
+ "1ed1d848fb1edb44129bd9b354795af97a069a7a00d0151048593e0c72c3517f"
+ "f9ff2a41d0cb5a0ac860d736a199704f7cb6a53986a88bbd8abcc0076a2ce847"
+ "880031525d449da2ac78356374c536e343faa7cba42a5aaa6506087791c06a8e"
+ "989335aed19bfab2d5e67e27fb0c2875af896c21b6e8e7309d04e4f6727e6946"
+ "3e"
+ }
+ }
+ },
+ {
+ "Example 9: A 1536-bit RSA key pair",
+ "e6bd692ac96645790403fdd0f5beb8b9bf92ed10007fc365046419dd06c05c5b"
+ "5b2f48ecf989e4ce269109979cbb40b4a0ad24d22483d1ee315ad4ccb1534268"
+ "352691c524f6dd8e6c29d224cf246973aec86c5bf6b1401a850d1b9ad1bb8cbc"
+ "ec47b06f0f8c7f45d3fc8f319299c5433ddbc2b3053b47ded2ecd4a4caefd614"
+ "833dc8bb622f317ed076b8057fe8de3f84480ad5e83e4a61904a4f248fb39702"
+ "7357e1d30e463139815c6fd4fd5ac5b8172a45230ecb6318a04f1455d84e5a8b",
+ "010001",
+ "6a7fd84fb85fad073b34406db74f8d61a6abc12196a961dd79565e9da6e5187b"
+ "ce2d980250f7359575359270d91590bb0e427c71460b55d51410b191bcf309fe"
+ "a131a92c8e702738fa719f1e0041f52e40e91f229f4d96a1e6f172e15596b451"
+ "0a6daec26105f2bebc53316b87bdf21311666070e8dfee69d52c71a976caae79"
+ "c72b68d28580dc686d9f5129d225f82b3d615513a882b3db91416b48ce088882"
+ "13e37eeb9af800d81cab328ce420689903c00c7b5fd31b75503a6d419684d629",
+ {
+ {
+ "PSS Example 9.1",
+ "a88e265855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef437959"
+ "22028bc2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b27"
+ "8872bf51321c4a972f3c95570f3445d4f57980e0f20df54846e6a52c668f1288"
+ "c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55cf979"
+ "f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60ca70"
+ "9e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c2441594"
+ "20637028df0a18079d6208ea8b4711a2c750f5",
+ "c0a425313df8d7564bd2434d311523d5257eed80",
+ "586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef"
+ "589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d1"
+ "3dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802c"
+ "b13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d231627"
+ "9edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f611"
+ "21f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e"
+ },{
+ "PSS Example 9.2",
+ "c8c9c6af04acda414d227ef23e0820c3732c500dc87275e95b0d095413993c26"
+ "58bc1d988581ba879c2d201f14cb88ced153a01969a7bf0a7be79c84c1486bc1"
+ "2b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb96d90a82ebab6"
+ "9f86350e1822e8bd536a2e",
+ "b307c43b4850a8dac2f15f32e37839ef8c5c0e91",
+ "80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66d"
+ "d7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f"
+ "7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546"
+ "bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83ea"
+ "e46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee"
+ "361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958"
+ },{
+ "PSS Example 9.3",
+ "0afad42ccd4fc60654a55002d228f52a4a5fe03b8bbb08ca82daca558b44dbe1"
+ "266e50c0e745a36d9d2904e3408abcd1fd569994063f4a75cc72f2fee2a0cd89"
+ "3a43af1c5b8b487df0a71610024e4f6ddf9f28ad0813c1aab91bcb3c9064d5ff"
+ "742deffea657094139369e5ea6f4a96319a5cc8224145b545062758fefd1fe34"
+ "09ae169259c6cdfd6b5f2958e314faecbe69d2cace58ee55179ab9b3e6d1ecc1"
+ "4a557c5febe988595264fc5da1c571462eca798a18a1a4940cdab4a3e92009cc"
+ "d42e1e947b1314e32238a2dece7d23a89b5b30c751fd0a4a430d2c548594",
+ "9a2b007e80978bbb192c354eb7da9aedfc74dbf5",
+ "484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f9"
+ "81817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c"
+ "8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd"
+ "1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b6059520"
+ "19782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecd"
+ "e3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca"
+ },{
+ "PSS Example 9.4",
+ "1dfd43b46c93db82629bdae2bd0a12b882ea04c3b465f5cf93023f01059626db"
+ "be99f26bb1be949dddd16dc7f3debb19a194627f0b224434df7d8700e9e98b06"
+ "e360c12fdbe3d19f51c9684eb9089ecbb0a2f0450399d3f59eac7294085d044f"
+ "5393c6ce737423d8b86c415370d389e30b9f0a3c02d25d0082e8ad6f3f1ef24a"
+ "45c3cf82b383367063a4d4613e4264f01b2dac2e5aa42043f8fb5f69fa871d14"
+ "fb273e767a531c40f02f343bc2fb45a0c7e0f6be2561923a77211d66a6e2dbb4"
+ "3c366350beae22da3ac2c1f5077096fcb5c4bf255f7574351ae0b1e1f0363281"
+ "7c0856d4a8ba97afbdc8b85855402bc56926fcec209f9ea8",
+ "70f382bddf4d5d2dd88b3bc7b7308be632b84045",
+ "84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074a"
+ "e0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c"
+ "97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8"
+ "b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a"
+ "919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477"
+ "e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e"
+ },{
+ "PSS Example 9.5",
+ "1bdc6e7c98fb8cf54e9b097b66a831e9cfe52d9d4888448ee4b0978093ba1d7d"
+ "73ae78b3a62ba4ad95cd289ccb9e005226bb3d178bccaa821fb044a4e21ee976"
+ "96c14d0678c94c2dae93b0ad73922218553daa7e44ebe57725a7a45cc72b9b21"
+ "38a6b17c8db411ce8279ee1241aff0a8bec6f77f87edb0c69cb27236e3435a80"
+ "0b192e4f11e519e3fe30fc30eaccca4fbb41769029bf708e817a9e683805be67"
+ "fa100984683b74838e3bcffa79366eed1d481c76729118838f31ba8a048a93c1"
+ "be4424598e8df6328b7a77880a3f9c7e2e8dfca8eb5a26fb86bdc556d42bbe01"
+ "d9fa6ed80646491c9341",
+ "d689257a86effa68212c5e0c619eca295fb91b67",
+ "82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de845481027"
+ "4cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da"
+ "5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afe"
+ "c7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17"
+ "179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba"
+ "3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c"
+ },{
+ "PSS Example 9.6",
+ "88c7a9f1360401d90e53b101b61c5325c3c75db1b411fbeb8e830b75e96b5667"
+ "0ad245404e16793544ee354bc613a90cc9848715a73db5893e7f6d279815c0c1"
+ "de83ef8e2956e3a56ed26a888d7a9cdcd042f4b16b7fa51ef1a0573662d16a30"
+ "2d0ec5b285d2e03ad96529c87b3d374db372d95b2443d061b6b1a350ba87807e"
+ "d083afd1eb05c3f52f4eba5ed2227714fdb50b9d9d9dd6814f62f6272fcd5cdb"
+ "ce7a9ef797",
+ "c25f13bf67d081671a0481a1f1820d613bba2276",
+ "a7fdb0d259165ca2c88d00bbf1028a867d337699d061193b17a9648e14ccbbaa"
+ "deacaacdec815e7571294ebb8a117af205fa078b47b0712c199e3ad05135c504"
+ "c24b81705115740802487992ffd511d4afc6b854491eb3f0dd523139542ff15c"
+ "3101ee85543517c6a3c79417c67e2dd9aa741e9a29b06dcb593c2336b3670ae3"
+ "afbac7c3e76e215473e866e338ca244de00b62624d6b9426822ceae9f8cc4608"
+ "95f41250073fd45c5a1e7b425c204a423a699159f6903e710b37a7bb2bc8049f"
+ }
+ }
+ },
+ {
+ "Example 10: A 2048-bit RSA key pair",
+ "a5dd867ac4cb02f90b9457d48c14a770ef991c56c39c0ec65fd11afa8937cea5"
+ "7b9be7ac73b45c0017615b82d622e318753b6027c0fd157be12f8090fee2a7ad"
+ "cd0eef759f88ba4997c7a42d58c9aa12cb99ae001fe521c13bb5431445a8d5ae"
+ "4f5e4c7e948ac227d3604071f20e577e905fbeb15dfaf06d1de5ae6253d63a6a"
+ "2120b31a5da5dabc9550600e20f27d3739e2627925fea3cc509f21dff04e6eea"
+ "4549c540d6809ff9307eede91fff58733d8385a237d6d3705a33e39190099207"
+ "0df7adf1357cf7e3700ce3667de83f17b8df1778db381dce09cb4ad058a51100"
+ "1a738198ee27cf55a13b754539906582ec8b174bd58d5d1f3d767c613721ae05",
+ "010001",
+ "2d2ff567b3fe74e06191b7fded6de112290c670692430d5969184047da234c96"
+ "93deed1673ed429539c969d372c04d6b47e0f5b8cee0843e5c22835dbd3b05a0"
+ "997984ae6058b11bc4907cbf67ed84fa9ae252dfb0d0cd49e618e35dfdfe59bc"
+ "a3ddd66c33cebbc77ad441aa695e13e324b518f01c60f5a85c994ad179f2a6b5"
+ "fbe93402b11767be01bf073444d6ba1dd2bca5bd074d4a5fae3531ad1303d84b"
+ "30d897318cbbba04e03c2e66de6d91f82f96ea1d4bb54a5aae102d594657f5c9"
+ "789553512b296dea29d8023196357e3e3a6e958f39e3c2344038ea604b31edc6"
+ "f0f7ff6e7181a57c92826a268f86768e96f878562fc71d85d69e448612f7048f",
+ {
+ {
+ "PSS Example 10.1",
+ "883177e5126b9be2d9a9680327d5370c6f26861f5820c43da67a3ad609",
+ "04e215ee6ff934b9da70d7730c8734abfcecde89",
+ "82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5"
+ "afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f2"
+ "1e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad74"
+ "1a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0f"
+ "d57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e"
+ "57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b040900"
+ "0be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04"
+ "388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666"
+ },{
+ "PSS Example 10.2",
+ "dd670a01465868adc93f26131957a50c52fb777cdbaa30892c9e12361164ec13"
+ "979d43048118e4445db87bee58dd987b3425d02071d8dbae80708b039dbb64db"
+ "d1de5657d9fed0c118a54143742e0ff3c87f74e45857647af3f79eb0a14c9d75"
+ "ea9a1a04b7cf478a897a708fd988f48e801edb0b7039df8c23bb3c56f4e821ac",
+ "8b2bdd4b40faf545c778ddf9bc1a49cb57f9b71b",
+ "14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd27030"
+ "53bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b28"
+ "92ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8ca"
+ "ff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a8995963"
+ "7f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c15"
+ "9952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e42"
+ "31690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd"
+ "26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3"
+ },{
+ "PSS Example 10.3",
+ "48b2b6a57a63c84cea859d65c668284b08d96bdcaabe252db0e4a96cb1bac601"
+ "9341db6fbefb8d106b0e90eda6bcc6c6262f37e7ea9c7e5d226bd7df85ec5e71"
+ "efff2f54c5db577ff729ff91b842491de2741d0c631607df586b905b23b91af1"
+ "3da12304bf83eca8a73e871ff9db",
+ "4e96fc1b398f92b44671010c0dc3efd6e20c2d73",
+ "6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c5"
+ "4cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa201"
+ "02854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5"
+ "d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266"
+ "f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b"
+ "442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e065553"
+ "1c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724"
+ "716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb"
+ },{
+ "PSS Example 10.4",
+ "0b8777c7f839baf0a64bbbdbc5ce79755c57a205b845c174e2d2e90546a089c4"
+ "e6ec8adffa23a7ea97bae6b65d782b82db5d2b5a56d22a29a05e7c4433e2b82a"
+ "621abba90add05ce393fc48a840542451a",
+ "c7cd698d84b65128d8835e3a8b1eb0e01cb541ec",
+ "34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7dd"
+ "eede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82cc"
+ "f09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234"
+ "b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fce"
+ "c58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d"
+ "023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f"
+ "01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462d"
+ "de8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb"
+ },{
+ "PSS Example 10.5",
+ "f1036e008e71e964dadc9219ed30e17f06b4b68a955c16b312b1eddf028b7497"
+ "6bed6b3f6a63d4e77859243c9cccdc98016523abb02483b35591c33aad81213b"
+ "b7c7bb1a470aabc10d44256c4d4559d916",
+ "efa8bff96212b2f4a3f371a10d574152655f5dfb",
+ "7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f3"
+ "46b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1"
+ "f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b"
+ "3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be0772"
+ "1e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6ed"
+ "b8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9"
+ "215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24"
+ "869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc"
+ },{
+ "PSS Example 10.6",
+ "25f10895a87716c137450bb9519dfaa1f207faa942ea88abf71e9c17980085b5"
+ "55aebab76264ae2a3ab93c2d12981191ddac6fb5949eb36aee3c5da940f00752"
+ "c916d94608fa7d97ba6a2915b688f20323d4e9d96801d89a72ab5892dc2117c0"
+ "7434fcf972e058cf8c41ca4b4ff554f7d5068ad3155fced0f3125bc04f919337"
+ "8a8f5c4c3b8cb4dd6d1cc69d30ecca6eaa51e36a05730e9e342e855baf099def"
+ "b8afd7",
+ "ad8b1523703646224b660b550885917ca2d1df28",
+ "6d3b5b87f67ea657af21f75441977d2180f91b2c5f692de82955696a686730d9"
+ "b9778d970758ccb26071c2209ffbd6125be2e96ea81b67cb9b9308239fda17f7"
+ "b2b64ecda096b6b935640a5a1cb42a9155b1c9ef7a633a02c59f0d6ee59b852c"
+ "43b35029e73c940ff0410e8f114eed46bbd0fae165e42be2528a401c3b28fd81"
+ "8ef3232dca9f4d2a0f5166ec59c42396d6c11dbc1215a56fa17169db9575343e"
+ "f34f9de32a49cdc3174922f229c23e18e45df9353119ec4319cedce7a17c6408"
+ "8c1f6f52be29634100b3919d38f3d1ed94e6891e66a73b8fb849f5874df59459"
+ "e298c7bbce2eee782a195aa66fe2d0732b25e595f57d3e061b1fc3e4063bf98f"
+ }
+ }
+ }
+ };
--- /dev/null
+/* pkcs1v2-v15c.h - pkcs#1 v1.5 crypt test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the file
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt .
+ */
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *seed;
+ const char *encr;
+ } m[20];
+ } tbl[] =
+ {
+ {
+ "A 1024-bit RSA key pair",
+ "a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0ab"
+ "c4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72"
+ "f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb514"
+ "8ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb",
+ "010001",
+ "53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd"
+ "8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55"
+ "fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbf"
+ "b78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 1.1",
+ "6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34",
+ "017341ae3875d5f87101f8cc4fa9b9bc156bb04628fccdb2f4f11e905bd3a155"
+ "d376f593bd7304210874eba08a5e22bcccb4c9d3882a93a54db022f503d16338"
+ "b6b7ce16dc7f4bbf9a96b59772d6606e9747c7649bf9e083db981884a954ab3c"
+ "6f",
+ "50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b80804f1"
+ "69d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d8ea0e607"
+ "ac58e2690ec4ebc10146e8cbaa5ed4d5cce6fe7b0ff9efc1eabb564dbf498285"
+ "f449ee61dd7b42ee5b5892cb90601f30cda07bf26489310bcd23b528ceab3c31"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.2",
+ "750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5",
+ "ac4728a8428c1e522471a8df735a8e9292af0d55bcb73a12ac32c264f3881c7c"
+ "8a710f70feb10485c8370f781fffd021816f058739766da0a9c9db0eae7e9a25"
+ "b6c43318d0caac236522ca310f17fc52ad4229c83a24e9e545eb35e9826d559f"
+ "57",
+ "6842e5e2cc0041d6b0c81a562c39a617379a515cab74abcb2619c7740a541d95"
+ "55dd9165975bf8a3ebd0d0456661dfb1a6861ba2332269930e0db514fca0733e"
+ "eb9c405713eb1f9d768033ed293e1e081a125f32ddb9ea52edbe275c4af60f8a"
+ "7bf832bd227561c208dc0031a84b5012c9dd9f74459dcb070bdbe13cfa8c2d50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.3",
+ "d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c245"
+ "1fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051",
+ "dd2d60a5e008ebe1d0be6f60dbc43f2962ef50bfde542bbbe98fedd1feac057e"
+ "771cf15fc632c8db272e28d29b5793ea6ab806218c538239b93a935e65d24416"
+ "ec6c6e99ae04",
+ "709c7d2d4598c96065b6588da2f89fa87f062d7241ef6595898f637ada57eae9"
+ "0173f0fb4bf6a91ebd96506907c853dacf208494be94d313a04185d474a90741"
+ "2effc3e024d07e4d09aa245fbcb130219bfa5de02d4f7e2ec9e62e8ad32dee5f"
+ "f4d8e4cfecbc5033a1c2c61c5233ae16192a481d0075bfc7ce028212cd27bebe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.4",
+ "52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85",
+ "2629a7aac0c3905e831eb602388c545af554b96b2ae51532e9ccdb8972ef30b6"
+ "4a2f98c695297a01c5812a2c401582f37b144a3e90e59d81b69039c64b844b02"
+ "8c105c8e683615afb658b6c4d9f38238a76301bb14449113b69de126045e26f1"
+ "3ee6d7",
+ "54ddb784268eadb3955bd9f9498842595ad29ff8a667feb41f6f530cb60bc926"
+ "ac6c71c772f803d022b41ca57204223b27ca79ec5b72652ca9afbf40dc2f6a0e"
+ "13bcd60d37f79504b0ffcc01cf5342d6d34ac6f1f2f9f2f4874625b9fdbb7dda"
+ "2ec87df0cf87259798df86a06bd5aef7354b8cb1cb137575f4cfbc46281bb331"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.5",
+ "8da89fd9e5f974a29feffb462b49180f6cf9e802",
+ "c3ca84600f35c8655fc7c64c75c5873853d3aa8a9426a51b63d7e75dcf6cae97"
+ "a4253fba871d6f968997199bf01b6a4d3428ce4c96d1c487b2830cb9e35d6405"
+ "5623699ab4979a02584b92e6ba39e757284079abf133a7da54e5425217a210f6"
+ "7c18269b511f61f8c5",
+ "a85548013bd0e20ee0ebd36fb748977f985846d7610eed24c36cd83033dd2aa4"
+ "580bd15335209dcf782ee26c48c30644b0b5cc86c8cd165ae21eadf578041867"
+ "7607031875e221ecdf3b1057316f3f12a47d5da40c41539b636430da2e542190"
+ "119e429c53c2226f959b19ccf48a3d240217c4de70d7072a7e0d95b616d115a8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.6",
+ "26521050844271",
+ "3c6a0471daf00b7c2efc9ee88041654f87629007c124322211a5f4ea3c582385"
+ "7bc8fc7e21c94548b0eebdcff79160e112461e40509110cfdc4f0f13c7fb921a"
+ "bac8dfaac21acb0f7b8a13a4b5cca523d5c7ddf70523eb570c59b6c7ae9767e4"
+ "ec9a63d1136d10231b401e20e74102848348017a1616",
+ "5e514363287de9b380048cc4435d53294ad5941c551a97e13c16dc1398de610d"
+ "c7337bc6bde578e9e9f56af14454f2e831beef3231a85068e8fef72c89e1df1c"
+ "99430a60f6d94289cfba87b2b432a40b88db61dae088f9ed4e284a2163af65bf"
+ "2b43559a5da2aec5bb8f43f92c1b04a5146a65b6e019b4cdd2940c35d9645b2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.7",
+ "8a847dd9e2",
+ "a13dff8a48e80494ae66e6ba9f179a010d9e6d403187967f99fdd90ef90e0a94"
+ "073ff0e4d0e6664ff373b509953e04ef7783be0fb46c8a9fc0ed8c1f33cb4d0d"
+ "2f1d0d5cdba14dca508ca1d73d208018639bc8e1658623de1e5ba3f05ed0914d"
+ "2f96902f2520332d8492d3734acdebbdf43e50a43e7aa872",
+ "827a67e815781c4d4e2b2e169d80cae9366872a792afbf3c0cd51ce28c70e86d"
+ "41ebb9752f3f92dba51adbb6851b1f784561a8f197208fde02970b38f2a97422"
+ "ec7f4fc8a10675a9dbde109eed0ce06527703ee05b657d3408f7fddb1eeccffa"
+ "e16b1da107307a2cf256fa60e8152172de9f9527fe920a901d93c4f4d57e546e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.8",
+ "373236b7202d39b2ee30cfb46db09511f6f307cc61cc21606c18a75b8a62f822"
+ "df031ba0e0e82dd2f3e5d31e4ea257b15b",
+ "219974a087f0a28193e649a04ae9d84cf2c8a9a46cdfd8f1ac62c7e0f20f4e27"
+ "030c72b20a5db725b4a8683df5556ee7947fa0a7661b6d99dcb79e494f4673f0"
+ "73a041dd907c87324e8625dd",
+ "1a6df5759984f2c4119355c5db35c8a478164d5e5ee77b4991f104ba91b9870f"
+ "1591be1f19f55a8051a62c0e59493df6f00fe50ef73a6cf0c43541f5320dab7b"
+ "2fc67c93225cccd6d50347aa969ad87bd3d82081454fead810dc1ab8c21781f7"
+ "612e6406729b322e04b1624f8538985659ae34d9931e019f762c797d5cbfa32d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.9",
+ "97e0b636bfddb8e1c8a9cf5b305cef3a8f47f9a8b3344f1355fa3dbab67bb972"
+ "10",
+ "c1f89bcdc56040d5e663b74bfde2397b584608cdf32d5a5844724ac7e598a86e"
+ "f7114b1be08730cb10f661fbfb8609f7c6c37442a1b11e04a611ff8ca5ce9afc"
+ "1eb3aaa92c9f28bae220440578990226078378c493411374c53e3ddc",
+ "873cc4dca427972b63c6cc8ac11ccc33c959f7fcfe4b45bbd47b29d9c988c01a"
+ "96bc1eae0ef9b1948dce2cc9f0aa917e86a6c11f8da3da29df905901f1918a76"
+ "168de1175e2735128c097299d66ea5ccf9b95b3692eebfc6ea11bc37091b795f"
+ "18803d70e79558e12516230fed5515e51b45ae86cefe47b93790e4994dc41e05"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.10",
+ "82b5075bfc88f4006576aa80a0007a7451184d4f760cf9242804222b0e0726f5"
+ "55030e4e6b01f793b097018127824a3e402457d8495fc0",
+ "d55e3d4897e9d865014cb15d3ee3f9fbd29c92e5c237dcae46672a463eaaa4f7"
+ "dd09861e946ac65b8562506393b85192ad41fb0c48c8c052981bddcd5f1fc8b1"
+ "39cd47cacffc",
+ "2e83c3d288015a5f503d3e5de7d2ad9106545ef97d63e4d06a5a0d9dbc29f6ba"
+ "fb93a5173fa5063a6939dba6c7a428c35e7dbe6a9593fe5ec4c19878893f3137"
+ "09c87602726cb3255be75adc7f2f27e6db91c3a343eaff1c28d9d5f7cb6574e6"
+ "31069003cdcfa07743a7340d58839e708bf36af6342db8dfa41feadafc6953ac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.11",
+ "3648c36f851f52f2328779091985a3c812e18a7055d090bbf0324c13793bb822"
+ "1a57",
+ "c1277185c35955caedfdf9de55d5d95a398d58f5f333191fc02945efdfadfb6d"
+ "b05ee2a2d34183edf89a1a4dccc46591b3532ba7039362c75df194ec106448af"
+ "b7f6bfb2807e383e159954255e827cb9dadc8d9b7e68a1aa097635",
+ "8862f1973fefe0af02d96cc458334ded6c02d8d7eaf593779c5d386c4e49f768"
+ "f130b487b3c91e323a477e4c110a3341ff46eee37c773e5c0ac839bc55cc0c07"
+ "0cac01cd45183cfee6b88bfb82361d3560197cdeab42e5c755d237971a88daf6"
+ "10cb3952614b364056cd491420effe3a0b8ce31f2e3e49cad6f3b0640f4491de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.12",
+ "94f78cf45c53fc46e7eb1b26618a29e9485012c1",
+ "e6de9e9b9022a55f56121d5ac00aa6df299c8a369422e7542956b6da2e0dcdee"
+ "968db07d995a7bb876f7f8cd66b2f542c05308f74983a3f8360c6b8947f87d60"
+ "8b031a2c68dde1471ae496ae9b16e2a81181eb6fc2f65baaadda6422a93431f6"
+ "f3b07b5b46a3cf8948",
+ "3c6d3b43d23adb79d697233808b074487697f335fd99cde865411fb182289256"
+ "1fdc24a8b8bb2c4f653c4d156c77a75de31600b5709e8d506e98e1d373cbda01"
+ "f4d9feb0297198cad0ca2a7e3b1e63903b1043ce79494c5754f7f90fc1f073a6"
+ "19929ef126394b0624f3b8ba6d5645e990e7c0132ce2123146fd9cadf745ec61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.13",
+ "779d1eb84fa284c37d29d5e179d00306b413c44a800a077e59853f6305f92e59"
+ "fb7f81",
+ "c3e6d18bda97782ca781fa76d97a6c94d854d14199b4ea7d82c5bcbbe6cdaab5"
+ "255747443c59bf8c77ecdaa64ae7ce61e2c7300132b754e9162f7cde758f480a"
+ "e588cfd44a946d64e2720a2d17525545220484838118ad6e6b54",
+ "722ca92566c73cc85d19ce3faa14cb2e79849f205092d1589282313c0427f067"
+ "798afae3e3f0a561f399346e9d107da04af44b0c6f044adefe097a0cd14a47a9"
+ "9cd9819a98413706307cbd0da01697469eff71d31441639493fbed8eee1ba39f"
+ "dd07fc0ea08230186179f90e7ef13c61ee56f167fc2f6b15793e1a3224ffa29e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.14",
+ "88",
+ "c0169d76e4ea4545410ddf6646c1ba7dd272d7c3498ba6b0804b426130a80fbf"
+ "ff4bb7b5f559b0a9090e4ad9b9f416a6dfdc1501b1ba46877b1a96fa8491dcfd"
+ "de50ebeed24d3f98962413346ed4a3393e235b77bc1ed67468ece2792a2fd3a8"
+ "348fc5509b5906f2885615df8c1461377a741d5952fb36eac0201e27",
+ "4ed7d1291a0336654d5ca2b1f9d20cb2da7226f7116b930988439b4463981104"
+ "bd63c2ce2b77d626b3109c931403ac5b49b4247c4f6967b8c0db063c9995af9d"
+ "36540650938b01f93906f9838907ed5936abb343b0e25509a1d2d4c5c8b95806"
+ "50da2ce11fa3cf3e640723eacbee87fad3ee35958b45075df781c413466af139"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.15",
+ "a2dc087778d543408e8973f1363159edb8f0783c457089072dce66d3102bb4fa"
+ "e60aa60e41933c48a1be3953ec2f804c0cc96c",
+ "18112014065329d04bfb0cf544dd38d7bef1549b4a49a16776dda74d0a7edc49"
+ "67b4240c37142fa3f6639c2696cd7d4b18a11e2fb54081f2de5bd7bd15cdda92"
+ "c94c3a47187b5ff43b53",
+ "7115190a210488f04fa0c00c93a468a8030b7b9fc10020d8310bcb01a5c8dda1"
+ "d06ce241dc775b43e6f13b19abfcbf3616e84f107c9ed80d1b86bf87c98c2b62"
+ "9ffadaa6ec01f4e675558ef52606eaf126068fa7534dd13b920d2381695ad775"
+ "fff0bb7cec4690901d6f1e1736b82cfe3a0c224d18f12915fdc95c18397c3570"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.16",
+ "110bf2b1d0dd812f2a5a21f3404fa2f2c454c4432fdfa70f1b0f23ec69c10237"
+ "73a73aba",
+ "17b85f7653ff0ef5de7f25696cd49023ad8eac948a83e22458ecd5d10a43866d"
+ "c791555e64f078c38c752b6e9c6eeeb339eec91016d258886d012775ad643602"
+ "a0f0d1793454a0609471162288223950826ed8e2025da9a4e9",
+ "5d0f2fd85e6f9d9e432fad860fdc49969624ff4fa0715d361e9f00b05b3aa0ba"
+ "9eb27bae610efde1143cbc933b52dea7018760bb251be0e1e30cd1c5991aef74"
+ "4db82f166b9063efb7e33840a2569005654b140e115fa56c30406e45656e8199"
+ "af394f6386346d5f1a300b95ba48fc0873d618d692bb025bf15e9d232c641ada"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.17",
+ "d9d937131ff1940a86bf7139b48114364195b4005222a8bbbc261a7f2e212b8d"
+ "d035e53f9144f5610b4cec32ea01bda9d3c80cf29464f80f5f5656c8",
+ "3305e1da60e58673fc46cd33be2a66d3a102c3db161ef48c0d60ef25031b4014"
+ "167826246aa528a3a3e5b0ab95078d8401d92903595afc1aa854e6044e5eb5f5"
+ "be",
+ "0e12167489f0baefcad63934bc159f1bbd9e9b287e500f490923c16a85564a1d"
+ "a63659375f22af7ba49798e1578cf315fae3e9ed5699c691e3c1d0bb46da492d"
+ "01349e9329593d4381d074a0a531df921b31316f7e2b4fe915347283242335f0"
+ "b0b23192c72102f2c63624b1e78965450e8230d4877e4617b03d44831398ddbf"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.18",
+ "81b34aeb8afb8a3f",
+ "02f748342d010fb56a6f69f21f8c6a631679c8c4b8f6feb525cf8e72fda8ef8d"
+ "f6623128c0fe74bc590caa34f1eed1ad2d6142dcc5bcae84ef313762f2e4e703"
+ "03d209c8d9577a7c843d2b9172ed4efe2ad629614b99a91a4cc8325ba324116e"
+ "cf0c5e29094938ae498984f4f4cbb1623886e03973",
+ "43b276c7d368ea21c6807116cde8608298f24002072d776e56e62c3572bfb99d"
+ "a4c56e938a47dc075fa1ff7a618fb5faed3ee37b91dfc39153495aeba9df6d45"
+ "df94b0e8a8ad2db37a9fe46d0fdf154231fd6f3221474e8f5c191fdb8538e1a6"
+ "03e59897e150faf95b65da140667edb19809eb4a16acd01ecc604bda57f20ef2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.19",
+ "7bf9fad889de73ed873d",
+ "fa5dad45a4bb5e74c4cf2e213ed40aa9617598d11d49ae1c32d794e09cd0e5c7"
+ "aaae81b9554dde3108d60a9a82f42cc6c2a689f460ff1d53ad85bf838311e758"
+ "9e1967957b51567aa0d33afa3752cde6c5661d4f27aed3df52905f1cf2253304"
+ "618e0786041e70b4dcbac8c108ba34ac3939f4",
+ "61c2550e0b36a6797ff86493801b1146d89059498352e4c262275b1404b13315"
+ "e956bb3d312185b521b3c708e9d954021719a059d984724c53c04f5ad274bef9"
+ "ff0a7950b2fdecc5290cd5f3bc26524cd1342048184b0e2cdf9406a453a2ef9f"
+ "3bb23c4e7c1c8b2952a0202bcc238247ea327b8c0700c8003fd634ec1ed9bf30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 1.20",
+ "b6a3509bb3b9b0b57cd58de409d953201a042f9492dc1d7e34a7d0941a1a1b",
+ "3a9e15065786b3e01d826b862a8f702b5cac8c1662ee7d15ff323cdfe71ebf4a"
+ "d1b1f3a6bcbdd4b0010877ecac091f615908e2be400bb0c498e355d571fd1089"
+ "5b8ee9c3a9c31e4b110389c3d5c46ebf76b3b35ad1f4791b6d2097f109f2",
+ "6b4b6d7babfe4d6417acadfb78572e7c87e3fe1bd58eefb0d4b1279c7b7c8326"
+ "a68bb28795e09f9b1ce2e24a539f4b0d93b29274cecf7cd9f0b732aebeda9111"
+ "bdfe25e268a88e3422e29b52bd4b7a0547db8fe12a6fcf1a3c06a002bf870a2f"
+ "abb7c457e4bbce3e316f7232449f87a9d702b12d19bde7f9590f9467b06bd58a"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "98b70582ca808fd1d3509562a0ef305af6d9875443b35bdf24d536353e3f1228"
+ "dcd12a78568356c6ff323abf72ac1cdbfe712fb49fe594a5a2175d48b6732538"
+ "d8df37cb970be4a5b562c3f298db9ddf75607877918cced1d0d1f377338c0d3d"
+ "3207797e862c65d11439e588177527a7ded91971adcf91e2e834e37f05a73655",
+ "010001",
+ "0614a786052d284cd906a8e413f7622c050f3549c026589ea27750e0bed9410e"
+ "5a7883a1e603f5c517ad36d49faac5bd66bcb8030fa8d309e351ddd782d843df"
+ "975680ae73eea9aab289b757205dadb8fdfb989ec8db8e7095f51f24529f5637"
+ "aa669331e2569f8b854abecec99aa264c3da7cc6866f0c0e1fb8469848581c73",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 2.1",
+ "e9a771e0a65f28708e83d5e6cc898a41d7",
+ "168e3eb5809b0870e1f2487e1be77a176b34716de141ba4c9059da90e5e51a36"
+ "94e858fed10b926c02523980a8909da996c64333ea676787bce677f11fda77db"
+ "b1a9516edda9b1294fc2e450522288e930be7fa729b250e3aac520511e9516aa"
+ "863af6bc075cbdbff4304670",
+ "71c2b8fb3819f134c2247c6babb4cfbe17d7b2643f87ace5c571277be1908ef3"
+ "a5288e34384e460a70386e7ea1d19d3dca1ce15ba93239a8cdda18e317fe0796"
+ "80ce7e6ac6d9bdaf86cb9aebf1cf46cd10ef6a688b0cb2ce765dd0b325204239"
+ "66eee1aa05c6c28c6f3524fb686b5fb15853659e583ac437219def8edc58be2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.2",
+ "664bf05d612baf61524c608eda36fc6ea2c93c143153221bcfd6ba0cfbbd6b64"
+ "1447e4788b0a462cb5b3f9fafc9a75",
+ "e7f0a27918cad915da28113659ffb5dfa0b51b24d5a71c2027f8e4d9409e8c64"
+ "72f0c54b5c08858da63d4b8172b07dcf8c5a7e8f9e90f017c24b44d16b670bdc"
+ "96030c8353a2839ba4c075d24c20",
+ "0686901813db053ac708e3fcec6bae0360088fd344e9d7ea118bb3f537531425"
+ "1e606737f5824b3628f6650348f6ab553b277da01544d05673baedf455cc0332"
+ "f613f65478fcfe066734c46558bc233b4b6f5241e4f4ac53fc18c55384c8fd96"
+ "183f0bb5515e893114f9c61ccc11fc1983de74469264dbdbb0c749174ecdfbe3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.3",
+ "5e76e66ed57541fc23d359f4adbf3f568201d3c6f0e026aaa5676356cc9866f1"
+ "755de98cb39f236dafa9e6bc794b7443b53a2d85",
+ "5c6568b6e33bc13ad2dcd6012d17da81b13dbd62aae40a64af97e219e75dc181"
+ "126077d120dda19d6312cf1e9871c115f0867fe662d78a4031976bddef68f52b"
+ "68995867cd809505dd",
+ "19e79966ff1fbc10073de73df3a531637874e47df639256c51d0bba935610b46"
+ "34f9e5b4689bd921735b32236efcc6e7cc49a9e06a25ac9659b7fe829cb3e8b0"
+ "1f103179422365741b76c8342149cedc76eb0ad018ed4235fbd524fd87c9549a"
+ "b33ff23ee4f8200efa33027e9deec60fac013d1e56e6e333d493a4a9460fe58a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.4",
+ "5b195048eb90eb4793",
+ "bbbd49550ed1ea1b6bc7206ce0b003a632a52b0bac5f32710b39fa64b3556ad6"
+ "f6c82bd9d531b307469e863f54b5fe2183056954f2a967e4dc2b326e41dddf74"
+ "3a764f7e82886829a8fab2772a3497706b9538a9f84296c82d9bafc29c39d468"
+ "4f75ff6bb1c12e39bb8056af2d24344b2cae4629",
+ "42c9cb6821b55dae30d90025753112e6ee02f4ad6f0f5b3cc4952a127c8a16f6"
+ "6479b8144f3cf29d84e43d67d67712c7f5b76da2c66ba0e90cd4b1fc1c1b3f17"
+ "a392e70408288af69b50fe8a50b3296a0dabd7c8dc3984a1940688be70982516"
+ "20256cc21b7c76ed29d86ff7c01ec287df4738be3469b30a3f8fb7be83d9361a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.5",
+ "660bbd40069cc67bade41a09ecf43cc4513f7c7cc02dde972d2b1f29295e09b9"
+ "910c59edba0ed2ddf11a6d4169351f97240733528f91b268faa7af906e",
+ "307f61b183a8dcf9155ab235e61fb56ba2b8795dc4235385e8acf366d25233b4"
+ "70e05d7011b6fc532f0a658ad13afd290c6f30e2795ee3d39dbdc80f560ece2f",
+ "049b26050a3abef83ec2776111e3b72fb9a2d6a801055d6b5e0da4e95ccf2ebd"
+ "0a786a9721aa7925bf15beb62713a313877dd85d2658b208e88e6445fc35019b"
+ "0cad6bf4d06e2ca5f11949eeee7ee47f1d5b4c88241f50e4d6edf0183d4fa35a"
+ "371fc407364f2dcaa4cdaecefcea6dfac1d513f905e747944744bb64576ba1c8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.6",
+ "81cb0a97698f823b56b45f",
+ "938c8dfda08b89055b68af011f246cec1f93a2771da97dba20954c900912285e"
+ "5db187b29e3272e99e694e1214172528453084064e5c60f01e786fc5d0d9af06"
+ "39a498c57ade937760ae517484afd7025ea0d55a62b11f9aab7fa5ddd093e5ea"
+ "bad61b67a295a775be96c6b76ec3fe472950",
+ "7fb8f335eedc4af6af44073da196457d046145030147f8420fc79bd589774a73"
+ "0a6d94fb7efadc5aeea7c070f189249125e166c6d30129ecf2c4822a50496bc2"
+ "f21e79ac57dbfbdd71a68b58d9051b480bf47748a13dfb673eaed7710a468fe7"
+ "2f7d74e6f4a28944043a52d930de68dbcb6ee7fb8b69640541e3ed5b754e65fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.7",
+ "05f7835623c8cfaae482a91085b97f6b95928bb974acad02364aaf1317ed53c9"
+ "db2ffbc8a3cb3a00f44dacef78",
+ "80c83d2547be41baf2321bd30a9ab7749c5eebb5a1fff0b31d6bdb0ad16dd0c0"
+ "fb3ec157e78b0986602041cde88957a55329e3e2cfe85a594474945efa333585"
+ "fffd41ebb8e7c518c3c9259aea8de635",
+ "87f9ce05f0ac9c05e45fb7bb555a7a18a9cdc55f544a542101e9a71cd2036682"
+ "0e7ff6dca34675229d86e4fb5871f9310b12bb74e28618d6d6586587f66acc89"
+ "68a83cd807f4d21297731d7c22c14599e75719fd23052b8aa65b7e9c5c020038"
+ "2d35d560f2d33dd049e06ac827cbdd9af581a6b26db61d43d7124b34721df142"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.8",
+ "e2e0f6b328d9bbe9fd66cd87987c1160ed237b1c7c656a89fb1f21d709403b04"
+ "10f8e4e12eb9690aebeb3807319a936564f66717a71c4862ccc56e",
+ "cf18e608b156145c44de314966cbcc6674a45ae0df900406e40d3dfc322f3940"
+ "4ceeb6dc58f801bbf2ac4f47841abd796179d0824f3bf5518d78cc66ad8dfbed"
+ "b117",
+ "1401aa21ec6ebaa7e3a9f713c86b508e375f6c125b29626ebd349f64e20fa48a"
+ "1b068479fff33022f66f86e97d9c5edd9026e3183ce08641570659352f87a618"
+ "91f3d86a3d245f0245e39d99892c67fa2bed8e37548de23defdd1e43d5d7e3d9"
+ "a3c22ce6a368d84c5afa1cc5bf49b68fe5c25a326b0eec5e44c5e2ff5a359dd1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.9",
+ "c69578ea03e269b1b91633a72f9fb4d10c",
+ "e0a1a9bae30a7ac66cab3d86433c1ca5e8ac2b74e483ca7f34597716ee161890"
+ "6c97772f2886f46d783121b7fe1b8fa5fbec09c068e5635c89e6a0a9accf2b12"
+ "c64706b6ae9a5a74abb83f64e13a8c53f926760466b645e28e9ad6461ae7b89d"
+ "5efccf7d89149aa2e69f0d25",
+ "78f87d6b06761bd7e717e0c5eb40e1fb80899c7be4017c2efb075978ee38d0f9"
+ "5e9803dcd40fee9792c61d4a2d85dabdea96ca29f3ca1e8bcf817655d0c09474"
+ "d98094eb6a7ef0333d6971c93836fe0232f718463dc9541853463bc1cf03677e"
+ "786ee52e7271c3c11ac00553c6752707e0df9280c4f2b7d19fd6f3d8bbcc7be6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.10",
+ "7672cfc27a41d501aa4c41baabf4525a7c455fc8",
+ "4ceea1a89464a5d2f89e078953caf776365898a5bd5e8e448c65da26ff98900c"
+ "d08061ef446c69b48dc4609ed8654a646d708262cb8409ac27c4a49adfed47a8"
+ "5ad429ed75077578e4c273c61e2c3b46beb472f0a345a05d61a7eaaad8a63e0b"
+ "3d4952f27c4081329e",
+ "252b14133f1db25013293501e356534f26afe334688e68d791833a0d82560570"
+ "bbb3ce2b16d8b5f7f89e7ebc7cf9c294ab3416b7c21187707fe5e7992e720ff9"
+ "58daa40f5ad45bc747479639a537fe0a4a75fcfb45a53f0173afc0f3cc910b86"
+ "ae3137628d90ff675ae1ae31e1640537ea1a7cccfb73f8be5aeca03bab193bb0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.11",
+ "a16ad8f2e0932342ed21e13777f4652a3550ddb4368b5ea71c66dbc3bbfeb7db",
+ "55884c830d4a80b79f089da74dc25ae0c482462145e1d09523da3c9344bb97b0"
+ "52fbdc1543dfb53cf2378259687c7b1b35caf2f91999ed4ace39af10d6bed0fa"
+ "22444c129d90741cfcda90198e2782fb03bdcc7cfafd89db6fb0fed224",
+ "08326aff6d03cc4e2610dd536af7f21d76227d827d5280d8b83ab9eb30e0769c"
+ "fa02b5c1352bf4d170ceb66f8be698784e1a6c203fa5ab9007a6f7fc2065204b"
+ "982fa561fbb361af2b8eea42ab3fec0ed08622e5f289805275380b69342a96f7"
+ "6a9904876890d92f24002032351d8a1cbc3d27b2464821bbfbfbb9a678519610"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.12",
+ "4a",
+ "8aa0ced17f09adae610a46030dad40311bf1469c2737411e40f92396751dd566"
+ "37c958dbc58a17fdbddddbbf7975187898be1aa63c5eee5f9a1902980f595184"
+ "b9b5b465b92e20f7ae8b5a5cee7f3b57d997a06a702d238350a92698ef275dff"
+ "5277bd2c999647405adbe4fb3f1be75e159a4c438313b7fd8aca9dea",
+ "4c4e5ab62d0c967ab82921429ffe50d2240e7e0a1875488755bb7ff615a8c99a"
+ "bc37b2e47147a927d7b98c30db24da8cd35e13d7b71414d032bd0c3ce38b89b1"
+ "1b2c3f9d830816716a2e8ccd8c79e9c74931a7b8a8db13128ce40b2159e498da"
+ "98f2aa352f23853106b661d88ed06ff66a56e756597220bd10158153ce5c0263"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.13",
+ "bffc420873f5af5dd23bb0",
+ "dd31ccd47d4e3102df0fc59b1b8477af3a78c2fa9c8ecb4f0b3bde2350043655"
+ "0364665f81c0356abc0b78e9731911140275c866f75ad0cbbc88ad6b5d4da52d"
+ "08e22ee539b58e92c6196387e221a087396cbe57ec5603f6162627983eff82de"
+ "048bdc1b5edbb5d4ea84f50224bd88a905da",
+ "0da2d6f7bcb50a472eda24609da67728e53c9880aa5fb6fbe60d83c11e6bb3cf"
+ "db17d14dbce8ec55c73ab0143e9b2756bb6968e5af1aedcf6a80c26d490e4718"
+ "7ea5d8cd2facb81ce64a723c40f0ba4c693e1b1143df15a42091709ab4c7cd9d"
+ "47079ecd68f6a196448a44679a041410418f11a1e1bce78e772604a2f2778195"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.14",
+ "1a9b8729210a8471fc5cd709f2edd3240150244bec96a92ff807e3b30d295d3c"
+ "345c044f2e956037",
+ "5878c91b166e90c34e6e66568c151f4d444340b5f1d73052cc5633ea2e47aced"
+ "7b178a64fb09a5ad0846aee4116d6780ee75eb20851668820cdec0f2c496e4c2"
+ "88d8279c1c5d4ec00d980c272e870518486dcaea85",
+ "3700ac362cf60e163947a198d00f3b3b26e03ee2fb782b4288b8c1de76e9e899"
+ "46c9807c56e09c7b52be0078acf692964acb97d1fa5ceb5776a1d556b4bc9db0"
+ "0bda25237a751b7c229b6b57f7ff751c12d1f22a4fb0e90b63d042d9499e0f7e"
+ "feadd3c588f2c743a12c567c81578dbeebfd3774da34ad09eebe9017890214b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.15",
+ "a6d0e8c1ea4ab4ecc8957d62281579675a648d62b7f22b2b08d1313f406f137e"
+ "99426735cdb9372feca1ee78463fa5de9cdd84756c68bd1d92ba965f506410b1",
+ "1c25c9b832169a1fdb6c148e47e66c3cc82141e611a6f30cc90c5049e8c502b3"
+ "1cadc76239b7bdaf93fa97343e7ee551bc52fdb5ec9e400af05dbeacda",
+ "00e8b2fc76dfb4a6cc4364de8f683c3fcd0a9ecfbd4a5a7224f49ae9b4f3b5cd"
+ "c71cbb8c66fd35f3d18eca98967bd4005df79152416fd47e562c55edc6d61212"
+ "286ef975bcc802692592653900973c72e01a693b05fc2d5856eaef7ac08ff5ec"
+ "d531e2c2ce927745a1165a51aa6698a1ffcb87f81ef6510bcaf9cb761e9e1f0f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.16",
+ "f3405b218f3ec603a980690099c2cf5cbe0b2b059679c46b7e48f6fdc4da4092"
+ "d831c8b52b2cc79bd2bbf6e9f57b4e8caa94b581f9f231261f0e2bbbf53dbb",
+ "f4707f58642b54cbf80a9b5048a6ec0bd35d095716db12060cbf50585fb92379"
+ "81052f7bb1583cd87bc8bfb55b733e890eb9c08ef0e880e9ba0d50ec9541",
+ "6d9d39198b5fcb132d93151149d75991024ac22eb6eb2dc7c6058f6487564510"
+ "2b95254e25e9f0ae4506d43c601c188a314f4bb4e038c81539416e105e8097fb"
+ "695aab36fef516e6a33f36f7f95ad1ff15889025b1b2e81e1bf3b2de5ba9187c"
+ "a96ceba9fcecef9c53e4943486185967cf7a6477c329f00ea695525bca99f2c7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.17",
+ "6afadbe3da68d90285bb8f1e2129ffebb1c65b9588d6c2c04024c238b20c65d2"
+ "aca5e38276000a0e6a0d0537efeef6d3e3d94fb9",
+ "ee176ea3cfd490b6c049d2e74c90c0ee7468520349b851653db058a1c3e956e0"
+ "885f261b6e71cf1e623d3b9d1d56fa1367e47ff374ad39309ffa2e671128d5ab"
+ "b4a61a5b0dc2db2c08",
+ "672fe95159a9893f3498b616c17b59da71da802febf7cd38110614a1b25d96aa"
+ "8a74aaaa2a0f000ef8aca3b41ad161b62633f241319c33e4ecb7706ab3adc6a3"
+ "efea22430f3f5c9c4ce5404eb8e75a109369c0aa0b7dd713bd8b77cca5f74bca"
+ "5bc555696b68e1172db402501dcd2649685db0fd88c88360dacc6509ffa8dfc2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.18",
+ "6d9f9b4bb123ba909553a7573a971f64b72524cfeb042de39215f650db612d66"
+ "d7ae8605d0441954625fa98122330e92",
+ "7ff8685aecf340261390ad0742730cb639283014ab3773556c697f97ef621a4d"
+ "cbf8ec6edec50d8ec9590adbaf2351ddfa0e52ea6ed18eb6c378f38085ae5ee4"
+ "cc48c1891ba47b2010d5d43539",
+ "8d30655cf15bf10a469787c6a10e79254ff0bd11938bc60a81a758d93cf2a030"
+ "2459fc2f0d7700b86dd6ed618383b44b458704ca11928e504f028efe5037172c"
+ "3e51b837be6156de6a09c55597be74c97caa1debf314cd94b91b9f94cbf7640f"
+ "86c26d1d6a0b104628b587114aa31d99f69cf95737932c0cb5333374dea07fac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.19",
+ "33cccb597de95cedb8b657fcd8f88886da04c757935314",
+ "5342f4684391cd74f5282db83141fff678f23a3ea652e0d427fb6ad976c5a710"
+ "a6379577718947ac727b4d58a0b0bd207ae373a8b99ac8e251eb02458a9edc39"
+ "52fb28426d18fda18a802bbf0a0b8b2cf25ca3a022f778c7f47fc530d0b7a5bc"
+ "846eea9180f2",
+ "8c4a63d0731e2e71eb4615189a968b3e4a242856b2090245238b6645978f1ee8"
+ "d79811062ebd2d1f3d523ae600e0e5a6e405c4e4b5a16e8dfb4924304b0d1ff4"
+ "d641bf987fc6d41d3eb7cdc53134d0069cdb5afef7f8f9cac0ee5230b6f88622"
+ "a84de52ad6f75047843706ca969742c58da77262ff1f128a664e51cd635e7115"
+ },{
+ "PKCS#1 v1.5 Encryption Example 2.20",
+ "19d6",
+ "eaacb578aeabf69d4eaeeb36d04cd8a22e8fd7a25f0443a11e4e08b3ffac1e05"
+ "421a876cca91318250befaffef9b2749dc402fad4fdb7c1b66aa5e089ff99f8b"
+ "300cdc46f48f5648c9408b5f8b3f5a12e65050dcbc0d5343d63d58081921652d"
+ "5bc82dd3d70e075d32d802c2976478fc9f0993dd0859c90e228e87",
+ "613bba5c190ad772e08c29076e2e9e5f12efc9292e3b5cee52c2697fb7b607dc"
+ "72e82578e8b753bacadf23b47725213db89f8873fa79b914a4b5161efd9e15cf"
+ "a8dd1effe89f8947a6f3826dc6bf53beca365b9381184562a79e21ca0e68ebf0"
+ "ab82ae762b28c14365152ae0f54f2e9d14439a846b383f5e2c55efa7008597b5"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "b93096d0261efe000b3d1704f5043160abd3eb566c61e53c76c401e2b65521bc"
+ "12d481215183e8f46c2ca8d00ada5dfd04dcf7cf36cc581105d99d2a7dd94b56"
+ "760a6564fee5e8aaeb0607e145196210a31b7ed8dd2af32d29d2bad6f15ffa5a"
+ "11dc735cc36219021ee8d1eeed34639b5a91ac6a92674e183970c59d5b196d4b",
+ "010001",
+ "0107ea61adeca5e9007c59134a7d38fc7af3103ad2c4a2bee39708befc83dc79"
+ "b70dc97592db6df70fb3c49c2535fcfd9fc2ce7b055392e3eeb3e79793cc1b60"
+ "153f4a0bff26be667bbcdbbf6e32afa6fd14837f3c79be44cb1c638ffa5c6b17"
+ "709a96e127030bb1116decfde52bb040842a94d2e674f11751ecb903ee104845",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 3.1",
+ "44e56aa77bd935ac59a9bd323783e12742",
+ "92eef619f04f52028f4cc3e5241f0aa0921b4d183c1f5bd68d86fbe9e7b7d0bb"
+ "104ed1cae07ac7d80bfd9c1ceff8dcda1dcc6930f4c55137346bfd68c19d8797"
+ "2f7f34cbae5663260feb79f760221cd67be066d5af0f073c0f2c439e8bcb7463"
+ "ede44c8b150ebaf3298726c3",
+ "1591d1ce0fad66d86fd42efdb31e9a028a3157fb0914b247eb3d22d76f9769b0"
+ "e19f6c064ca1b9890639ee6e37b709224d6b58ebb655ae4b69ed4cd75d812921"
+ "17c06930d42ac4d42ea73514218f49ea07ca97436709683d67a8e9e808da69a5"
+ "0b739c42eb0deb94a3498fc5450eb69ace23767661fedf34183a1b6f425dd6a0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.2",
+ "a75738291fad5413957fa3b9f3b2caac9f5a",
+ "3a191aaf45ed4c2589205d9cf6a30f07700e38be06256243018d23c684daece7"
+ "e867e39d76c6b6f03543fc15af81bf84f964eaf3a95a4b808628fd51553899f8"
+ "11c08c62609c514cfa1dbb78d5a5b33cc0b857fcb1eecc531b132634439059f5"
+ "5a733e146e1ca1eb5a97f4",
+ "70aaf724396c1ac50edbbfe8341b087ba0ffe287605a8c3a8ccf85ab2ed2fe22"
+ "159d62aa027476ebbf0770026d2d3b0c0d7734faaaa8d15e2ce51c85535c26b4"
+ "150ad6346e3bfd38db5dacf752e75d75314054d167a96d819f3438a7bec4467f"
+ "c560a694469485e8e78e47e4e8277ca7d3fd2ad94a30464c2457854725c61615"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.3",
+ "87312f787de0659750d602ac1102",
+ "a229e3e8ef1caa66caf0d8acd8d66b9e41cc771f26e20f12ecc6e2aa3845513d"
+ "d134f7c6e574f41b215d1d111756daf971ccf39ccdce781619d79720df918d33"
+ "9c826dc049b390917c17ba0fb1302fff110a14dd2384902741f912b26a1adbe0"
+ "ed1e8fd989710b403d27c4e018fb9b",
+ "033846d7664c8f926257c7fd3264484792ac7f9bc8758a7a16abb89fa3ccc4d1"
+ "3a1eed88af7323bc3c74e23fdab50381894c8626dfd0ac8589d46234d3c35f18"
+ "998179448431dc816fb63e55cf26d74a9d2a0932673cb4beb829cd7d49508848"
+ "c6d0c00d5c70f7fb476770e40319237c786bf4e26c48d2cfd96ee362bf292825"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.4",
+ "9a2bca75e32649777b9f13ec30fe16bb8ab46d6d5e0c6463a73d8c3663adabc7"
+ "23bde72a50765e7b300ef6b561dee88484880e4d612c",
+ "8bfae9222f75a06998ed6d9b149e8905cfc8db055a0e32acedf824d2f6b5b42b"
+ "3aeac6a7104e144d5e4834280e36445ab850f3a6de164c2c790fe7d9d7bc7f9b"
+ "dbe25217da2ded",
+ "6ec5f559c8a320d90d1eb5ef091c4d1255a24a6919410eb1df65a97b30cdd7fa"
+ "e18e6512a027e976704b4fa044374393d501e2ba46186200ef0dddf19c757758"
+ "e4679430bcd9fd119ea243b349dcf81c3432d31fba911ec6fc686eaadff6b9fd"
+ "f53aa4c85a49a22a051c5f1807f3083b1b3e6117b4ef1208de0a8001dc291c4e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.5",
+ "dfd63e6ec61e07275b8e37cc6369e1f3ec0bfc57a298b905ae5d0774e0f522e6"
+ "759c7d116f8e8efe69450fa7a8389f81",
+ "c422377b89864b0df38b4f9c15f98a059655e1c9b0c709635ca60649d8d2475e"
+ "e16cb127f6763912964e1984d6daad4d6abd04b04618b32e5325ba95eb5e76db"
+ "d46d9fb59df07a081e956cb073",
+ "9e06cd91a44a9adea6a79803d3e6bbab17db1062b6510bed40075566749544c0"
+ "3d7a78b137b0dc1e6626321fedafc20dcdbf7080f7f5bdd56744ce999f76705c"
+ "4f5e6fa15f46c5ae508090dbbc85fb86899c9578608dfd778aa4a79d3d736354"
+ "ccfbfa2c86f29a7a58453d757fd522f78408d9916b1bd0654bffe6e066baeb50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.6",
+ "5d91fbc1a7ba79939b89a2408cce8ed4bb2666ddfe09d91921a0aa69096a9569"
+ "92c21c",
+ "af07fea321eaa267af7f09806f9ea8b4cf135ed6f1432d51b28f92448709c2ee"
+ "8aed7f73b6282cbfd37f82dba8723e5e5e0a81f590f82e2fa84c3bc00c9b9f91"
+ "aa553b8b2c074bfecac2f55237f4cb70543aba499468cf6844c3",
+ "76050e2264220e10052c49b96cc8411e396a7a6e4aedb06b48fdb071de839b40"
+ "1cac0c468de8d1ed0b568ce690e8037af5def6b3d2dbc7b5f2fade356c26cffc"
+ "dd334033ea2c997792d930a72646125c0ee86a4dd843c824c7a52ac988c92e6c"
+ "69b580761c49881f29dd8a76da793f432e7d5dc731a25e5bb50258d027395fbd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.7",
+ "04edd83c65656a01",
+ "88f9a27197f9f257fa81c0e30590b73e9e11c76bc89e08536b4b64a2506aeb33"
+ "b45074730809a05c45b9bc95717369cf92c1bf986e53ba11238330fdc4e05ea1"
+ "07334ab31106aebd9c6c29e501a57d997c01bbc1010bd52f0538b95159f39132"
+ "0de6db23d8162cf146584c6e076c4eae862072eb5b",
+ "791b379148a83a034d312a82bbb37b111b40bcf6a337fde289b08e072e440319"
+ "73ff9d0c27f70d64a8eafc6eb5f8eb4e52e2c4197ecfa545ed63ae9a128379d3"
+ "f562a18fe3ad14052767f0541b90168185cbb78db60381c092bc23e1aa05b408"
+ "92f9a116e625cb148b560742cc1278c4d21a4a7d37f6982aee27f2a4c0c573d2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.8",
+ "3f7eea781b77d85fe371b3e9373e7b69217d3150a02d8958de",
+ "4999c64cbfa38524adcab66f64454d36fbfcb2986e1fa4753a0e03889ff06ee1"
+ "600eee23be53a97442b42c69621866632e4a6b6a1c710573261d71f38abf9e52"
+ "49ddc8e1b77b3f126ba08815c4fe63314f9b9e8e7a40c7fc72862520ed49d412"
+ "59ab2e0c",
+ "74fd8b9856d7576e0f1287e0e9085a3801e6b6774db733541debd39e72cfa829"
+ "1fec27018c9f5305a44ccb5a3cb591fed2e6a1d1d85caaa74dc23759d6665a45"
+ "70a637f3ab304b7661313b96713c7b7e49773133dd5d4ef9d29a1af712001502"
+ "8daab3df042c562620aa49d2c014414dfb1577d719a9588264712de3bf4a7679"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.9",
+ "a38508d9460c63f41581a8869a75824b14f5c650322999dc411350d0d4e8624f"
+ "f09ceb00d3bedc5d762a40c9398004",
+ "6a0a288a1e67430c666aebea44b582a90969cc01e90aae1053ce55eeb9879bcc"
+ "62253915e922f1096667bda02a14e70747b3593524c2848547d2114d1d0cdcb9"
+ "7eb4df455bbac9b0cc290839b73a",
+ "a67757808f5abdc81edb7f692f9fb852f1a1661c4a009805c44b216cd3b1322b"
+ "bb25d1458e31b0f07d65505759c4b4147f23cbee2af4a1a5938a068ce9c5323f"
+ "f53f4b392e1250d037b31e6281dcdfb96bf4bfeaa147f096c784c92f4ac57091"
+ "1228025029c3b523303fe8227e8b2cc0ef157014cb6731aac09bfe6ffa18eaf6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.10",
+ "f78405236a9eb557aacec6007dbc4c0ede78ed12b04c82888a82c213",
+ "86f0723b3168e2aeace9ec2e95fda6e6d6fc8d6294556566399d7311e799faa9"
+ "b1ee1f032ab2e534a91fbcd07c8a7d04a9b485f31e0723fd29eb2188069d9bbd"
+ "7629dc6e3fc89be604bcf00c52fa8e1d6c62555fd1f60cec02d4d961d828dabc"
+ "4a",
+ "6e8d2fb0b2eef82fc110cee0a9d3842f2a058a24407fa11ba905d1aa50e8cc12"
+ "decc073dbd08a8c70518ef25db96fda2411cca08728788956f73dfa120e0ea60"
+ "5bffc93b43a441a43d0eaa3ff073e6982eef5296390607e25a588a398255ba00"
+ "5a485e6e732e3a1920cd43a390fb66d5428dfd628974b8aff2f0602da578d625"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.11",
+ "561d27c1d3f6d5d1a643aa47e55d78eb00f32d42896a34e0c1d71bc3a5457c92"
+ "05bed13b984c5259",
+ "98176e1d67a2462f5dc1bfa6e0759542104ac14811d3187938250455c65e4aaa"
+ "7632bd2d1d752e1f34c53cab267676a78c10c998e773fd8ffe35c867c443bef7"
+ "9865aa2da2915a85c7026323693e454d8ab32a7715",
+ "0bc04783c692447a3de61f53b72f7aa410316dd509a6f49e3aba56ad1ff86ebe"
+ "9e6366e17e51450076bea371d4c689cd61495cd8fa29c0e87b6dbfa8e386c2e8"
+ "20e4c742a487e89b275a2186e23840be9c02527ba717e9e60b5bf417711df34d"
+ "7b8e2d12bceb859385fa001d4b4bffbbc0edefbd4002418468c566fdf6b83509"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.12",
+ "eb5f8c0dc9d901061b82aeff8d67d8bffc0c047ecc4aa346b23bdba62a87e9dc"
+ "770b11695fbf1902f24b66ceab",
+ "7482770f3cf57edb8140ebc33a028245ee0648520689a50e33f5f467f6d1e432"
+ "4e1c50c899e5ad2c46c97f8120d1c72239d6a82d8f8ebc80b973eea8c5456929"
+ "504514b4b15662844f295062f21ebd92",
+ "b8404354a381b7c2abe5f72825f3d315bdace6c3cfbd88b89768612005197c61"
+ "663883f2c2574f995ea6f94eb34f276862b33f58a8839223706be1c1ff472305"
+ "f11ba9562a0eb012f1aaf85c22e88f2fdfeaff8633d3cfeb5f764f4228920de3"
+ "0c6bde2cb4e8f03d90ed548f648500351a5f41df74ad65e8c3bee9505a7d70e1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.13",
+ "5a7f0eaebae49cf57c475a6da67943a7d3046e3f7c7d50b09a8098b544693968"
+ "93cfc0b2f08f6c2bff235051575e6e56",
+ "fb084886db3798d2b5bb35a3b1d3af4fdfc0456cbc797b9640d8c44a0e034e40"
+ "372b34fc7c1e8b66011b4ecdfaec6ee4cdc828cb1ab491274ac1e39f67587a55"
+ "476709b4023fc569cbe8b4fd4b",
+ "07784ecb8cc5ba02d207bab055c0e55d10a9b94270cca250ee75fa1b5ae190b3"
+ "3b9696eb2ec972b26a0e9423af16aa3789176276060a76400321117482963403"
+ "4f9712c9171017f2fb213f25c146c2651f89440ca536e533e305cc6b0113398f"
+ "61b463b073e1be05073e9d64bcaeea5444b820c6abf3465430ff4de4a8bc0e75"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.14",
+ "f91c71af5aeacae179e16e87c9023ba94d84d7516cec6c3989801fb3e7add064"
+ "bddf928b5000940bbde539d623379c",
+ "deb260258be2c853352157b06526b143ba133c4f49bf3df2c050ecb2c9ca3253"
+ "11b3c3e3d88df6c24a894eab63745b6253e3c46bca171a26a4f2fc0ab62b8a2e"
+ "63a018eb47018cab951f59f0203a",
+ "0dffff519710c9eadc533b108a4c2974fe531891a34107a67427935ba720cdc6"
+ "f6ee029a1b036861db1404c5864990541fa2421301a7b248cb11f365b6a4aa94"
+ "6f2231cbb14732b01aa4a60bcbe520ec6c3853a6958a93c5b68b85d4bc3d8415"
+ "ef8b1d4f63038f4d942ca6bc7a38251f15a4e33b189c250bcfbc03156e4f9211"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.15",
+ "0790c081f361c95b59d527d3cb50710e66e27259501025ed3f20f30c",
+ "fcfc2d56cb926d905db36e1e2eff1fbb75d653517f59e86f71bc4bc55726f088"
+ "b821624483b3e29ac21a49bd859134908e6c0ec1a0dc8079930144120d1f6bf9"
+ "3bc627b99969b2afe21a7de10d96f6ef43c567b5e238385cc11a5a2a13e17855"
+ "8b",
+ "7f0e6b342d6a135466be4173381ac04abaab7e14fdcf51018987e96967169aea"
+ "977803ebb3242ae9adb46ff51120934b39214631b03f5af5bdea1cacd328addc"
+ "d40a3a29966bf98bd7c8c6fd0f4e8b972e2da10c6cc55205867f3904ed60f5b5"
+ "bedf7c3b3c7dd5f387548f40056702ea720176dce206d413d7423f943fcdf639"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.16",
+ "93c41a1adda8f69360f41a58eca0b55ecb37a6a900fbc7dacd9ca399c23d3172"
+ "615377ac0cc6b0ed43bf597f21cd259d8f80887b159d96d66161d5589b95f1fe",
+ "991a2a7c061c23a8ebc9489abc1b4a64a5d4e838d9fcba4288c01fead66d59f4"
+ "9636e4a8d7524cb89d7adc7af3f61ae6b39b588fb77eb7022362ffd26b",
+ "7e54a432f525c52333abe3bb45487e039af94dd3efc35844dd8e835ee1006178"
+ "e24dcd19fc07667b4a34f3bd771d09a7e29f8ca17e88d029b90ddb5f2813be99"
+ "000d59f5432c466a84287577204bf7659739276998305747667fafd8029cdcbb"
+ "5918393c2cfce4d84a9220ea3e3819725336f25fee8e085debed3332d5ddf1ee"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.17",
+ "9e2a7b3774b11e62b6490b5651a0c18e092e9fab8b2284ae4643bec36b265e5b"
+ "a3c51ac385b2c73d220b2dc2e10b0d690f67945a0c42b3bd09d0a8a7",
+ "a18bfb74f6debcedcfb47c7d5dbf106e774d7ef6638ec3821869cd2ed62dd532"
+ "5f4e5733b8bfd5fafc43e4164e78d438994d85337d7f0d38f0ea3ba37f4f41b6"
+ "a7",
+ "18c88aee2536d942f7622a644fad6fecd33228c7aea0cada0e531f4ccbf1c1f2"
+ "69cc958629a43b9752fcaf2bf953ec9f7ef4bb0e62d128e0cf4babe92c6d9284"
+ "9e9838dd88e2b468bdcefc04a9e4cb55e2a518ca259f9e81a49f28df34761f9d"
+ "ea2e70595662626cf96ac05a7c8b103333e906e132639b65a766f4092c8ca078"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.18",
+ "0ac52d4001f25c2c9db91ce50bddf0d5919e19962e83b07cb79adb00436e1366"
+ "b0aa8f3fd1ee796b23c8bc560ccfa4bcbdb1f8404dd6f7551520d7d9e2",
+ "22ffdcfec6f06b1bbd1453977043a34eddf8594da022130914975542f2f00e98"
+ "f31e0dd0c48f7ee5f09d6a527121ad23371c6cd0e0790eb7308bbb0896dd590d",
+ "b26957c562294de1f39324b1cd803cfc39fcee2d3c9d1379f8a112079d694368"
+ "f55503c2094d988a8a5b5ac549be1cf55316045df5b6f633a4ef1e1f019ba1b5"
+ "42bf0a87fa3e5ca3f6b61cc8566128a0fa418b0825c90ec2f1ec74e587cd8057"
+ "d952967ac4521ccdbf6326f350930093826d2efa058ed64415374db3204885ca"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.19",
+ "a8003462f806b7f661fb664632",
+ "c743f4a6da03ab2de5a731cb88d8ca9b61c7319a5f8bf9d237877a05d0f368c3"
+ "608a052ac6ce13731795475542ea16a862913d0432f08bd8c8b6ff8195691fee"
+ "5ed142fb9eca9467524bd3b5fa5a4ac6143b0d38250ae621d439909cbe3a6b5c"
+ "01fbea2d7a3f1ae41d61fdd64764149f",
+ "b738e1c429f8fc0682faadc8ca87ed8f16df930faf43b1991aac71d88f264c0d"
+ "829ac03d23c25fc5f3e85dd302cb7b1533e68c2416c51a79bbcc7c29b07e2e0e"
+ "23c6f2df0d0781917eba1a5708628eed8a15b3b184af700d0dabb14df60b09ba"
+ "d2127df180f4d6f729658760d633c7775a7b596d09d903491f21096c34c3953b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 3.20",
+ "ef32",
+ "4399cb044a60076d18ccb34e8b078c818ea77f63b0a43abdecc5778193a8bbba"
+ "5d56d0fc4e82a211516bbdef44e7f4e7febbe1e1923c999a7e961cd6ee1c416a"
+ "8596e24b6383a469935f33d156fd5bcfdbd427460d486683061e4105f35b5e75"
+ "2320155c7f69ad8eb402cc1106e0289a9b4965823e7a51cfe4d26d",
+ "131b625e86e6cd1e08acf195d93cd3a0dc8ba9e2dcd6fc996be21724af1790b6"
+ "88d79d3ea9a95098cabbe8a5d48592e4746b0ed2af7caf89b7b6152e3824d915"
+ "89eeec3375c71a899748703acc1e8d1de471ea7528040b795f299e668cec9f5a"
+ "f3eb48f98c0d852067773e101fa24aeb6b404dafb42e7a63b04a66bd0e9f9c94"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "e9f25e48140b5dcf4699e3037fa834f0c78b16735ff79f6b18ae60b51848d306"
+ "99ec646d857f15770e2c7a0c0c900fb6040b5f34484e9cf5ceda23d5b250ef93"
+ "286f011e9a5bf9e542e5c9f442de5458e23e41d1d9cd9f0ce1cf2008d3ea4d80"
+ "32e854cffcdf5f698d1316e029c488fcbb2be29a4e7bfb8e6e81d342123ee75b",
+ "010001",
+ "45458868445327486049e1bfdff56113a8aa45100dab074fd16394ec1a9039b8"
+ "1b2cb581fe84e648b5f032854dd4fc69f361a0a39d0376138cd7e7c37784e2a2"
+ "f9d4f26684cc5cc9f512ba6215ebd232f9aa3da469db43da1c0646e75b33aac5"
+ "70081b5b2e96eab7546acf931785aa2fd1824cbe2c5f9bf56334ec1566d1cf45",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 4.1",
+ "ca24721c88e04774f415b4c46ca0fc26d5bb53aafb1992f6de785c763a",
+ "fc7f85c1386dc43c3a2846e4dae4d9548054459da23182f984079b071fdb5e6d"
+ "9d0fa0b22e3de636ee5b253a42f95eed4422956c70f48dfecf0e555b05157b15"
+ "6a55c8bc658cd3b5397fab78d711564e89c7e6248aa06ad105c40c31c4b1997d",
+ "e395ff1fa552fc2e79c4a53558df1400f8704eb36cf7cb051bab93150ac6396a"
+ "dd63669b04248b9db36a9c94f5198c6e5d9a17d474edb20345fd6a78b51de816"
+ "6e98cab5b6d16568b41a8e93e4838865d4bd9c51cde8dfbeeea5882b09dc70bc"
+ "9fe749b5d24bb7ca511db2c2b829a7c9146c774eb0bd7aafdc5c38d3d7cd5827"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.2",
+ "25c7bc4cb243ac1f0740869cd26ba826f355d477c4aa6cbe543addea844444f4"
+ "1c3592bb3da7d421",
+ "272be3fbcc7614996f1ac0e0a5e2690623bb0b6970fcde0b6f4558ee623426fa"
+ "60add6c5a8a10d4a3751501536fe8a45c542f627f4229fa12457c11331137205"
+ "552b014c91b1c4e09e459678340a74c285e26aefb9",
+ "7650d6f81aef5c0e320ec77fc89b7c3e6183850d10c98ad7e9feea47e38cfb37"
+ "a025db421fb6d005809e38bb3c51951da9d9433ba7efb17de7d8fe3e9b9ce455"
+ "5374ea663a1b5da4a092294ce966985655e2ddd20d7de3aa3537058cfd7e7a7b"
+ "97fcdd9853792ba83fcc89074a8d0f3cefdf985b9e78aebfb05967364f2411cd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.3",
+ "cf007ebd23da06971af79aa634d5d25505bd5229",
+ "9cf7237e28a86e418d664fe3be7ae30eeb955a3f7102b27d5fa096749c7fc206"
+ "4c880bf3d30eaa981fce3986a910feeae184c01025048ba6794896fccff74a59"
+ "42f962f3e36371f6b3551829434ad8d00a2c597cf6d451eace88868538a480f6"
+ "8ce68fc6856ebb57dc",
+ "b63252af2e8ea271e706fd683d0f8c10b3f4a345c4f5b6785ba9329f446243c6"
+ "f369e30ea8fb11084db97988e9c3874b34d6fd08717d9e810e9c224360346bec"
+ "cd3e0e53d10b1ed458e64f3fb092f48cb66ae03b64f6aa9c63bd279fae4c33f4"
+ "2a9d73bb39118eb87d2512b9d936a27ed2e449607dbf0e3e223a53952635599c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.4",
+ "efda79e9c336c234ff37b4f58fdbd31af3675b3d2b105eafbead4bbbfff54e68"
+ "6ab5",
+ "30c20943f1bfc42361d4d22f51a8d786cb2d0dd5ff7d705b3028601811293dbe"
+ "5d72c3559710ce0ae95d2f16b239a4ac8445537d488e3e6d2cf5b7a64c06c375"
+ "6e11606763633edbddbf26bee6511842d2752dcd88896cb8558a87",
+ "bb91b2f6f4331d64d0736a2ea60329aa16c2ed7a4d5ca8d784e6304ce4844c71"
+ "58f822d2af29c890977d75a935e43d93b5be10c1d44fa00ce28e75f527bd84a3"
+ "be5af5bee94567c55e15ee3e93426ad8d50f064c5793ca38c43a70c5f560740b"
+ "16eea16b7f13415f751b3fdb877a88293321f50fffa6f1249496c2b027a218ed"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.5",
+ "4a01fc13c1d86fe7b2fdc792f5280f875adc5ae99ff911d02c8c003d39bbee54"
+ "b851efa34b4131be520d8100ef62c25a4b517e9b",
+ "be6ba5d11df1bfcb2b846771b6c9dfc9334da86c4b7c25439318e8ba8e47492b"
+ "cd511bd4cae1677d312ca22a9457cc81d90e4d524ba2265f0fbca18e3c3f482d"
+ "caa788332239346d6f",
+ "16bfcfb42d28b9d16270cd138dc3ca6442956a41825ed0230b71091613333a9e"
+ "7c52ce8cc4b0bf29107941a0d72cc34afd0048bbf4c716c73aa9b0c78d37c193"
+ "719ebe03a9317453b553d4f5b385d141fc3b0ed19b96dc350dfd4d12e3dd03ff"
+ "1839d4782c6dfd5fdf5971f3ddb0e312a91606f31373020db3a76d04fd6d65d6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.6",
+ "7ab06e196922c0",
+ "de0d6033c1e96b5fd831214f30d81b8fd9a2693e5e8a36eaffd039e7473c28ee"
+ "43a3916c78c9a112958a94ce671ccc40d97ed4187a3fffa0dc129d88a8b8c496"
+ "6ea394a910896125f54dafbb3b17b9fa10c48220096490c6f75be25183e9984d"
+ "f5e4d7ebf9475d11ea39335ac72f93d333bd74221942",
+ "541823f905576da142e265d89045ab6620fd1a74c9533ada4bc7b43d95629a31"
+ "186f4e89892083d2549b0e638bdfc0d27e14ec18c45ca35861dfe612a3a1edaa"
+ "fc72fb4681a99ea6e648be8962f1561e750d1449f23f430af9307225544d8a8b"
+ "8965af5dd18cb78953ce6d16d85eb211af0c6468a2af9f72e78661b0fcaa4815"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.7",
+ "9ada9c10b8ae22",
+ "cc2343724ac50ee54708fc5fd03f09a1cc1222a44bcd4403877c6bde86bf43e4"
+ "2c1084f6efff20fac0acc31eca17c738d46868736552fd2f7e93b8222561054e"
+ "6dadc315604eaf8f77f05dd8583a93bf03cb9cc2139bc419bb10e9b201b2a7e1"
+ "8b03790cc83ed605d6d5663305347139c75e1ae2a56a",
+ "9f54d0dea05a5d0072235bc46793cfc47b006daaac0241c7e66d333e23c3cf97"
+ "63b61d9eeaddd83f5d7f0aa97d16c7699255cf7e4872b6a0079562d2607d6440"
+ "d7ed37c6713ce96643a441f8395564d26adea5823a4942da4ab8e47bed5881b9"
+ "d184057957df6539e436da35e30a253af12d541d4b0ef83c5ef3c135ab95949a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.8",
+ "d8126f4a8878978293117651b30e7922d14acf",
+ "adf9b0a9152f0e6ec6f4395971ad403f02e7fa98f815560afaffa7cad5b4474b"
+ "6ece65edabe27ec24a0aa473ed75a61f5c2490a536b1a4df7b03417737c534e1"
+ "d45bf72694386bee820c48dbd18317bd617c04b6a417e30eed79588dc23fd4db"
+ "a13744b4b2aa5af80a8a",
+ "3b2b85edfcd7c7c27bdedee1c28ab6187abf1c96d945300792cf8af197c2f9a3"
+ "91b48b8332cfde7e4c7dc34c4230295692cefda5efb25735492b9ff784c7bae7"
+ "3511c618e3aa7bc87bc313f26709a8ea4ad73a349ab9e5ad826c96ad0eca97e3"
+ "13286bccbf8e33c91f036839b9948b4eb0c38e213ef47f77661a27f8cfe49903"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.9",
+ "f5df01afe6a922518b3f4b80cd4fca73b97bab61716e27d251bd465f4b35a1a2"
+ "32e2da00901c294bf22350ce490d099f642b5375612db63ba1f2",
+ "6bf2810db8fb269398412dbb88060282d45fbe9627337e5434261a5dbc193ad6"
+ "18c11f7bdec1de2505f86037fc1851bf6fb49d2360627347499efc98e29205da"
+ "906d32",
+ "4012fcc5cfb978def88fb8f8174aa5b4a30775ac4559f0b2f3d3b4389b828a79"
+ "d1402510c9a0337d489d1182ab31c838ac7c80b748609a2aa537da7acc3a4a7a"
+ "31d2ad252bfd59280b3d1813a26f93c59ee8c5ee688718f4278393fece323a9d"
+ "ff833755e89ac8ee1fa2904bf24cdf4f01e6eaedb6a8ef01f407bef3309f0339"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.10",
+ "a3823faf",
+ "94f670fd82f6913275eea4c67116caaabd33578cf84d22636438a6fd7ecfeefc"
+ "0b187decf793891c6e4cfc52b567d872bffbee0a67472a1a48c0f1ba598ad825"
+ "8901c56a5592f141147e81339d747e0632def00d3dbee95c4e4321cc25b53114"
+ "47a302c534929cf7e534f9ae67f41e01e22a3d7ce41b3b3135",
+ "7b602542b64f0a1e0ec2aa01cbed377e331ea3ff86f356fb7a5883764be4cbf7"
+ "d0754c5829643136f2572336a23f15411d838514a1438724ad7409e8ec8fe263"
+ "41aeea5668345d0d823fb5c21df459e8bf7c15b80b072e5f8a8465a44aa9d09d"
+ "825c0315a0ecd2d649702b109be8fe35eb22843a20e7fd874f1c6b46a80b68df"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.11",
+ "75b9a4a0bb2d4643e478f654f2cc1a8c1bb46719760d4541a8a733f33b713d32"
+ "c60bfd35f16174834847e8812cbd7f06ce7289f372c58230f2b001459b5d",
+ "49a73deb93e3f1beaaad3a199a70569e099afacaf7a75fc4ce648fa82eaf2a0f"
+ "e411d264fe45f74525c91f3c751017f80a02babff35799626f2b8ddb9f3691",
+ "e5aee70de862723c5173dffbf6926c3d3316d5909cf5a1d663e680ab2bb576e3"
+ "5b93fd432743a18e8db4faa332f44668a3d19e5e695732f84bbd86d0dded7665"
+ "b70b97632eabe2364cafef7b74dcd1bfbd625e2bbbf6654cc0266181ac0a757c"
+ "3fbabd430ae86371eb56af610f77cf2fff6e248f8c579160b91dcecc0d202b50"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.12",
+ "1506eb3491785aa72106bf6c85d01002046d1c16d435dd4e7c4b7e8e90dddf16"
+ "332f94f4b835d0e4ad55d83a81b35c54b679d3cf",
+ "f66e6a8475844086e28477229746801d4350d9ad0768f3c3d8faa8107d95fb20"
+ "5e4ba8c64b738e54e5ac0dfeab996d61125c2679807259bc9e47d8bdd2c04095"
+ "05448bbf872bf6647a",
+ "d1fa3952cc6145ff771b6c5a68275bbc22d00392036617375f0c2bec3e288583"
+ "ecfdc6df6a828de37f77c556a8cbc4d44336e8d2e30587e331587317e97b05a3"
+ "fd78025b2d496b3bbeeb6c725d9ea561a732288233d68b79497fb0b6fee0a6b6"
+ "8ac313661b4b654739f918f6fd3bffc17c1df41f014495d55f9590147b82d15d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.13",
+ "9e3e",
+ "9b3ddf17cd74e76c69b5ca3a010a0e0fbd1705d69c3074353be7d3c0c205f099"
+ "c7a810b7a1ade09f5a036bb769eff53a53d4c6f87152922d9a7b86edeba37237"
+ "d7f1734d9d9739383f4880af3ad68887e0fe7c87a174fb3238b1e51ead2a8434"
+ "40c2b27f22dda4228dce70f91c98d471a8744d2765557958810244",
+ "42126b492a1e7cc03395b2ac7033cf6a6736b12e76825a173b9e011ae8bfed44"
+ "fecb8d9f58cce19911fe42d455e249200932a9b68fe2e419bc639c1178d11ffb"
+ "dbd9955d459f5ecfe09020098e297b8e91485e94bf11e7bf77edf5a27011c82b"
+ "927365a12c9c77c7e49bb7fe2f613339de3f512087795386ca585a7024782790"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.14",
+ "70aa78a4d37f74c181aa27407f2f9fe663a91b16be9bea6fc612887f",
+ "d0fd16c0f0d7909a3886170811e44f24fadf94ff17039a5684a09b24e1933fa0"
+ "c47151635d757b73c23ff39101cbe2529a63a7f3a0195b6e47510711de171a16"
+ "56c9eab3cf82d1c65226b58fd0fe58ec3196247f34b1a0552702dc037512c681"
+ "04",
+ "9536d47e1d687f1f24996cb46ce946ae54d4a149b34b5bc34443a201518387f4"
+ "b6381837cb7e4b0a4475137042f1448c1ea41515ef31c2fcbf62e7e95867b674"
+ "ac230aed9c7d8d61c52752b2fc2a0bbafc77b31c514930de9823b438b6faaa40"
+ "d25531033c66483fa0023af21da64fcc8bb8c5d52d3f6c4380f1d608d8c0118f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.15",
+ "0116a4617773b6ddb219161c4fd071937bbb0715cc627c17b8e75280d99cdd41"
+ "6ea5cdfa0906b9af0a20cd477fdcad1415a19a9d1b96fdc3c0edb9",
+ "86b158609bfa08a8ede4ef3f23e12eb50d245574264d764d871267db8a9524ea"
+ "3fa2e3845ffc291bda989989bf715aa2b08c49798a819f6858d9fa35f94df3c7"
+ "e086",
+ "74a3df385d20877bca9dbcebca2e532c6abe9562d6817be16e118a60f4ab0a1a"
+ "c0a8466653a8f8170e35fce14b449cd59f558e020a898894bd2a717558e6650f"
+ "3a128570d8c169a7746663c1d7ef62145f4b75c5feb6386fdb853394c659a91a"
+ "a2aae03bef9113dd4928ff28b380927ad1ba4e8a37edd172efe8e9eabb614d83"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.16",
+ "15c5fcc7547d63761f6af1f26eed9be8134f9f92127e76b03a33a97b9be3f78b"
+ "2e22fc7c850699a15c0e0ecebe2a71805f024b9388a3bdb2b360d69c5c0c46",
+ "5b4f17a9de91737a7fe854e8a176be5a0a16fc1042cb870cc01892fcd38ea75b"
+ "073c0ffa014f96a358e3aa5e73eaf8a91fce75470bde64e87ab891ba3bf2",
+ "7362d7398d0c251f835817e47937a9255836ca0230457ff608b078d50931a880"
+ "33ea7650811265f8e268b53315d8438e52a6a4b1b3895d30c3dae11a3b8ea8c3"
+ "0f05e9d71def46d4511192a10f54218d3936cb17983a1e7aff18188939b94692"
+ "7649b0fc4f7bbfcbfc14e1c0eca07d00c903db78169c50ef0a38f1da19ae4459"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.17",
+ "7cad18f175138742285e9035d13ad41fc3a85210e1544e24dea3fcfe66",
+ "9a06ca10fcc6610e77dff90dd176f82e3f96e4a9d7ab872c748ed422f34b3348"
+ "619440f0aaa22a669851dac8894a8efa34ea2c2da5e95869e0adc005a49ba458"
+ "18caa474115c3449966a85c418fcaa8f45630efe0b1b4d3d69be1bc0068aa799",
+ "1efad41446b91fdadd8b80619f68273668b7585fd91f3449ec85c242d0849e4a"
+ "53a5977b61aa40d12cc485ec7e4ff20f988691cb9d73af46ea376afc69ba2233"
+ "86e9f15d032697da75e2f952be2af062e8246cf749b89c4cbcd64e23f882bb55"
+ "3c3ce305203622b5a7397735a634aab0d17ef9b5559ddd34f4872b56e7986efc"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.18",
+ "fd98c38be3193070b5c4334b11c25b334a44",
+ "f357911103e987d1a9f15cc2e52f42390e0faa5002c4f17d40a4af50f31a2317"
+ "50e7af61d9afdf9caa3861a20dc721895861fb118e088d3218e6fb3556b162d6"
+ "bd67911dbc94219842658272a5d49bf5abb4a0879495c5e6e686285929a55a36"
+ "8f524c14a40b0c61380d0e",
+ "deae183b56c3fb3841ea574234acd30aff00d0051f57803758a4714abcbedcda"
+ "8bd1a48a980153df896b1376aa4b45958013d619be7eaff6c1a675e292efc3f4"
+ "393ddbdeab47e890a78cef69002449578748906c1021b891b943d818d3a61e67"
+ "a315612d4cb1cf197ce5dfabefdaeb590b8e8c73685e747e59a395c845c5d0c3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.19",
+ "9653d79469f05d401965a95ce874fa225ec47974e8d06841c13b4785e00d547f"
+ "9d3144c3879e6ccdaf787aefc2f8452a4a3c884e38ee",
+ "855d6d1512e543a45d3a9aa9685d5dfda70479ba39526364141bb63627458985"
+ "71200122f4bc82c6224345c69d3ef542f123bde3015b60c4c0ffb98d630131ae"
+ "e81fe4a0b01538",
+ "69ca62e29a5bdb4b04e24016212c259140a60cfa81eb6693bffafc9f600dce10"
+ "822a007b6ade93facda1b2b165b557760f0a675ac9bcb206b964fb90cf6a2cf9"
+ "9f186b36d2eb991d8253a0754f9cc2d72de549abae9094f5a86ce1db494dbb6e"
+ "516286715b3dd40559b3107b9524b729ac654cfb40f9ab35d034e027197cbc36"
+ },{
+ "PKCS#1 v1.5 Encryption Example 4.20",
+ "0bdf3fce8e487db22d0760ab711586ca8e459c394ff8b1a1867067a9315199a8"
+ "012474b0f90dcc87cb",
+ "c9b78dce9dfd7f0404ff982e06b59650bafe31ea19bc1f2e1f3989f4cefce46f"
+ "c652423db3c99d92a8fb58f3ee393d555b7684889a4bf815a13e3b9bf2437140"
+ "66b9075890675047f17e935bdcf0e66fcfe39bcf",
+ "43ad3e625fb17215578bef2f465faa72ae694383369ff7aa151201a3f259c8d8"
+ "ce8c16bd25522149f666e8d692a0795ea71569d2881f9707085d3f59bdfa2873"
+ "66d7f5a3f76ea5dc109fcb03302da0b78699713e0d3009584f97176c1b9ba63e"
+ "80cfa8fd4c013d74b5fade8472d52c11e2e93681ba19d353d31ce6fa3c0ab60d"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ab29d49cdc925c69cae75292fc03620373c6fb36d3c249dd5bb50f881a4c9389"
+ "afe73e8c56b8d667a5eaf2b5714adaf4caa006a49ac4bd4b91d545cf3c10009d"
+ "318a9de0f3bbd8384e8c7e96ca1595e32a7041d168caa73443b885bf7f614ae1"
+ "212e3b5adda29dfad501b8b1a81c3f48a456e133ad52da2abce5d6e782f275c9",
+ "010001",
+ "077bb273323486ec4c25ed6706341aa8a67aec58430d533fe586c6b94f570a3b"
+ "4290c45c0bdd94681f29a4b7588eea8039cca1c5b80b8270279dd0a9c5093911"
+ "93e3d5c25c1075c4a1d3dc3274066dab817fb51b16bc267ed9a9980ffbc09285"
+ "d97f112f152695e6e09cae72bb55066cb9dbd098a75ceb47b46272005c6bd215",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 5.1",
+ "5dc9f8b12dc812a09aa4b06dfcb57e1d2e8d1c7d2c076b25d5c18edbc046bd63"
+ "c7ca4a599f18de26f3be738cc28d16672c006e4d9c",
+ "43d605a5740a970b323727af352a1bd48de69d9505e22c2fad030c3b84b6dea2"
+ "d22f916406a7693cf506c2d251886f02203e3f7655a30a6837af8a8cbec7b5c9"
+ "2fc04c8c18dfe9d3",
+ "215a35f4c0435b07ed5d2c4b6865bc281cea7050cfea7a7e86e03f8acb28b58d"
+ "bee65458919ceaa5a33edd98201ea6e7632d7622d5a51d35a35fede86ef203ee"
+ "f6eb3475ec8f19e69c0ed52c05dd7d59e353f52b6710af4026655504107ddb86"
+ "f957e6c06ba67b1f4fc9f121e15f82736709d2de8d77432df08dccd2a0cc7704"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.2",
+ "d77407d8f69f80dc08eba5f426282de7",
+ "b829c789be381cd59de21489dba141e0bd1fa8a3c3826d59c6d110e7df7242ba"
+ "98c47a4392c7f2ac1c6e9dae22b9eb74a76436088bd0ba6e1991e19e3af79cf3"
+ "f7defb6a1161802534ba0e7ed16534938872eca677058ac73467d49ed1125b50"
+ "dfe5d6d65a5d245399b6bf1bf1",
+ "2d4806cfafe4af36bd02f62d6a43b00b416f708e9685b17ac8e3a4d8c2918093"
+ "05769d7898f6fc85917ba2fd8e589ff7a8bb84bb7c12202ed279e06409a5c0a7"
+ "d324bc46ae4f9282c9023d3dfb3a7915defc164b3f08266acf1241f826249815"
+ "07414e562978351dc8b7a79ef531402101a8d3d3eaa3539bbf62aad99a3bb11e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.3",
+ "238a",
+ "a5881acff3529f251b1b9c619ce9f9df91e0a03dd889163646871a627207eef1"
+ "47680c32f450a776e19f54ec055dc68b04bd4d89376df3eafa6fcaf60eb83184"
+ "3910b625b64f25d9299afc306a23765380455194b75dc0135d27c3b7d72df908"
+ "775c7e90befc0c5adf74a169ed5868f3d634327a05781892544543",
+ "7710eea8657dfd1565166562df0e2e840ec3e3dedc0b802bb0213e47a5ce97f4"
+ "b85ba9ba141977363d8f54b06d578d5b2a96e969cfa915df219f002a85d03257"
+ "047b3116a1c4ddaf791d93982d1b9ffa243186e9e2b19ef0741ce98de2a4a158"
+ "6e5012c481de23a0eff882fd623838d2011f4f63738affd7efb8c50f46a6c20e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.4",
+ "25a27eb1b21f10cf9d571c3305610b97f0daee39905c6594bfbf452a9a00d9e8"
+ "2b",
+ "2504618011c673db3c412279dc8ad165ab7b6473ae195e8d6d41214918198b34"
+ "51a6508d6138cedc518d8012ba0ec79b386af8fa40b03478bbf2ba065e582d61"
+ "95ccbe158f11781eaeb1b1720b72d9b52127deb9551711e887dbd0b8",
+ "3572bdea2305e1785c754de744c4fa3fa2cb757160e5cb39a31497e1485bbd7c"
+ "0899c53585b2bbbbd99081b416efc68578db78e0ecd08da7a3953e386bb25c12"
+ "bbb87c78944283a8c80187b4508dabbc7697f43a8ae78a33febb15f3cd581c80"
+ "d49b971bcbd48e44142f58c2c91adb1ae145aa9a83b3c5815aa1a8ff8dd231fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.5",
+ "59cf0b6b50ea",
+ "2bf19160df6988935bd246106b8909dd7bb3e51690df84d76e4d31ac82104456"
+ "346b4c3c9ba7b5e9e68ee2086c8473c68302e2599abf6b31ceb3f781ad6b5689"
+ "86f21cd6d755328fb83afd5548501d070ac2dd8f5cdfb62cef545e815fe382bc"
+ "0c67b676e5456ebb9ab67df47740c6a43de3f9a2477a9b",
+ "2ed591fd4b357e94f481ba84ff4ebe7ae431054e5cd98a99589648e616cd68e0"
+ "d4724fa8a6c599686bfee1747ad077dbedad45f1244d7f8e00da3a3a06d23132"
+ "d3171d744ef14e1e97cdda109bd2e556a5fc7bbc609a7ff24cfabef4b56cbbb7"
+ "0e050653b69848d7113075a5debe7a468215f8dc08e7ef84fd55778cd5b596e5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.6",
+ "e94452f50a5edbe67573ab22309fa21babc6d22520e6e83bf72e7afa6d71e202"
+ "96daeaf54a60c8036304879a2131d178780e348ee0120b997c",
+ "c530443a16efd8d6d72ab4443f8db24491de99d5aabe5188b3f61dc0483b7ee0"
+ "0b1c13259b8ae2409f1ae62d9930c11a4ddef3e83582938893f9ac668f79c64c"
+ "7f5d796d",
+ "0eee90c70818221ae2704bbe38d68f8e154c6ee7ade53e2a1f4d1dbaac98c575"
+ "91ebb6c638bcb68e181435b70001bad180192bfda05732c05e7fb5af22aa89d2"
+ "a8ff80cf9f0862f04c05caca3d2a3a5b0779946c6ddfa04cd79fa164d602f1b7"
+ "de5c95be85e9608467e25c29d035c4660906269f6dc00a472b0446ea56e72a59"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.7",
+ "1cbfa0e7b1a10c13d75077b1cbd80310cd2410340d5f537293464a6781a9cc30"
+ "2cb5380ed9267b3eb23cdb13",
+ "d36b7e1799059d1ed1347b0bf8247c6be5187d8f15219e3cb66ec62e1ac41ff7"
+ "ed357ed7ca0384e31d39948561fc16cbd96b7e704279e572bf564e06c3a3401a"
+ "2714dd51d7215beba1c66154f60dd0cd4d",
+ "9c03dc0133a6e6aaba92059bdf5a6cc1b144b90d2a94a48e7b3cb90b0bb6f624"
+ "c7b1d172331e4323d08d2e8e099532dcb3b2a87ca420749fc6345c0d86e9abca"
+ "71af09a0929edeeede83e72244203b2bf45ceb187e9db3c7d3ad05b23b59624c"
+ "246696cfc75806391402e444e397496988e1e1f42c6aded30cdc937937f30054"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.8",
+ "e172a6b8b496f077738b74f6d8b292dda607f2adbfb372be37ee000888bea31f"
+ "99cba1cf3932e4be3717c9e168901a32d1b820be4fb0137527a2481877fe01ee",
+ "840ce13bbc9617dc9f3f26b147301a6f46300d7781a5d981162f869287371f1d"
+ "5958764fb00b055370ec711bba5283fcb00b83bc02175ea1017bcc8353",
+ "993e396fb57b2ea6a1a3fced9a69d361cbb6265b26503c175f84c61a41ea3e1c"
+ "e4fbb62e01d6420e22fef1d9e28a5883e2eac82e05f358ea75f77da4897b6b64"
+ "9aa47428394193ddec648c3a7fb81cfcf4b51ce3ebba78aedca7bb917b35b3e2"
+ "2aeb201cea96592e50e0d2841e7d2ce0d69ff3039dc01e964a977a017683b387"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.9",
+ "c8f0ea23e06611e4fd27b61db7920c55f3c0a222128838e4cdb062e176b21fc2"
+ "3253558c5d40de2dfd620fb7cdf1399c2af8fc77ca3335",
+ "164d77b5d26ae6d7abe7caed625d87c211cc509ad0172c20833d8f98cae38a2c"
+ "370ef21d4096da841dbeee948ec63403cabd4a5f71ace49364aa7de20f32c988"
+ "337a115f8346",
+ "7a8f15eef510ade8d5c317f9064ad7dae6c93e7cf156a73722023258f8b57447"
+ "34700034a3de6f137af6e90046d86e9b90590fa5a650cef4fdb4d3360233af86"
+ "f4a7a23c243d1951c666b673c33c7dec4f51ace34b805c0a9e67e209cc7f9ed6"
+ "9b8f5eb5c553e0f15c10304bf56d7be171f31cce88f37d1fb4a2a00418897576"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.10",
+ "19db242205c03d7fa9935d9e04fa6ecf38a51ea998ac8e4baca6cdfd6a0ace1d"
+ "f367e73d23c240af76b62e9fe9215fe943",
+ "be495205556956fae2a22ea70ce102de066c9e58959606217484a5b15036ffa1"
+ "d461239dd47b4f381cea71516e2db0fc369d72b440696512a97288f06fc0bceb"
+ "968286e995e02d218d9c2662",
+ "5512b3999b30c9c1440e5975931d55f21e9eb422b62dafcdab5d5003a75eb124"
+ "819986361913361dfc46ac29aaba8e1aa02e1ba44467162d20f63ad170fe0d87"
+ "a53d93c64e026b12be6bc2b8eb0e57c039eb60f32c4b527035f703a7a8374bd7"
+ "faa7b5404a3c5aadb792e25ff92876b23dd3a7422c45266c6d986eec5334b9ba"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.11",
+ "49a761f8c18ef92362d6abb24c07fc728255842453694e17605899f437b31ac9"
+ "8db516",
+ "d8cd85edfa0a84d076a9f8b2f93daaeba9ae374381ea4f8ceabc14f62a4ed763"
+ "8c1e396757de3ae2b7efa3a17c9a5586da84a5e50ecded61087fa6f0ce938287"
+ "998ac1b9bc3321a7ed160d286704e0526ece7b30b46814649fec",
+ "9b478268406212ca0530f431bdb26372615084ca488da43451d25a22b35ac6fc"
+ "61e37074a5c22bc1c701db1932b8c557b8487cea566050e48ad6e0376f8db419"
+ "8c4d27db2e6b28c25aed837ef47742d5eb8eb1d8b432c9d573cd4b86fdf32c52"
+ "a3d0f6cf92cf3cd9519677a58b1d1d994fc1c9057ac106e816045926b45b00e5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.12",
+ "84e828f715f228a60265",
+ "f7f275a853d4e126d7d0c38ef703f3fbda7a9520788d7a81a31b0530d43fe6c9"
+ "4b1b1bb10851209db26ac4b888aeceea7713824c2938b4c6431b2b03c693ab7b"
+ "54631541546ac40394798548fbba95882d91a17c27e7dd53026c96791ee55f24"
+ "7d7f898feab3709a132a782666a14d0df1a84e",
+ "4e3fe96e8f96e5b3c611cadb96ed51042098ecc547be7b88f8dea765ae14e835"
+ "0cfe39dcb1c1d6e4179ca404d5384d87b0665075eed7da7aaf71008e2467d70b"
+ "fff623b4594b6dfff90e3d8485f94189486ca0ca9e722b2a777e25b582f7ad4e"
+ "c5103ad767859ac59a1b8c5c1971301748fcc264f6c929364a8d9af42255c0f6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.13",
+ "c4797e8a6f269bf25d4cb4ec3fa46f8f11e6b369fbdaec1e51978358d46f3cf3"
+ "b842917d967aa9d30b183453937a682656b27b",
+ "177742197f0411443bd87e28ea88d54b4f2c7ab1dcaed81a56f8d78791124454"
+ "028504d322e1de346047a493933e87628ce08b06c017082dccd38b48946514ea"
+ "377c2dfc752adc24fb57",
+ "7984c3bad86a547990e0475a484f8dba5d4dceb0d3e3fce071d6f87176b7cbe6"
+ "f8112d81d7cdaad77ed0d5788e65f8bf5f0c2ad0df07ccdf54b2dacefc19ba65"
+ "201ccfd361d186b7d9e269aa1e6ad2c72bd23f58084fdbc3bc60e17a33e3c55a"
+ "95eb0c38a081bc0d3981db26a7212d6f691b336dac46b64ae22538a7b0087f25"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.14",
+ "a5e9deb1c20f982d5b7d4b87d799461f053d919e",
+ "59759cf5f838d952493d0f4281e3ea0fe216971c0a2e2454b96c8a11b4c69127"
+ "159024db6ec5c33640d120295899f6666c9417b202a86c26efd7c6134c92fd86"
+ "b8323d174a62534881382d7c6c9e1b8c1e95daf210c3e9ba43e58879f34f2fa7"
+ "1ef6ae4b68d64147be",
+ "70ac102d071e3d902281836216e081290bb5dfcd5668d11daefa0ab064599d0f"
+ "914b472961375bbf5f2a666fae0f6a25bafd44f665c17c144dc4d4cc0a5d5ba5"
+ "5c47a4cde959b32baa5232a07fbf9378c9c53ca2b37781c93a1cc8d6529478a1"
+ "c673034dda7ff33560786a464f5b4a559c626ae295bc91d0eed9375f49e3e4aa"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.15",
+ "739fa76dbd127303b7abf93e1d7ba729755d6c811b5e93355e0c011f74464c7d"
+ "b479193c3fb7380a62a0c006a2d1dc49a766af63fba4527cd157506d62c21a",
+ "a0b4daff3e26cebb3e4e3a43db36c466fb8ce605b25af4c9da744b62d41f9e62"
+ "c2285c390d60d18e3d7e675b4ac3196724451946bc1ccf2a9b562c4533c9",
+ "2b798091b3a391533d62dc0e417ba6deda005bfc30ab7dc82e8f9bcc7417bcb0"
+ "04348c6d00e537d2722b843861489245ab0d51f211447dac33a3f9dd6f3ca66b"
+ "bfa0d1adf98bc9099515926976b9258aab63204ad89165c87bbefd8d988534b3"
+ "7407df7d43ad391eed99824728efc3a533b789b47e8aa7121617474f3325c51a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.16",
+ "5a44b547bda19ecca1dc7bc04550205f66c5de0acb",
+ "2f5485d25fe5ce40ae62a112976cb4a539b74d96ef8be873325e204bb3f86607"
+ "a16a2c2ab50f697809ed03017270ef20a102c43a2c4c3be6ab7a8ae2dcb56984"
+ "d5e065524593eb7070834ce553f1756920bbcbbe4fb26d35d4adcb59df524635"
+ "6ff12e7aa9ee6def",
+ "62d1489a403a90faac677abc174aa7243bc751a964695f6c32b39de018fe4643"
+ "4420ea7659be2c410bc56c4e3e7a1b1677fdf4adfb2324f041edd5790c4cdfab"
+ "3655e07e41fe9d73292151b0dd5b96fc84a6b20f6f3bc0f60eaea8d82917b210"
+ "83055940fc02ee3e17c378bd4d8506d08ec45f33de5780f01bd318a9a16787ad"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.17",
+ "16802d803c",
+ "02f0e762c33917bf6a4df11fa28473547a5ab0767dd3a61a8d05cc1e6f98345a"
+ "f1a00e42f62bd8eccacbd37f4ccb809e9e055f73d3375a6041d9782ccd85d59d"
+ "14f43e5c9410257b906e41cc8b973547d0622bd21db29a9138d3b1bede38ce5c"
+ "94c4e1d2a0a8400b45bacd4269797c385aa3066e65807299",
+ "753b9cee70d4181f95638780db7a04f9b12ea38e5daee4f2894c02673a53f485"
+ "30746ff2858b787efcb42d45e531bea1c8dae94877153b956ac7b28746ee21c6"
+ "31bf9a3ba79d2ba81321b79603b1d01a4e909ed5a27cbf27c957783d3f7950e0"
+ "1dd8f447f10eced36f2d193586f5cc17fb622a05faa1fb5cd2aa064c0867b1ca"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.18",
+ "d6d0f60385979ca506fc833421bcd22da6a06a8f370a7f02fef47c1cb2199f26"
+ "45c75490fbf789ad524704da8a2766c6",
+ "a03c05672efe23b44b26c793e7053a77048ba2dbb4b53ae9751854e7add7d67c"
+ "12cbd16c0b1934d2c23e77cdcc89ce1d45c761158aa8613171a73901ac1f61c6"
+ "5705533d3e639b57a248929179",
+ "0078dc48a66158992aaa68fc3ccc628f92a708d0b1d43837208d534bc3f9be1c"
+ "1412ed0f9f7bef49430dc9e998f752e0747768b4ae38144696c003d6d25ea1a6"
+ "ca6aec924a9f4d9b575a8f136bba29bf31c13b7050bd55d1000d433daa6cf10b"
+ "49116c8063107fd3a5bdf61545c5d863f6a78881786cc8dc376d36c911368225"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.19",
+ "b0381cac04f3101504968f26d6554745383bd171d36156dd3680b3db6fad7f77"
+ "1f7d",
+ "cc548a6777cde953c15a71fc497c0c3617b1bb056b03288d9a548b693bb4308b"
+ "67c1dac38bb9b8c9cc896ac244a9e30d132430f4ceae5790343dbce38d056f27"
+ "b86bdd9d32a8171f3b3cc2fd142265ac9a68dc353627339cd88303",
+ "456f7c3e3be85ff7bdd6b5b250bfb81cd6fbb186d25e0c1c5259d6788793c541"
+ "edacb4ecdedb8a89290134a606f46a81991c13b120e33056bc0fc7e97b342d0f"
+ "20051813dde45e0b596a7dcd6904903b8fc076a6e24b3ad8013416d9fd184830"
+ "554ad54d5548bcaddaf5920a024955887825dd371ae4ef90069a4f311c5a1729"
+ },{
+ "PKCS#1 v1.5 Encryption Example 5.20",
+ "e5",
+ "fe0bc7acb56ce14b4e2f55fba0e2b17154907be94ce485c6984d61f67c04a740"
+ "a28d6094aeae33b3ea0d58183e1ec7f601b2ab820fb8a7ffac0b4f960e1b4acb"
+ "e57cdc35b225c497fcaca03019a295b3e66da96f5379ccd1da44479a4f2135e1"
+ "063d71a282c1e66fdbd5d953f5718c2539d00ce49b451820454d2d49",
+ "5c533677a1dcb36395da9a6d3477bfbf71512c6a933d041ca31344e1cbe1e555"
+ "88a1146e3dec4610efac41b5f80266026652b3d7aa594274d9d920d33aa0ad9b"
+ "4ec59aa880712a1d1c368a457f35c74388b042f2498e9f4bd45a26f321dd9eb3"
+ "33ef80afe3af9f729ca18f42c88a7173858c542066f8a252ccf0feafe6b5a924"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ddcad6a38b3704cbe06bb1b51d1162584978a4291fb673b4ea30ed8b51a4bf26"
+ "1dc9f0f469ce9988a089f084366464a180cfd7171069a6f636d75f23401b30cf"
+ "43adcf870ecd24582f4da295229151ddcfc7c99186b245885cb63196c4a5726f"
+ "207ee360af3ad8c48385a4e0841d7d851d54545de767d8f999dc17eb0c571189",
+ "010001",
+ "5e48e03dddeca1a959d9ee4da3f1c3f0ec2ad0fe7a70c177632731944c3cd0d5"
+ "8f4c4d9659746e685a76c93c2b333a643db21d29bcdc6d11b5f6908717b57765"
+ "99ff3088b2014ffc51f18d932224f1059b2239ea5644e8069a5cc431aef60738"
+ "0aa924c158abcbdd9751f54e6779c4ec232168b0014f4c8b497be949aee65751",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 6.1",
+ "a3e15275fb33aec37bd3dd582e19f5d38b9d0d",
+ "78daa61c07f941b4b440e738338d06cc157a01574a72fa78d363dce994090422"
+ "0a7132356996f07c01d54ee54fa32c5faa1b90d2430c80a23217e06bb1c8043d"
+ "61ffa18aa1d18e15e430aa121cdff43fab2bb0debf73e3d5a75b46f90df73d65"
+ "6bb066ac1c768fa383e4",
+ "9bf1dcfc654ca7a23d80a12c09c259d04bae07e831f609e9f035d356414ed106"
+ "f9b46235fa3da91a32b8fdc8fb8830c96523dcaa9b2538fc0102dc0f7a5fae86"
+ "35b3b12314c39055faacfbe00a15163424148cc9e0f0ab42df09023c052a46ae"
+ "3f86a18dcc5380ce39062e362375d3a5f9e3b34a5da25cf0de9cc19c4d04f63f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.2",
+ "443ab03c4604dbd8bf8006aecc2aa8de64a155b4f90cdb0859986d5ca3606603"
+ "59808c59bd9c2de775fc18520224b669c325",
+ "3a6a6089f727dd169297a579fcaf8ea7f8e12d5427f1f7901a9022a21e2d82d2"
+ "f08e63baca267b653aaf89de232ba3d392d1cb49dd76b388b2dadfb0094fda97"
+ "18f1783738d18fa7aaa629",
+ "5a0ae0de28fd33cc9801bf4dd3067123745363cace4dd8b7b8b811d6482f5912"
+ "0c0d653eee86a61a012a180ec5d17e99146d0cca0a587c85cf01dc7add84230d"
+ "9180bddf5a7719f69d1fc481af6f47db8cbd4ee1871a573fc8767ce8beedb5c7"
+ "3fa93f0c53804afe2e76ccebb87cba00cdac94de40e2b0beaa8e2e4158c77850"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.3",
+ "d1ba30e88cdda33d2b41896f43df081eef20caf78d7c1b970c6a6172e83839dc"
+ "43d4be29f9a772ba4159738bc6132968618dc7197c0edc57a1",
+ "9bb62bf9a751fe418166436898ede835cfaee2f50efcad60942f2fb2da1a2038"
+ "03f0be80beb17ffad0dab218b128027f3497a4f8d41ab9a1be264e96b4454876"
+ "7be8d4a7",
+ "81191c5475273de66a41bf5604f32b58b759a14e7426c746de4b53baf780bba4"
+ "2b42e9278aa94527f0eebf855f462d6fbb2978a4653037d8b448e1b807a1831d"
+ "bc5322d066984eec28114fb7201c796b573adcc5cc927f3a5897b2005564ef1a"
+ "2c0167f54365511834ac6f4958b8318d09e67854d631ca52807686ab705d71a3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.4",
+ "a54bc2278b567685c9b56854e4c1c406d9161747c6813480163ee3af23b21ed1"
+ "9983e0f42bfc9325cb5c82e1a47b8f",
+ "ccba5fa5c94e79832ab046c9777495b163bd3af217590fec5ac48c62786a27f3"
+ "70d2859955e45afb2b79f12de4161145be62ac13a03bf48195fb9e5a18b82deb"
+ "bf3ddfc80825d593fcd402e74eef",
+ "3de4c3e059357b8a54837ea15962cfe2007c5ea8985c93519164a689b755b61c"
+ "8bd273969d333c4bcd9b060353c37baf13eb422f1cb97756e6b4946adfe1af75"
+ "e9fe2d95b4b13da1732bd8b8be1197027919530c347f3dd1039e348a53b116f9"
+ "f8fe8936a84acc39f2e06956b678d20fdf9517072e02f57078fdc04659400c5c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.5",
+ "f3c00b009e5e08a63be1e40035cdaca5011cc701cf7eebcb99f0ffe17cfd0a4b"
+ "f7befd2dd536ac946db797fdbc679cbe68f1a2f36259c558f04d",
+ "e22d5e43b1eba1ac0ce65c3270510e0f13c94e9624ee525659ef4d57378820c9"
+ "35229b3099aa2b2350614f8cc4295815a2c9edb2d9c59c73d1aa900c2134c0a7"
+ "d0909c",
+ "533e67a2bc5b3f01342d8cb8d925d73b4db34cb675da9039226a98e4d813c620"
+ "110990a8e6acba50fd04f3307debaf20d4f374cf6de0d9b21d86e266079cf2f1"
+ "8b4503208a215de2b11cca9e3464fc5ac1dd7e96b2fc0409e42f46a50612a6b2"
+ "061ed1619a7fe46796ed8f52069a5bfc8408d558f52a03332ee8eddef8f745d9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.6",
+ "aafe5b271111efb8792f5aa92383072976b72a0a272f90c52461f88afb1bb6b7"
+ "ec26381c6576a41087a039809d14f6116067594ebb",
+ "750ef0869f8c757ef431578b45a6e741bd1d960efc3789b10d2bde273818074e"
+ "bfe5faae10ac244f89f6c02de5d1adaefc7a8fd24d7bc376fd65d35e39508c42"
+ "36acbe2d5ca7694b",
+ "344d4337612b22dd402be379e6b2650b519ef37b7ab485819452d167c1b215db"
+ "d3fb24f9b2f9298669cb1aee141a7d8901642043111fc38b3f40ef0b7ffd7df7"
+ "6c2d92e329411c75e0f17285bb6bb82688128ed9bb951caedd7d067edd0b13e8"
+ "275ac88625d97ce8d20b69b35738b2f4726e2984b8dfa86695aae88d9e176df6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.7",
+ "a1224df9aab6587845b2a393a5a876c17d959d535b5419d412a9a531bb437e1d"
+ "ac1b546d62",
+ "761dc4f51bc8518d627c45b3e9818b8542a06ffe172be3af5ce7a9053fe54e69"
+ "70124973374dfcc1f49fcffe957aae8c9c3b130f4605d2c3efa2932ad083dec5"
+ "8e70d4f6926c80b5d4891a1a559edb0caffacad75eb26483",
+ "785f6aaab4d2f318d4af37b6e0074ed5a4194fa605a7ec87d05a07f3349b5b92"
+ "f5fc4790eab13786cbf035c78ffcf1344d1f3ecdaae01672222e6d4a965559e2"
+ "c08291cb1d4c2d4e68ff8ee71523f6ddaec50a4ab22edca247364c92d87399e8"
+ "a71df7436b62d8ba8ad20294cbc60dcae0305c7973f7fcb4a5cbed15713a7a16"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.8",
+ "1e0e3f650c32dbb2f6916f36f135bcae881d545507402d6afd3d5b3bd8385a50"
+ "b4fad6f78949fde62164ed7689e5f9a4",
+ "eea90a54d016da7e8f0876a733b0f2a06f90a73c1a3cd639b6cfa906ce08ef78"
+ "8bb6fea74f22eb91a6ab3284cdfc1e72e63e78d18a64d67f9d1a291949ed2e32"
+ "3e91dc033876eeeb09ffa71f59",
+ "6bbdae20f989bfaa5d65dadcd61a86b66307a0602fb551a73806122db188ec1d"
+ "41e84daa2cc7d6be541e12288809a17e085f2cafa8ae13670e0f3365a1471cb3"
+ "157c06e0f63b8200f3160c163fde7c901ef326e5700c9f5e07fe0198810fa80c"
+ "8c5dc53a50bce254f7d19901cf6cbb603413e41f9030e739c8ba964997847499"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.9",
+ "73ddf0a14d57ba65b4f693ac761e202b1e5b857c8b3404e14185dfa8aaf04989",
+ "fd433d7b0176b731d780dd6c5851b82f176d62b80d96aeb631d7fb8ac5be55ac"
+ "217f4e08bc7ecf81f8e3f5ddaacdc6c2178df781882397533a638e62f074ac48"
+ "8f4c12aa57be2ece5bb6e9096cd92259a45b0b032f101431a28b8640fb",
+ "ae97ff434e9a5ee487761db356900b063737465be5058dc03a28a322e5c0e091"
+ "b799bf659455cfbe05427ac4d04405e56ee04e063a2373dbcb9b4fa16e430794"
+ "6a49b35634520d416f65c3c322edc54671569128a2a152a76fe444c430aa6f03"
+ "c4129c6e2131755d764cec4a1486a81ba8a3168d16e74dca8e77bbfd67ea372b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.10",
+ "ef3e7698e7d9cc863b466bb288556e4ac25282e094fb5b57c17617bb98",
+ "db90a7580d8d429e22bd7ea5c7b4cd0c65ad0e2e27f53341bc23a8b1358a76a0"
+ "b5e94fc5b42a9f756cc63b9d623f551767fbc6f7114e40ba7361fd32d6f8d772"
+ "3437436df724b1327aaef7b957562768f8fadd57862ba0b314096a3b38770e31",
+ "43f8cccea812d3385f43fa837cb5e6fa590f1affb862d2caccc6d8e8bb5d5c0d"
+ "50ffb9f8f8098900c12e772a847b378157782b0a9040f7a616c2eb058e44d4a7"
+ "e20b485ac29f40d68e03c39ddc8dae7e7e09e28f9dd2190f3a9f3574b2f63400"
+ "1544363c861fe27f7a39236692fe3582140b2172ce647eed417685c6e1db856c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.11",
+ "f86918474f881697111bdddc1f00613eb2c3d9c1787668353ebb02b320a326",
+ "cb7d99da9b11ea57f6405543447dd15fb5cca0a10f3b69b4d23309eff2750c48"
+ "6ca655325b55a327ffe8bd6dca99bc8efb5bc2942ec039e28425e4a56a07d380"
+ "12f10d215a22d637685943d364725301dd40e217228ab791598998836bbf",
+ "2a408780ad514e5671fe1dfc367d7aa465fc3469f1c152aee18145e0f5f0759f"
+ "4469b43d55123f5dc9ffc617f23fa49b78960219660ec62274d6c59ba31460bd"
+ "10941ebb5e05694151c57b5b9588caf09f455020a54e977c3cc027dae31f2ce4"
+ "4217023e10adb6f2d8aa0f8084fc458605803fd44b21abc27bdb8d4c561784cf"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.12",
+ "6a40bb60708c5a992ecfdc7ee53f54084d19affd4d21",
+ "c3f4faca56c1ff07d1ad103707d1b6682047b4d9d6246c2e5c4b0ce6553d5531"
+ "3f8f38aee5e4d8073a55d24ad796c4b76126c8aa61c46a4ee85fa9057a526cd0"
+ "aa245e5828f2181b4a6479868748e7479f4034533c0f3e1eb435fa47d53b58e4"
+ "2c9617bf7e777e",
+ "c46411c7116fe6f46f1ca0f74c6081a55df41d2c0b8fc5d38faa340b5ecf7183"
+ "f85f88c4fb28ac5fb1f18aebfcfc10bfdd3a19002c6b52241492704b6fe63d61"
+ "a73010c149ff6303283e9978cd845404fa06b8c698aaea8f861361d886b2c0f0"
+ "1b47a1a9a3dd903f8a58aed66afc85e9b71efc3f55a121667416a300001313e8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.13",
+ "3252fe99620974e077d6eb5575",
+ "bf069b4bcf15448bc39e45f4426aad0d5d82b74e93ae1cdd71f71bb9beb9b23d"
+ "59732f9c8bc6343d130231de18f7c89fc2f422189cd927e509b13197aa56d81a"
+ "7376f8333e4742448cc892de4044972c7f67dcbe8544a90eec59e795ae596408"
+ "392af5776da0d6cb29c7e0a7868130a7",
+ "7653cbff586892cdd258bfe6baebd99145eb1b22894e1a764d02b2ba995952a0"
+ "1258208de1a01d8e8cbb5cdaf0d603694f88255e809097b70e9d79e62bd5c0d8"
+ "36dcc29dd19b05a16026904205b60c4503d4fbe9933855e86802c75428d9a634"
+ "7303167632d33c5d9ecc8ae2493b58c36b2a6553a7b9e2b1358ae28dad50280d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.14",
+ "dc94",
+ "05e805bffbd1b74d1a5a838d857167b4c7d40a6cd3e68f31be4693b98cec6d75"
+ "894919ab18572c75822e75e9ded72da0679783a7721814e199160b7507f67f4e"
+ "de587c88be76815c50b261df308b314323730c1e073aa72998cc2f8e0a8a5bd6"
+ "5bf934aca8a64859e25f02c5a2713941c8c8e62720846dfb51c2ff",
+ "6adde244f0638c5ab745ffbab5abe1fe800b0eee153550c48c36f4249f9d5d36"
+ "b47b28ccda71a7dd832e6435ad0eb85ef7556bb84bf95a59ccc9c20751ed3e1a"
+ "d0de102994a712c514014692a67f1d87ca2e4fef29ec83e01e29ad0c978acca4"
+ "d5c502745a6c500df20004bc9bf16f5fcc69bf52709e31cf6a2b9fe624d9a364"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.15",
+ "4fae6cf37e9d5f59",
+ "e7f9ed4a0c3a646669039bd01f249f32bea1e6576c21d45189d0f891cf4afd62"
+ "32083a321ed2d34d070984f5e9457839b2ebc1e03a2c0d8dd709731e95b2e694"
+ "1ca0907187affdcf5a87f5cbead2f9052c38d0ee54e1f128ffc337de4566a592"
+ "5e1e947aef50881cbdaed99b1bbc1af513232c0ff4",
+ "46e6705eb1252debf8ec672c4fdeaf6988268459f99589bbd3054133d483abe1"
+ "e27caab0a7f0221b1b67a14ebf45126e601348b0434406da3a8c76d4f1e3f1a0"
+ "e06d0db823da5117b92a40b6f39f57e483a7da36e99b677bb3f76e6c5db03f3c"
+ "e44504ebd45e9f14fe0f613a2eb79547ab578c586d3b654a06fe1ef37a221066"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.16",
+ "cdfdfdaabca3767e70bbc5e9abf6",
+ "ac777f67299de4c1c4c574f31f674f6faabde031f8ec33e82676eb32a93f6579"
+ "aac3e959359fc573ee5c0e3e077653eff9d5f8db4b1e7acadb059971531f49b0"
+ "7c93eb9fdedcf0903a7d50b479676fcde8740afbd7d37c3a2102412bde1d3a82"
+ "44156ad8089d45dfdc91cde6c3a159",
+ "513c761eb1929aff7977a9ff0e61b7a1d511c8cb253924332425569a07e229cb"
+ "3901715390f7de37bd362c96fc0b0d79810c1e8b15e13b0032734778cf964e6f"
+ "6d17fc41c7867672b2540f569d0a460a80fad56b5f054ab8e49e409e9e0b8613"
+ "cb3da20c35c3e1bb99b7ecab7a00fc1fc2370f9c808567df89be2eddbdb6b110"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.17",
+ "b820c32e737daa234f29ba90647fc3bf0a8e",
+ "f5caf8feb42df7b6b389f50599a4ec20e619ca22d2bfc91bc7f14ae9f1229e07"
+ "c888ed57aa6ad3c1041044c51afb55217b0caa2334ad79f47abbf9b4208333b7"
+ "2b4ba4bb5fd037981dd80170c80360c14d5af51e5f82abf51fd36f021867a6ec"
+ "097bc33922acead9e33558",
+ "3e23251841db2e207a27101f1329191ab7fa6a701a526261482353a1a221efa9"
+ "d3a9d459cd2a2d8668908b783bb09c879a217f1e400f95b217b040a53e341c17"
+ "b93d3c3d65460c5c7f2b4d79a34b5a96117aa36751d9eaf233b03f68dba6a457"
+ "1b907177f828336e825a92261b623639bec98d3a09f872c2ec591b4c383a69c7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.18",
+ "606bbd613715ddcd92c7b6df04b36072f01162d008766312ca6977dd3a06eb95"
+ "e1bac7bc1bc6602c9ee644",
+ "513a5c9568e89b9a53d5af716e55fb340f8a392370e888a80caeda502e7f9dfc"
+ "175195a50e47071396d6ec554eb72f183be18f3bf4ec73b30592faef2fb514de"
+ "befcc65c8d23c4ad259456c1e80b360ad459",
+ "4721a23940188730f5deac85002e3831b149ae57afc69735a045ee3fc3536472"
+ "fc833c27c87eab6fc905e367961b312498636be6c77aa80b8da2f5d948aaa77b"
+ "5fab724bbf64ee89d281eed47b212c3295266577f4fd93a22239dee540c9400f"
+ "e56d7aef51df36a89ae92f926f558331e41bfdfefe35758b93ce1140ac9b6a54"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.19",
+ "1d82def8c592875008a5f89e7eb64e252edde9ddb881d37362317f6e6e6e993c"
+ "60233b0f",
+ "875e075ef1b054b5841e08450d78eb54a55c88b6d01813c107a09b74543b3f9f"
+ "e1b7c90211c62ea7338120d4ae0f73ba82c01d28f8194b3a396bdf50f9413a7f"
+ "b03be225fe0545db80cdf0f610a95fd90376e039e3831ff99e",
+ "8fb546263c1d1875c743f52f0267b2f2fe688d2542021049f53489ce7c359130"
+ "f8e11e3c461c5e863e4dc19f07a13a4c1a88224b26c5c0cbe2020245d91e1b83"
+ "42425252f53fc40e4b14fa02bbd74737d4022cc54fe38f0d27d8fea50f2fdd84"
+ "65d4f32f8ac03ee006be6233e4d1a3c16eb144b5d8be729ad304f82361e07cfb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 6.20",
+ "8a8a3eabdca7cab0cc296a291ea8a93da4d2d2a196ff2f8d181fee1f",
+ "2e4736e4296ab46618b1ef34da26776e92ef66f7cd174ef94769724223a765b4"
+ "ebef08a88fedbe270560e5f67437cf49d57ea6620aca59898afd52cdef30a8b0"
+ "d9855e5dfbe347de77c4c0280b0f1fd44d4fe68906be8a4f12c533087bf5bcea"
+ "fb",
+ "03f3e4ba034831a0e30a4a3344cead61b28b43be31532c2d7637539b9013837e"
+ "dcb1f216d32fdfae73323674a2814565dbf29e712d18c4373964df60c9399fda"
+ "5414a0eb45bde8661a89091295a1ef71616a3cd145e9b318b651af175d4ec350"
+ "1d5eb763e8d35a2b72746e020b4ba59973834b2150026b432b179a9ae8172b7b"
+ }
+ }
+ },
+ {
+ "A 1025-bit RSA key pair",
+ "01709341d2ec0804a74034e8fa728642983d1650d746e449c9ee4079aa15e51f"
+ "1fc134242e524b0d3d0dbf5a5121939b125fcc863e514160b634e37aa6989477"
+ "6c7d33e1e7c619521de482a0aea45c3c6abc3f33e25d86ffa1393325659bf2d4"
+ "098df169b4072187660e277700199b7a3e3484b3845f6fbf3198657df8cbf3a8"
+ "1b",
+ "010001",
+ "6febf798121e993324972c8c28ccc65a2e6aa15fcde232da03e4464db4da5faa"
+ "27e42a7c7a76d9ed49486b27a9d785c67d9ac0c519ad8dada6bfd115d7cd75b9"
+ "9c4b59c76983a7015b0da6973c69fa950810ae2768d97588900562e86a6df7c7"
+ "14b844b1e046686a5afc667b13573a55be9b5b38b99bd3cf54e4344a2f2d0e21",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 7.1",
+ "da509dce45e24700379bfe5aa1a81c24706c1842d9b13e7a2e0a15d3a4af8e6d"
+ "08612dcaa15d460ece872988e3e90fb27e5ca5c10fa1facdcb0e",
+ "808c2046fb505c37695c8dc35c38f9f9905ab48a2b8a146e8e8eda3385ced95a"
+ "313b2dc6eb418367feeff79a02ad74646df7a5d87054acddaf34eafd5c1db58e"
+ "5dec0481",
+ "00fc3d0aaaf26cdf25a1a8dfcb71700fb65e2ab5551ae5f419b2d2f94cef0173"
+ "02b00abd9e6c6efae94474d18e68da0a7c17ef2c5fcc89071d3b07121b9c01e3"
+ "0ff053663f61f89fdbc49bdcf8e671669443919d41342845e3e99e46a8a3b48e"
+ "2398a88e5b45d99a17dd1f212edabcbcd300a84d398ef57935bdae959e6054e7"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.2",
+ "ce0a794749874160e5d2e4ff",
+ "f4b2c9f311c1fd41d47944b50e1755d4eac5ee65087c9fc6d2f075b738c64926"
+ "eaf7d4316bcdb63654d5420da61e0245f195b9e824aa0b06c88799b127fe9b03"
+ "6df36175c0a6bd80e4e0af6ebc2f4270b04ce30b9fa27f0435860fccf40b3dc7"
+ "eaeffdbab9e1766619bb016c17902663cb24",
+ "010cf74bebc2636d2c49d9c622bd76cc0b1d02ebb52fdfaec01c4ac1e756071a"
+ "8ef76e122a4c62c6ba3265fa4c905626d113d59db79ad65f8640b3c4344d7340"
+ "c16e38deb189e3a1b11eaab0b2606a7f82f5946d419acebbbb3a937d41e29b33"
+ "edd3ad15f1e7770fcfc30ae06aa01bcd03d5dfb162f87a183967553c2502cb5f"
+ "fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.3",
+ "41d6",
+ "556e59b2c189587508e20892fa5602d249fbfb71a10905ed5af7b79be87111a0"
+ "c69addb19eef316d7c0b21817990dc3ed8c76cb23e830e17c0f43873159fab7c"
+ "5c4a6cf219cb1dc5c5da4553a3e0bf183b8e112b61f692a7ddf004bdbfdcc8d6"
+ "659c3dd80cb23aabe8c6fdf2675d073b662312e4accde91c1225e6d1",
+ "002a100495596655304bddf9097f78d9ddb5eb429b66635a58a298f1928eed61"
+ "534f80b4ea05ee39b02a64566f6c456e3b586e7cb43a88940ee129340f578e56"
+ "e72d8b2783361006d97129abef02cf1c1912e17f0cd1d71c0b328d0b48a4ac7a"
+ "ece3c005a6190eac22c1991041159a2ad1db0896015c4ff1d7b35447cfc10a24"
+ "be"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.4",
+ "0bb4abc7dc6ca4235c29ed0a2cb63fd141341e2c4c901e6dc95da9f0010fa2e0"
+ "22ccfe8adfdb6ecf4d89f579a10a5170be18c46a241ca7eed107cafe4a9d",
+ "bb80be7802dd8bf5fb5b1b86396654f4739f5d4351f19ce31b72c210aea1a2ed"
+ "2142d8d6f7ae374f06133a315c6264da65cef233ed3dcc8159d76c3a17f36d0c",
+ "006f1b6c1fb37ae5c8c024449abc3840e8e5097143eed16beaf67b6c7a4824ac"
+ "38b6f8c353b645c8cea4fab09c02fa6c325a507438b9645ec8230086b315e34e"
+ "7a56adb0ecd89fd07b98739c24db6fe11ff2e5ad38318ec31df2ed2508debca7"
+ "a67e240196aa9acd80329f4c4343c10b72699f9d6b5bc243995b09c46dd3d803"
+ "ce"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.5",
+ "ed26ec202d5e69740da3488406bbbd",
+ "f2fd08cc0db9a55abfebd92e2a9d75872ab7dffb0b4da13606e152759f866f22"
+ "eb8729fb8c9a5c45ba2f4acae43159a7ad3cf78e81fd0954909b1f0e7089ca86"
+ "a4588d8c87a1a61f1a48398236def9b4975e2549573f60adb5e861b7c3b2dfeb"
+ "810d13e297a6cd3f2afecb0e4f147c",
+ "00933c58a50c70150da0823a7c1e367d36e5213f66a30050fded72d5755b5f9c"
+ "24050b4114f53509988b625420cfd00ac1c8cd84489ca26b743fb47d1b64d0a8"
+ "808ee32127c771224a0dd5a564e636add73bcff7b473e9a12b7d464d7dd4a752"
+ "048661a8b074b9fa1506fef603dd96d11996a7d9e74879f99bb2d91c37aab135"
+ "72"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.6",
+ "dc285a26395939e7997204c71a932f795b4de401e96f34e189363237e9cfdadc"
+ "61",
+ "d80bfcc291ce518ce0bb6ae934dfd85658b239fb4539cbe05da126a898b7f364"
+ "887c0ddfb1eaea1d5a90de7695665c55822a1172cb5be8a112d28c8602c513be"
+ "48c292f05972e6711a44cbc7281715094b490fde29165a6b6b7d99dbed",
+ "0157e7b54a341b8df8bd9b99fc2e6c58d886fc79e7442a9e76d0d67e4858c4ab"
+ "f0ed25c33df62e2aada399dfeadc7ff68928e6b9007102ddf809f5908eefc10f"
+ "2a73710609231f5d45e00adda134b602dd0eee0f6722494b7e4f7b405772c831"
+ "b63729be0f1c4b6d2a542c1565c7df231d9e892e586a18ec54377376db77f813"
+ "84"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.7",
+ "4647d841c5a0b9973a91454dd1a05ec0e57503ed99672ac002dfee777f7fa506"
+ "fb41b2ec8b8d2cdb9bef0133bd5e3a7d0c4344b28fa8db",
+ "f527a14e2e06e73f1c245d190d02cced011e468487acfa5e0bce39786b46a9a8"
+ "c751a8b4406ccfa1fc5b7ab9bada7b4ad452467e50b7fc41318edc73dc2d84a2"
+ "8a081fa17905bc",
+ "004e03caa9481d7f9678207c17b6822a5f6917ed01eb402e7f230135a123cd9b"
+ "6de3bec3b9bf338adef8076fb7652fc7e3a373fc1622f1dc679d415c3200026d"
+ "8a8a50f8db6a583f666929d0318ebf91d95912fc06102d9be87525a736b5af21"
+ "e16de3efaa66e9cf41ca73482323dde80eec308581a44ca3aabf76dd481de652"
+ "9a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.8",
+ "ba10d47a9f624281",
+ "379fdcfa5d8c6137c36bad143fd9b1f7e894fa0e9ac0fb9cec60e86c8253975d"
+ "8e78742108495e594ad0898fd04c91e401e7c88089a87b4a4a82e834cd3777a7"
+ "d3f80e6486812d4ab0d33723162bcbc7e081a99d3f9b5c3ba44b19bdf884a462"
+ "6fd7def7674057bea082e00db4b761ad753ab5985a94",
+ "00c4965e2963d7bc5b1044d8fc75eb3382cedd9907419792efc88c92b1d5c390"
+ "fab190011c518ac9ce45c1b8e7276bffc7c7e05c2537089137a98df6e0c69202"
+ "0ed654af83339bab11927177f2f523226b4fe64b99c1729f6c922906bc16d31f"
+ "0c94dc2ea413810d55940c97afdd4829fbf1618a8c9de89dc24006e7e421a58d"
+ "38"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.9",
+ "efc7489fec779e052e379c1ad9045903b6842a9ca41b48bddce58080a5edec63"
+ "f36ee11560fd",
+ "c8ecba627214c414d7c3fdd316c2d82a98535728b9a9376f69a953d7cd1cead7"
+ "1053dbe0140c7f02bd71e0137fea29cd4c21a58bdec66640990d28c10b701759"
+ "3c1d11fe9abebd7124e1d985631e94e9e51241260f9ef1f1",
+ "0032184ef288fa0aaa0c2c1a19e7c29f81c7012f4529eb9eeb53681f6247f8d4"
+ "35691345a5148a2c877b2b18926bae9de5b317bac0e902c96025eec2f9eabd0f"
+ "9e8886ef9519c8249feb834665c1010db7624f487e161f89f6ae0018c1f4e0ab"
+ "5472f7f0993561cd5985f383d049dd832b82c83748b2281bfb99d9d5008dc807"
+ "de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.10",
+ "5b264ff88defd3c299993d81129a6e5dd2b57b",
+ "0be7ab5b29704843c1c0d7e4ef5e93f3ba717db7815af572e3a9ab3f99b1ac9a"
+ "22b92d9b43da2b9965c7977057173c03573f32480a927019afff0e0e34e4095e"
+ "4a4d392dcd1bd9f27d32fde7159f023c83089e88a71f2433648ef8c84045b9c3"
+ "6d8e5f6eff034b91b70234",
+ "004c65293556f2fd15ab90eb22e07533b3dc17334f5eed27a3993180c56c8e3d"
+ "8f51eeb27595f878d23665ba3ab0e728a5aef7234f6036b023f871c2d6552a18"
+ "ad5a25bec55bc76bee6383461281d39a30f6d66092e0cff6923268fc043cdf74"
+ "7e8d5489504e7db30a7bd91a2bfc6c1b3414405701753d5b85ff7352012d55e9"
+ "23"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.11",
+ "72e20900e5bcc23cf879ed3531889a1ed5aa3d5c792e34e3b12690d9ac2403d0"
+ "f6f78f5923",
+ "116275e9be1bd4e6f203ffe4f0ab9a32738410e923e83971ee9a6b992c650a03"
+ "1f940f6ef33d6150dff8b39dcf2250d5665c04273b2be2dec99712bbc012f75a"
+ "31b30ba06ff9ebe3b89f58a68f2685e338ff6cb8d4181a8a14",
+ "00214a83be453a75bcda9433a7b951433439983072071cc82112b77742be0c38"
+ "226ca3c6f38d55b9ca3f08c8793789796e6cde67376d673f5ec57dacc374c4c3"
+ "173444dd8a6376de8f9ddc31a4c060d772f02eb749512dcd040231175d0b6942"
+ "a947b2c82f7c19e2ce875000af84274cbe2adbf2fbfb537ccbe2fbd072871378"
+ "75"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.12",
+ "16b110e2909b11b0cf36b052c6f3936a2ca13fc3a5",
+ "c2bf9e4fb1ed70ca212d15ee8eb3cd660eb65c5278e03a3b10eb12b25334a472"
+ "8b949920122fb992bf2ce430103d74ab74e6d6e762b85d6ef9beb7d72598f293"
+ "a43562e90689541111511d314a9c46022376ad055d54ced6ac1f36e98c2b25a0"
+ "acde64dcf6522c3d22",
+ "016aa95a082382c10c045310fefecc8d17dbf216d8edc04bdacd4f524de485b7"
+ "fe8a26f14cabd297e7f03b3c85086a16147d5f6193919bb95a53c146c784c00b"
+ "5332e018f643cf958724cd08075eb64ca5680c27c705d40d88b9d7f426b736e3"
+ "c5f6394ea683b65c2373a6fceb14f2ea851ca8e000e24dc8f7e7c81b1d4e720c"
+ "36"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.13",
+ "3c860a28fae8da2ac0d9a33989977ffa04",
+ "7c9699906c9f1665125c0b10673f3dad98c91a4ff0faaa647db554fd6227ef50"
+ "909c97b706092be210db2c24ba9e8e6a87f9ddd9f3f491291029ac6ee46e08d0"
+ "d7a53c462db4f0fd1cc23ec8f55eda07f4ca0d3e3cd37622855b4db08f64be3e"
+ "26c3e97875171294eadf86fcd6",
+ "010c1e04a858c615ee9695f64ab2db99806da482d2b460293c46dc7b717a5976"
+ "a3c7e36d8d47a84a34d63cdfca2c1e38452573ed44c3a040405ecf3fbf368341"
+ "c4a1fc9083a8f5529367b99cb89fc5a08b8f3475a0d55e3e42cccbeb20d04a19"
+ "97eeda4e3cc9e992d237ec7d32fe25845ab024d5882805ed52f10ed7d25d62d0"
+ "af"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.14",
+ "4edf4ad3440f17b10d26afcdf4e444d2aa61a19755a62107983f0122fb2a",
+ "e020093939b4189e934cb62d27ca5e9719652c137fc49e721c4ab9e9f398b0a6"
+ "12de8a8a8999af0dbc1cea0b6163da4261232814ed92eb2160cf4b26d0551b1b"
+ "dd919d494793786e1b86f79d6416612a282261363d6c9b7a0d92ad1758eaad51",
+ "008cf9b3f3e76090d101174ecd97d10bff6de4d46440003fc0d428f19b8558f3"
+ "1374a5fa283d03d4dd43f93a4d9f14ca0068dc2cf3e25437b05ab1d40621eebd"
+ "8416f5828ae7c6cfd297b4518f79942b914323284e2976a54d3cd911633a307e"
+ "daf1edb67498466b3e98916f9904f4a0ea9b87a98344f073833edf9b2b5394cf"
+ "d7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.15",
+ "8a6d53b0ada1854e2313691aab23063de131bc36c764",
+ "2685458aebfbd6074ebeb0fc0cc4921c273e8c0a881551502e4c299f334dd567"
+ "f51675b0ff30f2c48263200364996699f9b172affec0e79e5c523d1e779ec06d"
+ "ecd476a57430781e2dc81f25d60d3a73976579a2f01f07584cf8e5fb3ebd8d5a"
+ "932d57aa8a180aaa",
+ "013a3d32eec735ebda13f8be7602a0475cf3cf285b4286ad93d612c3ad917248"
+ "809d1c4c180b367015cc66c4d8e7867384168cf4cb719bd593355355cdd7d753"
+ "0c80c867745f9661c6c33bcb97f2cf75a4c27c3cbbdbbe7eaf4f8234f212e305"
+ "8256d4439a9f9781df48efdb023568f94ae4594654a0f9baf6ea30b7d8d9480a"
+ "d3"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.16",
+ "20f02044e63ac92eb9faf1a0ce35ba7209",
+ "2de1fcc117f821f1dea794b5eeb313f429e00b976b53419d3d03ecaa1b507688"
+ "77e8b7fbd6c363047e15c255793b3cbe0f5884f0a511254d31bfb23741023c1f"
+ "881fe016a12eef1b8af22b9368207e7b1639f7271debe3c8df5293eec3a032f1"
+ "ce559c0a04771bbf8898947ca4",
+ "017006e86f6c5858fe5ade0dcbfa9ccd11c02d4e7d0de6c158adf9eef10107e7"
+ "a4c36bd3d929ea6a476ecfa0b6ecd05149b51215954893a1ab2669c042da83e8"
+ "c818b00ae734de5f9e0b97ba1fe3e9c46ae9816b63b15c2dcc61cb3b8b2c23dd"
+ "b99fcd54e95560918b9a0fa3c4b6273d1b28a213e120b4f24286965ebee94ff8"
+ "96"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.17",
+ "d3883b",
+ "5ca3bbf992d7ae3594c605c39c3e979025ccb0a35c6ef0fa574a98be05ef7c32"
+ "8a19a2775ba06f2dd1e0ff6f0f1f6a3b20fbda2162d0924ff55b70ebfe2b16d4"
+ "ff6aef8d47ebe59638e5810ffdb58db05f4d9b4a3a423f967fe579f87378369d"
+ "5c5c07e5e3cb5dddf389621180270a21e01078c89afbab189e87f7",
+ "016f5505f74ff1104da1f8a52e50bfe29c998710c57de44098a9579e7a3313b6"
+ "29603102f08d2d911f917a9c9662608c97a1ea371734f67cbf7003d93c4c314c"
+ "3a0e77f3658fa4d0722562c4e13e85a7c8d0d9d4fbf7125884ba62ad2859b4d9"
+ "6136f7a2455469ceb60b63ba8474e6160c8317921a07b4b6436f376c5f98257b"
+ "17"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.18",
+ "06a2ae82a4853207c9f975",
+ "e2c33633d54754addd24c85c32d28ad870f1603d444460a03aacad7dcb809601"
+ "56bbb259cad346be90c0d4f3fb18ac6e9d5a9ae2a5ab98a1f84b8e70c71d0ccc"
+ "0a1a2aa39970d9c83b4b0c25aea43a5a5deadf9dc611b96d11334ef943090389"
+ "a8d3c66cf31877aa2cdff1119943278addff5e",
+ "0122410e765b2c9e90bdacbcff1bca8ae64be99cf013297485721768370c36f8"
+ "c0d9db8d79376254b9c69152720e05caefd4ce7eae08b3dfe3eaa91c4602eff3"
+ "8e4d81bcd3787a14d622dbb79ce8644c4fd1d2e41f7c1c97279611740fc50000"
+ "3178b37bbd81c5a5829b5c14bf459c4238b03beef73e498f865f6ca79a9ed60f"
+ "65"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.19",
+ "ad8b11a927de",
+ "5ecacff63a7938e998068a2f4ba6bcc1020e1f28c734e434e8863c48e6dffae2"
+ "8d1852727ffa7f2efa3de7013b812a02b2171a0f940b36d928dbdb960a6b2203"
+ "0c893789cbfdea9735e9ad1094a68461c2eb6f718be474d93a51930e3cda02c2"
+ "1f6363914e7eda5484037a76adc53312eb9dbbe45e23a14b",
+ "011fa43f5f4fbb983011814d4af545521df0b59e9b6ffd71333b8f9bbaaa0fcd"
+ "c1421ce4bf31bf9959fdc6b09b4f4251ddeee8210fc3a52fe7c71a876e6dde1d"
+ "fb59a4dab27d34fdce5bbfc6ed623e89967fb6fe73162015282c5f450138f250"
+ "4ab61c1f12d2649d815d6e8138438f8a8046c4e840cb718598e1e4a9fc25a945"
+ "64"
+ },{
+ "PKCS#1 v1.5 Encryption Example 7.20",
+ "bee29436c2a0de16f66042917007fb5130f3c1aa7df2c7c3bd99fbc1b413af4f"
+ "96a65b0e543ec6a50be83a9f",
+ "2391a68425dd8f0b83c9b3612467a779cf92f5ff9611c01493bcbef865e15bba"
+ "5e8fcf74beb9ea2573a9fce54164d06baa8b6df367cc4c6a114aa0346c454a2a"
+ "9e60535918d3660c66484ed953727a9c9a25",
+ "00989ddbd28d6095ada6881e28341ce7a0a1ca6bf7f31f772f910493afdba2d6"
+ "359d50b9833f83d0ab8713abe8e2102a27ab2a601fb77b9a25d6a0aff40cfdcf"
+ "9e12c42843ebad328324a719f29e8d79ea9e5d0d988695736034db5fea73dd36"
+ "00136f57a398fe352b278c60cb74ec98ad57a3e1d8c4478ca6179f4d0426f0f4"
+ "20"
+ }
+ }
+ },
+ {
+ "A 1026-bit RSA key pair",
+ "0252e95bb11ba1e1c7c95b6853f8de0bfe2b6403ac1bde819d918907747b0199"
+ "fadb8059c25aaf1ac565a74929d015a201f897a9bafe754168955b355bb009ce"
+ "16149312283c39cee220d0f0858b13812e86a7d4e5388b7eae5aca7c886a76d3"
+ "b1e6dd679268a82311e2820318cb8f0f7e85f0e6692eb0dedf30881caf7315d2"
+ "7d",
+ "010001",
+ "0104c85fd5d8d7932a2985c4cb7e9e13a2c4f1903c8b70f3df9712faee2017b9"
+ "2082c51653c0bdde9de66c3901b7c22be4f24cc56dffaa75d43b18a2e0c0dfe3"
+ "726b198caa0c9665263a93796a27d32984465f4b4affca0d92f4e51a37e41ab1"
+ "550766d5ca7e90d4de909bbd794e8bc52b7499a73e468ab44213cb3a3b5452d2"
+ "ff",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 8.1",
+ "f72637aec28d2b6ebf8f73d74875df01cd12248f0020608e61c73d1a01f972f7"
+ "4dee",
+ "cc2077a24001f3e3869694e4fe2772bf938f7627667b62d590f9ee4fcfffbbb4"
+ "7afd5fed6a180844a9121a32ed7cbc56cd2870a2d696b943d6fde9767c1b9648"
+ "616c32ed6c400d423dd4ab7216afada028402eb2a1c3ebcc245afc7f",
+ "0072575d3b11c5ffd6ae24f353ff749927b4ae5df463f70c5f3ef5496b0d145e"
+ "b2b8a53c28d53efe8bf9f27b2ef4ceea48310577c3d2b4b949a12e3df3f56776"
+ "828818452d81bd45af158c87bb57745b8a10fc1a92a0ea55c85139f842f73f1d"
+ "613b9a964af8ed720d0e0847f7ae5b305c05f12cbc4c9c1684acf902970d8209"
+ "49"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.2",
+ "2a8e3ee7eac6b22ec658ad44d666c8cd3f57ecea299b5cb7bf9a373dfa66972f"
+ "13e5f3a300e80e6dbf7415680d0d24901ad6b140b000aab85351f92f",
+ "fb19209d8a29afafbc053ac1f320ba60fc1fe104aa7839c84c9b3eaa18a8f943"
+ "bb219f59cc167a384bac7bd365824e103631b97bb9a6d118f4f0a951fa478a05"
+ "ea09",
+ "021b54646571a9a93f0b0a0382e540a8c3974cb31c87ebf17b3ba62a1c9521c5"
+ "0d7f90702e13ae0e22263834e7646035159445a0877d9a4f5b16177f7fe052bb"
+ "d023d081894f2d97cac2452076ca1191a171a48fa1cbbbc3f0f6f3bc1a447840"
+ "3a5a488febb3a41380163d942c977bb8ecd2866c5f5d919ed20c0db3ee31ef2f"
+ "51"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.3",
+ "d99b4f10d9f32e12ecfae2630b22ac026af964b9c715d207",
+ "e0af8b7eab36a6ee316d781367f09ea11e31fdc1ef2cf9c97c379eaacf6872a8"
+ "213cbe4ce2e29c778b35954010063f1776ab5b172da624b406a1c58e0b574a03"
+ "b1b1b2cd7d3a9e5035a9a973058f0497652d2f73b1dc8f487c09cfe71d8ff8f1"
+ "458c790ee0c5",
+ "01023bbe8557c2630a262246db7abc540343887038f64c641fd74ee874ae9670"
+ "fb2862d424703da20be4f48b239cd06043819d8f615144e2b1f00c8f88492e62"
+ "f6e07316f84905353b0b1880ed77da2b62d3a93bb70ff6a5007938b973b4cd5a"
+ "bfee0cf13f5d4ab2160102685cac8081834f9555806bb322d0dc5b8a2bf12845"
+ "62"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.4",
+ "caeca8e59b810cf75112f7ed047a46692ca0b7a86e1841d719",
+ "761f6864dcebc95a779bc0b16a95866c33dc8dcace61cd7bf90172d99aa457db"
+ "6d90887d84c4738d25cdf0e89569ae47d3073ec446eeedd52d57208bdb694557"
+ "034657a703784937ba694d42512138532b8ad1d986fe47318b2823de82ce276f"
+ "a6f0d3c8ef",
+ "011c0c03f7b6e1c1a8411740a6e5b473c28d6221176c9d4f68024ca57cda273a"
+ "f554740360990a1b74de34bcea103c2d0c36576002080b30bd28f076fb75fc9b"
+ "eb9e05d1989a311d12c1f28fd69392ad4be52ce389dec11eba946be05991da7f"
+ "d887a8d8768de736b905bf4bdbe88b85dfc3b25aea30fe90df1d22d8a8d61565"
+ "1c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.5",
+ "101212856e60cd272fb169cf62cf47f1bc50ef9f1fcfd214816c807f184a903f"
+ "16f0e809acf5e0",
+ "6043c8df6a7f4ab83e3197e8cd0225dc3866b5d8e6993c2cc5b876351ee33c71"
+ "c1a4ccdce45f3e9dc7b7e51b52eebe0e270e716207ca1403e13e723ce73f1045"
+ "5edbde85b0829052edafe56e9a22024d4068371d36c91f",
+ "0005c5cff89b933d8b6523b35906bb3a711a0f7f503f92147466598503912730"
+ "3b0011e7a42b41c33bd20db31b1560c9b5222089cdcf53b82c95f8c1adcd8b78"
+ "3fd4b48a454020668e0b62520e52585209db529f38708649d8e064890b228fb3"
+ "c1981b2aef3a5465ceb13021ebe08d02e33aa2dc3c39284ef7a858dcceb28ffa"
+ "28"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.6",
+ "6f03b5725230de7f9963698edb7975ece8",
+ "a30ee5aeab5931033efb70afbc2d3d11a63384cb8cb33a8fcae6146684e63f0c"
+ "c32e89a7e4ea43327bf035669543192886dec3fb4e2d0811efa9aec5109e31b6"
+ "a056e53e317f6a904b13a7356f5e7ae60b97215ed14817d28f74b1640b1f2e42"
+ "ef0d38ca35a354a0afefa803a4",
+ "0010bd2b356f9eabc22f7e68f72f6175f9ab9deda96423b74b11de82c607a138"
+ "863e17966c07f56cde9ed6bc422ed9feaa1f65367ccf91cd4c9158a749571a0e"
+ "9f9607cb48cd00a448de03649106ce0c2406aa50aa1217178cdb06801c70a89a"
+ "7a1a83068e68db95d24ca3db33a7e5e43a68152274bbbf4006d9fb69f0514cc9"
+ "e2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.7",
+ "879913045461bc0eac",
+ "c3c6a24ac340a4a3ff3b2c302b56eb8391bbd95fafb66478384438abd8b45d13"
+ "2b269909b187840a6844ad399fa8137205e02ccae7775ce6662120e154b7bfd3"
+ "0e8ea4d34a7db6a23488a5daea38085bed56780cff8727125f1ad5f9d5a0bc3b"
+ "e580bc4fa068267b27de383c55c7fc1764c86ac21a",
+ "01d21ece33f440c72a111d62ef486c77c6c890cd81a4eb0532ad2c0ec768dd1d"
+ "e5b2112fdf04e287a95b950b1fca5ae693cf0e8acc936f374714de7495908c29"
+ "15a707213ac3dbdabad81b4ba1cb50b95f9314531fec833f0821c04b5740d73b"
+ "8cf1f9e3d7abc9744926138fb015c0f056cc4ba2f3163734db443ebd68858c4f"
+ "a6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.8",
+ "5b",
+ "42b999fb163a6ffa67a9bc4e6ba12f81b1d56e54bf0866397fd314eb0cf97f13"
+ "b7804f768fba540621f05cd37264d8e8f58228fb6ab30ef54e30fa8cfcb5a87e"
+ "148fbabf85886ab1f0d525492f56c647f7229b2bf394a0ceabbd37c93e6da809"
+ "7e82727b3d53e8c2ad1f7713e34ed13ba59e0a914db06faae49cb37996",
+ "0090e5355947902bc3fb580a84770903a3955b3dd7191c928f7407ba747265dc"
+ "8cbc1d22f9377272b1a8c35c238f04a11937d1b4354f643795e986dee2e40a40"
+ "6741b021fdf05c4ba11562e83e9f28592e0a7914fe88b2c0fe7a5eeaf500f7e9"
+ "8a5ba954f75077bc8f659f21bb2203314be0d6d21e6320c05e6e2d557979226b"
+ "80"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.9",
+ "f63529901324a20fe5e9258ada2f9537b01f5839b44597e3293a1225ca3a2adf"
+ "684a72a793c69c56af2d3498d32a092e914b",
+ "7bfa8597a434cdadfe156314449513d76c105df1bfc48c4d076abfc05b5dda72"
+ "e0dd15f9fe82a9955bd56d3343e7c6f25a60741207e73a2d10bb95d1d729a227"
+ "93e6c455e916235a811694db",
+ "00adf4787467eac2ea61fe7ef82fd87c2da5899f30302bbc112786d2fb11c142"
+ "f3f1d8cf37160d2e4a43983ffbd393a41b599ee6a27e246425502d4690202fe5"
+ "f8ee1bc6c1d5d16be23b973aedf7f9111bd8b142844265fd93577a43c3acc6e2"
+ "af2089d9d2f3f31a5c247a7b68315bae25d5ae8140a51ffc0097107ec1620ab3"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.10",
+ "c6d14b047145f317781dd7382dc0a97257d554bb53539ee9a292e7da5cb6426f",
+ "01ff38d5ded6c43dc1dc5c27a7e4813f448f45c96edf4bd93e96fada9bc8ec5b"
+ "434f0619a38e04356e06278551407b7f37e42d9145620a81981850a49e285117"
+ "2d230b37824110f8ffdb847794639d2650cbed36260105f1f1296e52a7d4",
+ "005edc939789cfbfaaff282baf9701d61f9dbee6f2d206cfab775761f42cb274"
+ "ecba31c7cd2fe6031aba0b84d4627d3037e31ce7e15623ba7cb7690251c06327"
+ "a431371298df292195b6451162d2da92a7078e2d07c9f56a07068a9a3e173e4a"
+ "ae25a5d1c68e68208cb5253a0a53aa6e2ef6c295d1516569b862cb92ca823ccb"
+ "ab"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.11",
+ "c11653e810b53e6511f13323fe5226a170c21f6daa4429d968efda0529d7b6e1"
+ "0dced80c6b6301ded22f52911c0f7ff4535bd5e20ff53588cd3de6648ac02d",
+ "85fa7c6ce96d0a8a1fba7504717ccbe137138093956eff063fc2efd4a46d7dc7"
+ "4e90f1da9e43dba9129f14ec559a4d2d6c5a19cbf3a68c62d0983452a9ee0c",
+ "01b08d498313a7d74a055314eb4315ba028760dad41114d5942d63bf8d27be3f"
+ "49ccd94acf9d3aa22d09b99bf97409bcf33213c0996707868203a9ab27708d3f"
+ "ff69b89d02e36e0121a119b8d4d9bfd4fe8b168fd7c12a243f7a000b39bf8d56"
+ "481724208023bb607b30505dd1742f879f16c10ce490d34a680d27ac39607da2"
+ "4e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.12",
+ "095b77c94dc1b18788e400e6916a4b4cfd73ace0df9a3ac131bdf9ad0a12db76"
+ "6deb225359d901cd56ed88cda3d328565402",
+ "a34a6805557109c261dddf5f85d371ae6520f45adf469601b5c359fec744cb2a"
+ "ae80983c732db6c545df55e0208acfbbf1c2c5e79988f34ecd6e5bb4b525c1b8"
+ "bcb070d0d84248b1f8e7480e",
+ "00395636a82667dcf00d5dbdd8541206948d49368917ec0e00fd7ac5ca8bf44e"
+ "c58378386e594bc065a9a63cf2a355a608b6f0bacba56008bba4722a7c470545"
+ "a20f387853d460313b2e864e17b233e596354132af173b4d04492647790262d3"
+ "a43f8427378837466b0673a81527e6be104580326fec84ba371ea61091fa4033"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.13",
+ "38",
+ "547c91751905d5a284ac3fe432cbe03055b285065896110ea36d05a140083ce3"
+ "955fa82841eaf6db4a50d12c074f45a688b5576d6e616807540ac117585c5bc3"
+ "be5260727cdf123c774db40cff297088624853e4695136b931161517a7b9b5dd"
+ "cd9d32de3dfe3ee2ea688cf7bf882ccf7b9c48d5e19effa6504a42620b",
+ "0089e39dcfdf91693defe39d12bb25f80a768d441b481d6a7548695042480cd4"
+ "a0ba9783d5c5bd38896dce06acb177a4ac5968e655a7aaf50d694a649713b7a4"
+ "bdd14c819f83b2047de2195f7303665453a8a1115e5b48ac0e9a65eddb318951"
+ "7b046fcbc2d14381776a77fb468e11293c78c8374c8f4660351ac2b2c7845a25"
+ "fe"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.14",
+ "80646b3c4df0eb791bda0ccc4d97d81ea8f6f74eb245e2c7c348fd7fb99016a9"
+ "d40a605ac742b27ad248",
+ "11b8e798d7a142d082e0598a8cb4f8c2aa875d5b65178c4ee67a5cb841d1cda3"
+ "0431d020df2880d7935815d59d91b9993e53ac341c972861eaa26697cf10ca8b"
+ "2794b45303be03489ebe074d8f239854c3a606fb",
+ "01f1e5a3dbd824752d2fba3c3242e9d996e627430d493e1b446a2dbcd86a4809"
+ "3e37a2e128b28c49d2d172bf5a977c369baa9ffb839bd2fdf00bd30ff5228b57"
+ "6b94e6d8ecf944247adad019f21d06fbe418d3a6d54cdf113e8d14f6ea06d8db"
+ "796493bcb1896fc4f3f30386c5c8bab7037c879afea47c8fb7a3c5b50b291866"
+ "b9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.15",
+ "6b631c7c35ea75a1b0",
+ "3e4240c3e09ea78355358cda6129534730f48a9c9a1a5213284bfd0771216ad4"
+ "ca233d993ee6357f4b1b12a6baa17743134a857fd769a8bc78d61fb14fea0522"
+ "1dcf5aeb1affd40d8bc6945c301045b686c611fa437e30ca0fab5a4cdef5205b"
+ "af9926c607be9637b1507f5083e940ccfa2fb38619",
+ "0047cb9a9198d983b32224cf27fc7299bbd4ae0778a83fc59c4745fa99e917bb"
+ "74f8bd4ef13f140ca9b72e2aa174ceea264894e215f41c36d4e6f346f69b4f85"
+ "505c54cd46259c712e30c49294badb1c4716851f2b75e39612cd5466ba56e3f3"
+ "1599c2dce23d04c93a64402227df40b514c74d0aa36e1e8658e29277b305af35"
+ "15"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.16",
+ "400855da54a6d1fe5fb58a73d2a5e5583870fbd525d2f572adb5963006d0a133"
+ "9bea889d6d46a43762f513bb7cc03622bf859244d6",
+ "496e50bab5ef18f22c3f62b921148d36c101ad0a9a2038675808ce8b62f8a6a0"
+ "ba8d9105f92ed8a02b312f324f3fd39192bd4153784fb55905c3b669307bada8"
+ "27afa1b5cb3dc11dc4",
+ "00d3a85dec97d34488ee33c658ba188e64cb57837d2eddbcba8ee52f13f1e4fe"
+ "9bec2f92e7210987e1c3fe345d4019770b07749451b04d6730d53a91015b257e"
+ "810dae0a0c116a4f224514edbd39b2c65e152d3b9789dda4f0d45bf9832d279d"
+ "3431062b4de1b0677ef59c6c332768ecda3aa6bcd10f70bd06030a7665ed3f20"
+ "79"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.17",
+ "b87edb455a7e85539f928edae909fbf8f7a199c03a94a9a45acab25efaeecc26"
+ "2974cae0bb72243a99c6472079f19738",
+ "035e31594a5665605b84fec93adf925850851df7b394e9bbecbe4d72c92f2703"
+ "b6d60896e0054c59cafa5e0d286c812b23e537885e4c3438a772a1610ae9fae9"
+ "18e34d4992c7f263f3e8e2f980b8",
+ "021c8c959aec4729688768930d67e20299dd47902db079f239b8c288b0a70447"
+ "c7196b84912eaa5bc3aff6ba630c2eaa3fcbb24be463836531250bd4c4f2a1da"
+ "68c8bf4f40cf5c98b685ebeca4d03e76b334af0b1b34488b582e2935253572f7"
+ "fcfaa83544e7fd52ef458acccb19301a4ddd50516f16a5fb78f3959900dbcca1"
+ "f2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.18",
+ "302ac80e30c6553e9359df85b1e24a16c862a20ff4fd9d5f146be281dc3066ae"
+ "b8fa00b52a99",
+ "326c99358c4e5fa4d2c043f02f92705f791cf712bc01045b4cf349b42ae5acfa"
+ "c3783811bbf07f34bd6c851955cba4a8b2a7d139a78bc4d88e3a88e6c4cf494e"
+ "6a4a52354145e11883cb5c78b572f30a51ed23f2564b6960",
+ "02032987ccf75a638624178064dba4b72be539e07ecdf5300356cc43d729fe34"
+ "fb35bbbf5a32172ce39ea1fb47d38e497a03b601eeafdaaf99a34fd721184af2"
+ "e18e83d050a4108b15e5e3a27e0e636df8d94f981658ebdecdab0defcc0daf3a"
+ "c9a27b3f22a0541d35002752e9cc4fb2582fae2511a132ec5c228a8872bdbad6"
+ "87"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.19",
+ "00b38201746dcaf40348af57bad72570caf5a2855fec6c42ee22dcfe64c997ec"
+ "62a5c975624bbd1f8ec916",
+ "939105c004c01aa9f47446d3ccf530e9b2174c50aebca0a95cb7a4d83954efb8"
+ "039e591c1971d776cec761129206db7ad3dd871668255a5550ac4e948be05c16"
+ "2220dcefec13ff1fd8a5a7f78bf715b49d03ba",
+ "012ba87dc03a1a38bfedf121ed8722827bd97dd63fddfdd59050c53c5e7b49fb"
+ "7ae6038487820efd5fb9714381ce8daeb56d1350bfc67df091bea2acdffde929"
+ "2ab1291cc9751d9e39a826f054ad1f33a2b794da50ef80672917e0b3814045d2"
+ "3df45dba3fdc6f09ab0a018b060aa9fafc3a5d19d5eb64310bd602a9911dcb7f"
+ "24"
+ },{
+ "PKCS#1 v1.5 Encryption Example 8.20",
+ "ba2833660476d8731507669f50298c2c68d44c53e3d0a803786e",
+ "86ce8e92ad88b1462a171af28b4e99088c0498a29b4ca5e66f64f86adec7f964"
+ "e8eb8257c5c01cda165e0f7511db147c10bc07515f04f05f52d2bc89228357c6"
+ "61b43f43d542dbe77834091c7ce70b182e19bc936c30684a831e2c3b8a4a7446"
+ "3f0c9f1b",
+ "0112ac2898a25c1328791fc96a82b72918b51a668c540bcffc8e0b3aafe205ee"
+ "871f5eb76ad116d304cc0442bdb1af5b9a6345827e678e40e33fc858ef6c456b"
+ "e43652bb2ebc3964b4bf4a93a8eeef8404aef1a044415a156f7cfd7995ac25e7"
+ "b03026698e14489efcc1ae929658bb663de0ac44a7a55caa0b0b2034c2aaec13"
+ "4e"
+ }
+ }
+ },
+ {
+ "A 1027-bit RSA key pair",
+ "068ef0b274157d7b5ec72903865956183e0e3462ecd22114cad4c7baac94c7c2"
+ "c5e6cbdfa2abfeaf8d23182e9c08815d100d8e8f621d3cd4afbb9985966fd6a4"
+ "182b599088a35d77fe0178acf7531c70d896ff788edc82060540efefd9f3c24d"
+ "5be69af7f2f44485b19118a468814fc513e3a1ced67791f9036eee56fa9e2060"
+ "2b",
+ "010001",
+ "71940be6797bb3285ebdc20cc9275f5d775588e9af6f687a2e39d2c191111076"
+ "95ddede391d2196b29581df3154a3712fa6fcdf85bb4fd48641f071ffdb1de08"
+ "a1d5921ca10e68dc041313c9bbcb8081bdb5d4604227cbe57807416574d1a38d"
+ "a0b2344bb215b4182b106b2b534a8d3206f2d7d303b8dd5bce292abf75cd7649",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 9.1",
+ "96ad3ba4d29bdd3525bbc5d02e88c0133ffdea409474db34df733ca59c3a232f"
+ "6a64c2143ca131a7f18d005bb3aa6ca1eabeaa136bec37db111d4d8f61",
+ "10e9f5093cec872edb16162b6bbd5212f6101a71d51dc1420cadd1d550faf9af"
+ "40f573d3e3ab6891d8a882ef0656bc30062a05b1cc277a11c9ba2efd5103c56e"
+ "23",
+ "04dec01bbf8e0c2296d9f5bc2d2ba895343ec30ec54413576d8084b93143cfa2"
+ "d2033bf4c2c2e03f5b0259edf14a8f3e11698577652a2ab9f51ab0187cc75175"
+ "c86dfc9a45b1e4eb8b5447a94ab9b5177a0404ba49e57f83c93f7fe2de241845"
+ "f581f64212437e0c04ff34ea1dee6dd28f6ff3367235441374f0f2ef71a9cdae"
+ "9e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.2",
+ "7f92abb6e52ed5d420849ed6ccab36c3d0849255431e193d67bd944b6c0fcefb"
+ "7729cf5a31",
+ "cea968be78ab5faac227dc3c6fc9ced49f851ed58b08d5ca375428489afbef3b"
+ "f5ed83746d959a0a56e9ac66ff2e7c8b8c3ada97fa15dd7f991341747070ccad"
+ "6542bd7f4b33f55604458b9103ae13dc89b4e62ccbf84ff73b",
+ "025a1e65eb37f4b328cc31b01724f83c26ed8d18a65165213ba0eff7ae767ee6"
+ "0b9927761a0694b5c3bb64b7e03996a3568d6fd1ac6b7a8b71975bb0716d945c"
+ "02d47368966fffb1d449fc6ed73e2d19831b86d1876751293669e77d6e12a0f0"
+ "c962dfcd400fb83ce8260716317ad5fde21849aa6f68e70ce0b5b31142898ad1"
+ "a2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.3",
+ "f5b535b63d535e2137732c301337c953ea2edd58a78c2025832dca9d6bcdad87"
+ "c997c906836b2bf95c83f03f7afa2901346d674aa69a1b47f6b916fd4b",
+ "c89efdb234e01a2f07762957e8c0a4f91abae6d4f360e89a7c486c5549f3d0ad"
+ "75777f0ccd97a0975e9844d986870276c9825f5d1eef3d1b487abcd19b512d08"
+ "be",
+ "039a1ce8c0916251a01e5fb6615d2e11982f4fae7d46df21daa298f2c74611b5"
+ "5816cc27fa37279aaf5902ecb6c839fa900cf3af86ff40a447dc402235f90667"
+ "9123f3cd381904f33eee353ac90d5f7f203a6ea891351adb11601bd9d6b0a024"
+ "333a2455be1ca62ed82cf37cf8de4e2392dd54e775033c56990bae5c4391b665"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.4",
+ "a7cf29820347a52ab9cc4204bb6ac1bd7fd90a758a156dfa9ce71927e74ee215"
+ "98708cf69cfd7985742f5027ffa710",
+ "109f0d6ca0e13f504c07d84a5bbe43ed6a94acbafab048893605d341c5d28d85"
+ "44c3fd284350f2c22d1f367dfb9b6a6751d06aaeb17c3c0a1011ae38fba4e46d"
+ "4e44c482879eba0644374871b5c53b",
+ "0448c39cc457d6ccc30b0d76ff5a132e00c75d533646b8440b13ce730e1b7ad8"
+ "3bb2ba4a082bb5a33cf41466e067fcf16c6a29f1879f77e9b0dbf3ec080575be"
+ "bac0c5676baee002d573d1bcc8a70fed2ab67943efc9bc13139e5d8dde2cb30e"
+ "1b934f50cf6c4573923f7398de6670cc26341f3e35a419361e59f60898f2692b"
+ "94"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.5",
+ "b803c7ef5f9a9bd58401",
+ "8e7758ed4d1ba4dce088926c10b2f3d4c1e2671ae72e659f721ff7be6fc035e3"
+ "85d512d07a38dcca1eb831fef906100444ee995cb07bc26a5dc92b272a74a92d"
+ "2149732522d539434fa4d03b07cf9699958c19891d1d5906aa36d0a8d06c6fc8"
+ "7a4551bf1858bdfed5f886cc8d31ee4c164e981d",
+ "04b62d4d4b9c1c3e051309795c69248aed389de24a6c79538a2d51d5d03719a8"
+ "a528750d5d254a1b914096db96d83d2d9aaa2a165bb1346e44c3572756c38d52"
+ "f8d307c04e1efee5847822317ab469345b86c7b85b541541c992abea98d108a7"
+ "dfc7091c30c6685af0e33d0466ace4ccccb34e5b266d3d6b947bc7c0ae34d5e2"
+ "64"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.6",
+ "617ea9e4a56c4ec1d3d7fd7f3281ae7fa932b2a0a6cf55eb6048145681b3588e"
+ "df701269f89fe64aa14ad8df0d46796131",
+ "64d7ebd04850eb6f7ae1af48120a80130f32edb50369640b222b8d63eff65712"
+ "70dcab3176d0247228dcd1c3f3cfd51331b756a8652a14ddaab99396b9199a73"
+ "8750d69efcd377f184ae19b5a9",
+ "02dfe72958595881d807566d3e3607c022e461fe1dbed3cc6d63dedcb7190f06"
+ "c7d24b4f03264cafbb7482ec28b9ba489d03115af58fde475eda58bf0155cdf1"
+ "af16df206bcd125704c3e315ad3d9544b9e2c2fea810ce484556d29e07adbf0f"
+ "f461ccbcf662bd74959a437d4c8011ceada5502af7676d9a1521e3189dafde00"
+ "dd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.7",
+ "c91f2c98c75b2fd4cd8d5c7ff2e769b12f28f313fbacb51b5e5014dfce9d635e"
+ "7c6b2d88af5eac30d162b8ddc22ed8bc7bee506bfbf31e51ba48f426",
+ "6c445961f86fa298d7647c2224d95bc127dafcbd5b9021ec7e9ebde96f5d7a76"
+ "f4eed0ac922a6e93eb3b4c3c43f8a57e18294e1a5173b0f7e2dd2c4e577a4bec"
+ "e714",
+ "03a885aaf7b7d94fdae34b41c3741766a409c1ee0232b1c53e5f6c5aa54ac1ef"
+ "0e5bf99b9f7df3e9b00ced9476ee1adb8fc5716891f54d45ceda70b9db3b8fad"
+ "25e77795af1481ec492184c49e9df823ee6466410f65013ce3c57916635da830"
+ "677f932bdabab5c0a208d7f4367a7eaba75b045d25acfdb415fee05219a58423"
+ "7a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.8",
+ "7b1c3151a38d32ec7b82c48c000aa481de418e803b673d2e9a0fc3d5e974adcd"
+ "cebd3c2a8f41142118a55e87d04bbad5b36425",
+ "b0f5be9b3f237cc5afca5a99fccb77b6efd868947f98554fbeceacfa884c1515"
+ "39d7cf423e726031bfeb8dd2d4f301da6bdfcad6e5816582addce10d85d5ee1d"
+ "0446f373b95ee160bcf035",
+ "066c3009dc6cbac7b8bd5141c55cf86a3d7969d585452e3a66540f9402dba215"
+ "e3fb3a277f0d3396c8c008af19913e3d91e40f867606b5bf54304c0471dadd64"
+ "04b67a4857bf52246c0d601823dd0380c6609dacb92db602e55764ae4650df1a"
+ "dbb4b95fa5af4bcd1121f13c0a7323ada8c60de3d081729d197f9cf8e27cde80"
+ "b1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.9",
+ "b293c6f6d05d1f38b561ea3d0d0ad6a2af8309bb9adefa778fd6bb9fff3e010c"
+ "404c533997ccfed7e1917a669261cfcca4e37029991d2de9b299",
+ "87bd2f6bb48245591d65f023a65b63bbba8419792c0141092b1db1be53e8c9b4"
+ "df95f0ad55b96e5e57615d214b4977870a272f723166c62045765e6b4a73a7c9"
+ "ebe11d24",
+ "03104ec6c4ab9dacae427fb10699bcae003da56f6d07509587145b733edb5323"
+ "9a6f422286839cac064adfeee5dc89780cddadcc807219d6a97b85c13f27937d"
+ "70327f82cc36a5da8e456377fca23aee514e044abf1f66c3e7bdebc2cff628bd"
+ "524a0966e2638d2833bfa343ebc741f76b5b70a1136f4abc602864a2ad43a791"
+ "bd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.10",
+ "0838f4a592",
+ "89c5898c6c3dc6cbdb1acb2805df5398f0b3358a18e5e63c14d20c98d21d9fd8"
+ "b2ecc9a0e83daf0c069268bbe86feea51c93791b68e5d93b745feaf6adc42b83"
+ "c309c9cd3dfe1c06153ab8808556189890be053a925488d029fe5040e3e7d5d5"
+ "31b32eb9d2f4eea22111b38a6553f00edd2365575bb949f363",
+ "014f2797dde8d46018ff23d89be2e3ae046eed3197c879c60e26f3d2400866eb"
+ "50d7b45f6b01ae9ca006847efbe9abcc9bc3e35690072b68db9ecd926d945f78"
+ "7b27c3753bf96b2d49983084142c42a1261aff7b17ff4b20de9bffa58624ab37"
+ "1d4ce2f96469a8e1038d5720b81cf042dc78bfda9a3ccb6160812ddea158bd2f"
+ "5c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.11",
+ "12380c5e80bb95bbc8857357fefd17bf9e509627d28cdfcd12bb131661b342df"
+ "a6ca672e13a8851fce19b1a8caf0e33cd6ef538a05fa54269a1378e7",
+ "880331ebe91ab6ce1684d9af5d977eb426ca7156e0b6f4336c6e0933d6fa4878"
+ "2c0ac969f3dde61d8fd74c47fe9e3061710d245b1d3811042860c1f48d2b8ffd"
+ "809e",
+ "046c545ff496c21f690127245418cc5fb18f09102e7aca87e26e2082fc16f62f"
+ "e9f42a722271a79eaee9625a7e632c1936404cec6211d823863ba02c6b0a8319"
+ "58b4ed8fc625a2e52a054f8f181f130f8bc4b1dfbd44b70a35b35e9c7f4ac55e"
+ "e5e2cb068b758639b2cd643dbfa82e2d9720e489f5c821d8ebdc1368a9d3468a"
+ "37"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.12",
+ "eee1e45d18b147c269a60a9c642018ed6cd1157cd0ce2b2968dfa4b497fc40b2"
+ "24bd861e2535122b",
+ "5c513e514452b14aee33b61760b858c5357c7d7f20e4a37c7eefe419cae3fd16"
+ "f9d83e5ecde19ee63285ddce6680ee9464fe83756e9031d6379e6a6b384ce277"
+ "bc642ced83b29cf74b72cefff5307104e183de2ce6a1",
+ "03a86483cbb72c15f5a6932b012f40c4b173333b2686f4984ba66e24c7cf4441"
+ "23ba2ea666a1755d09357beea4379ce3cdb0a77a6ee3b7ca60db682417f7163d"
+ "7d3ac7352811bb94c5b771f3d3fda773e5cebc8bc6601155b3f4e4b4ca85d9ba"
+ "b8ec258cecff4433c92e8f863d96fcc79429498a9e1790330bc487c010d79924"
+ "5d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.13",
+ "5509a5c1ac5489dcb765f37cebbe7d81cf0276b1f2cff95d274bbd04",
+ "76e81a51371fb50741141dcb31d51d1c461fcc026aea852015d468740b452340"
+ "5f95ba879b0869bf031a60654fc4e568c1957ce4e42a350a95bf8cb2a8b5fde6"
+ "dcfd2505c037a29ede689c53d83219e73e640817bf8afc9ab004ecaec843e4fe"
+ "4e38",
+ "0255de280b71afefafa20f241e081b7ec6c162ddda1884fa9f825c4ce7636efb"
+ "c11b84a6ebea35892571ac9e6b1ad8473fa573c883c9f215a19580c3ea302f88"
+ "f44f48e4d95c3440d4931f1766a1fe7e790e5d38e85d1f63850a3c707ad8977b"
+ "88c38cb9ed98345cd350c3dd45309fc81cb46276e4ad647fa84c14125efd67d8"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.14",
+ "025381a55c8e487d7f4ff7c36cfb375007d19f9371136e2b3df4425eeeee5d79"
+ "c35261fbb4ea68bd91e8edaba2329e29315306c7d71833155b88",
+ "aa310f62da90da4a2028b381399cb7e0ed3bb510575c9bd0f638215baf7808e3"
+ "245eaf38b76e2652290b7cc620907cda0cb7af073c122ff83daae1986b43ec1a"
+ "1482dba6",
+ "049bfac6410b7780397a49fb8893b24d903b3600f33c782c1475b5d24b4f4e88"
+ "fd1124ef0645f3d391ed31006dd1b7c264128d0db9aa0d65a09ffbe29a94cca3"
+ "58da64bd1b72ff55888808105be091ae23ea3f347505179eccb2410d89decb62"
+ "330f36c744262eb2b078b4254bcdcece211cf0574a2468e2a1e018bc31f50222"
+ "35"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.15",
+ "073c4367bafd4810d7704460c783d350f7ccd099472f79f7fdf23ef0cfaaccab"
+ "9571df53fde4",
+ "f95a3996def1cafc1a4a0b34146b73de6b5a92cb812e20b20c122a251e6b22e0"
+ "469c98db128d43cefcdd80c7ff36998016a892a8b634b36b9b0ce87ea80b5dd9"
+ "fd7a082914e73b83a3841de51b71b1a6b7ef7de4e4b88edc",
+ "02dee48b0f9953ee12c718b303b0c89d6150ebbe83ad624e117e3f2704a0b17a"
+ "2ebee8385256f0e64280fb06c3b146c099af23a9f24793393781a555ac4ea2d8"
+ "8d785d8cdb6e7a2f8952d2503ccf901f1239f6f7b1acd44121c365fdae370746"
+ "de4526e7c6560f87546ed577cf9798bef47e492065509c49212d370dea0522d7"
+ "94"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.16",
+ "bab20b9a6a532e6f8af078b3a185e0aa86e61681bd1bd775044a2c958d61edc2"
+ "51607cd9f31148f5a911",
+ "376cf018143b0ce67021684cbb36e4afe2ff9de18bc7f02bed863bf1bc346631"
+ "9e720feef19d38e26bca7e99d4096a9eed8de5bf203fc7dd9c8485dfa5b69075"
+ "ef0cc037fcdfb55a0c928cdac0cba0497eb60e3f",
+ "048dd7509918430edabc01468db7e287a7381e428b5fc93ce8defd7f49d5e934"
+ "153043d137aca9f7b97577b70dc01680f2dba91e932b53acf2a7f3348f5654b2"
+ "cfcfe75d48f0fa4500d1ba5d29247ff142d6b980e11b9dba6883f73bb855a24c"
+ "c4eb9068236daa0f2f93458d72726c2d8e31259acd3a7fdeb6feb5c6d2ed178d"
+ "db"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.17",
+ "19b1f4cd3dbdf05b3d5f1680856c5a744f5162b520bfcdfc9887dd92be9d8cb6"
+ "25c725ad75f4f2caa5ef51faca71b5e66f84f2fc6f678ace809d76b842eafe",
+ "78a71882853d85af165cc0b22ffdc8873df49e2d6cc0ad0b0a995b4a259c867d"
+ "c1aab6428a5b8e9f3be87d87f9e6eac550f4df11368e7f6cfd7d0e476a459b",
+ "062a78db5ca69a304810789493db8cd644fb294e17fd364532b8ec17ce3fda70"
+ "476465624a60a6ecdbd5d97240c8d89deac11dc30d7b851441408edd642881a0"
+ "112b62f8cfde34d9c11385c29189bf3893a6abace04a10aa680cd3a6ee002c30"
+ "7035d2399a2a60b5a7f1caaf0584d10fd06d6efd56114c05e43d42d834f03e3f"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.18",
+ "8cb73bc47850c17febd34ff4b7323b5053030b96221403cdef45dec65ba60ea3",
+ "ed6478614881ebe3fdd6d9ee05f2765fc8a3eaa58031235af96f86e7f2c813ec"
+ "0480661d1c2b4def742b2e41419df2883ed58679cb9adae4dec4cf77f8bc2941"
+ "d033f8877a906ddc88d6dd3c5396adaac03eb2a7094c0fdf0a44a6b923ab",
+ "03978d4effc6d62f232bf46b4290c5011d73280ab0e80ab9d6050a852a6679e0"
+ "17e170d9e7156c8dcbd46cdeda70ff9a55168b9fdc0365b8aabb909aad40d595"
+ "c90b9f00c1e00ad6f01d544307b254eaf4255de62bfd8a5f7e79dcfc7445cec6"
+ "3df0c2bd0ad96cb70242b30b3242078816b58b0a9ffa16f1d86315f8a1cb2f8f"
+ "6b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.19",
+ "8ea55643dfe7cbe075c17b93c6ba6b5a74ea8d1abab9c728ae5b00866c62880d"
+ "3c00052037cf802d2cf2a8e1bea58c7ba604774d4f80bc04",
+ "af9d9d312e22570fbc4bc85a445ed8d899660ed24cf0301533946e5cb9471a27"
+ "c510cd175591d23d363dc4e3e69c7bb465517a4cd1d1ce413e1016aeafd55d2c"
+ "b9debcfe4b1d",
+ "0587111916bb42f84757691efede7eb7796a5cf887c37ca9f61b451fb1bade38"
+ "9cfc5fdc219841bb41da827452725fc82b4d1ade569ceec80579edb1b4b15b46"
+ "ad7d45b245988023ea0dfcb3744a692eb9aca85f211010afb1e9894f854a5e34"
+ "fe89aa051968a3b2362c150c6d970edd82b9e2d13b38c3c2956d9150088641d5"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 9.20",
+ "525cffa3",
+ "0c99304cc6263d1ee2446e248c27112c8f96da82515f06f812398a88811f39fb"
+ "056205c44d6bd4855a62c21c601b88f80234e23241f716322d8054a84a1fc3c8"
+ "46defb61767cc4d816fa7b3747f8729bf3372ac2c229d052f45bc42fc38050dc"
+ "a3f2632e6007b60853b7e0ccb3daa494e55335fd04f13d5fada7",
+ "063e4508e5312b5c38694de82a71eda312e9aed05bc143d338f7f22812d93c28"
+ "65126a9b3a42c3ca19edb34601c0b28a75663b18f239f5adcaa4e9fa9f611804"
+ "726fa12962bba3230cb886d66782a47ea9502a8371e7573bb6b0266c33646bdf"
+ "53f8de368ef205b11a85baf21daf3ce7a2599f008b9945eeb186ec192c540ac2"
+ "3c"
+ }
+ }
+ },
+ {
+ "A 1028-bit RSA key pair",
+ "0b52cb6b5c3b9ec5aaad894e5177f7f45b8d33dcbbe96a5b26f30072bf1573a6"
+ "c41fb0a97ae1e52ed8c25c62b98bf59de7b68ab98c2d8b93c4942723cc4baed2"
+ "b393c07b2b11909c732df7c1dcbb433a839d46f428e9ddc8d35fd33eed298180"
+ "f75f2d5c9fe8534f0347f8685c28c437ea5b811a286e810c697a88cd7e45364c"
+ "1f",
+ "010001",
+ "45cc1417b26fce3e9fd31089b1a3ccc46f8ff21eac2e1d67c0ae20152dc50d1c"
+ "e7ce6f26404e2e6495b977bf13f9a405b24580d6393a85225496e4abc49ebeff"
+ "de70cf26766866f276e15b492af8033f1bac7f66b71a3baf571ffccc038a4886"
+ "9394cca3fa004985b434a51517877eae97a384947f01a72cf4b20193dd276481",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 10.1",
+ "5922d09fdf6522802fbcf7a28ec3d9fadf607203a31bd0da963aa0315f35e1a0"
+ "a374d487dd0862a6f6bec932b7db",
+ "61395a0fa12e1ec2ffea2a8890653e8f378dc46ce2b8aa4a0a1c567b30e59c3a"
+ "33a668989714fc3d45ac886327e36c345da858f903d1e606740314cb808d86ab"
+ "c31b49b35b3f20e37929dcc859d59141",
+ "0439e7dd09af61c0ee25f3e5c2951da49d3fd708b297a3055ff9983a9ea538b8"
+ "3d59dabdb85daf82ae7bb1978e7da2a6dc0587ef9c732ee688373fbcbfa2dacf"
+ "f9b3c12f704ee14f8324bd4cc6bf9dcd3f0533c3b11a0d38dbcc7bb7ef9a7229"
+ "6b6c13dc42d7ec17f851a51612c7494c6368a7fbec93d22e8f9b72bdc0449fb4"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.2",
+ "5fbad43a910a290e5055d514e71c8eabf1f93320ebd0da8f90d146a8f3dd5c1a"
+ "2c720b93211e482934149f1d21b978f48a0bb8e4cca3f5d45d3f3e3ba8e1",
+ "21045261804bf754bcb8bf3498b1ad10aff33da1f225eda5646590458b20709f"
+ "c8d0b498907a8364ce1c436b6b1e73181c86c677af45c17f9e4af3759cad2487",
+ "029f64ac330134007f77f72c37f4177c24d660be4ebac1868ad11f9e3051b8cd"
+ "77c4691199ac4919db2ed363740d2dde3291f10d9268e7c7de37ea421ebb1fad"
+ "6529f292192a9680ba963eda9374037ab9529a486f35cbd29e09ea98a5045d9e"
+ "16bb8770155d70afd217a146862749ec1ad159cf6e6a63df142b8246d844a737"
+ "2d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.3",
+ "22bbc616ec6ef3573156b41761ac3bdb57bd9b7036edc9a6978875e2a614cde3"
+ "efedafd3889a5dbdcc5fad9e9becf8a8bb8033ff91dfed604bf8c6e9bbc7",
+ "3b47d2ca9554b34f9429578d4fdec5d96eca89b68172d1db1356b3da7a69f158"
+ "4d4c846b18432f02f259cadc24e154ff15f806f25343500e13b5be43c7b5ae7e",
+ "00c4e6c10c255e4beb2b31c1656846b97ca23a3ba32ab19c648520113d7034df"
+ "a46b0cd23d7399a93cb02f1eba948318e3791c306a2eb9c0c56d8f7e83250f83"
+ "ad492fadf7831769f02e1824347445d0419b98b8e795456532300b92d6e455b5"
+ "a4eba853d6f7459290ab0231994853a8c07e54f59c624537080289f93143ebc6"
+ "61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.4",
+ "316cc4450a53703c058c901f507d7ad0cb6396c551d4f06182abd3a43aacbabb"
+ "3159c026b3e7dbc160f41953317e0f20808c",
+ "c1ecb1164b3e6623f0d9b9c5ebf99e788b7bd94eb74374f61ed314304caf46f8"
+ "4a3fea1ba0e47fc8be4197d1d2cd4141cb9a615d89c4bd9110ca6ac9a560f076"
+ "ebe69b74a10fe9ccdb76dabd",
+ "0616b8bc772c5564d451b128d9b1364c9e33b6e558ec67f2105c9800117d0b73"
+ "ccab9db51d967a9d66322cbc5a01746e4731dd7d04e636e64d35f2c86ca39d26"
+ "1492176b8dabdb134be94be51b6c023a0d55fcc1f04c94c86d477db403b04fb6"
+ "c028505724793840cbf468aaaa91bc54e0d6477ce648cedd1276f2ad2d4d423b"
+ "6c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.5",
+ "d54ea37cbfbdb8183b3b547f6df2d5d63c415b1c44ed6393c697b4d93a97fa0d"
+ "2f4d300a68e98f7fd0460701d1579d9683612b",
+ "d1ceb0c072d6888fa91a757cbf50d66976bbb72e619462614d5dec0fc0bbcabb"
+ "070789c2b0895091b8fa9c7e75ab20b89758f97fd047bc44a568a2612d0d501d"
+ "15d4fb82e77528796949f3",
+ "03c138c79199b0b1700bab2e63e1d2a0031ef602f7ddf1ed3a161a5e70f16451"
+ "daa101f74cdd6547a7c652c7329bb1737fb14c1cc0c0c3e7612ae20ee021ab21"
+ "d70bf9517b4d33a9d809612e7f426885b79b312e266e42b202b571c66f9a107b"
+ "8fd7c56c050a8e1eb18956db06a0209dd16ef2d90524db87917f34006be6b15a"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.6",
+ "f64b2511cbe3cc6581",
+ "daca1963cb3de5245779e96477ffda277f4b923fa9a8d9385d523169233f5879"
+ "a3c9fc7a38e1b208c32de40bbe1da077471e61c8b9b7093c41b0a65c996432d6"
+ "45521184a66afcb96f07a8f8eebb6ef817e027ee2f379545239ef6f9c1d0d860"
+ "e82144ec71597f246a83ccf660ea4c70ee1df014ef",
+ "0508ed845c96238e3a07e8ec027f7b098a83f03eac1fec426f4d6005b60d0735"
+ "db0537082f23b750f6db5488214181e114cf1f7207419ca293750aa766fa7a5b"
+ "9be00e37292c23231c6ab3be2dedeed321b0f9cd832c5edb41677c1ab983e7e3"
+ "ebc8b51993821d76df2ac2298d8b80ab17c38b3853f18fe309cc7bf7c4a2c27d"
+ "63"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.7",
+ "852649015206e2a4097876f8abb9b846",
+ "034fe34e20e606a8dc7cbcd0d6ab3e0797c5dc4ed7868edc7959893e58137d26"
+ "32b2c5a29a8135c24af699b59d68103a1f423393e3886e3fa854e39721501941"
+ "3af0b0d4fb1bd69bd4934d4d1e2e9f3b9e7c46d4984fe9e7a37ab2f1c78b0b8d"
+ "9cd8fabb3d18d4c506e2fd3f85ae",
+ "016fbf2a7d368071cc7be59449354b9de05a85e1bb97b2514b52b8d1f3e26994"
+ "e12cfeda59e058a2f3c8792350c068417f99441bfe7417e0b5316e163ba8d1f9"
+ "e32c59a4449882f47ad9b24f6876d478d3f5b7d2753573e3f697bf64c7b3ac22"
+ "28ce69e75e8e14ab93f21978059a143b877c6dd421b6e20b0735a53605552ab0"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.8",
+ "f4fb50beabecba77e71dd8d16c975a86f619ea7dbf41969a24bae2b842c269e0"
+ "b4d6a29e829dbe2e49799c9ed971a30335e6ed9bf39d124be0f8",
+ "9dbd92daeeb82bde816c593f706b1592568522bca0797f9e811dd9dc0e896e98"
+ "4a4a9ace77def5a9250db79581af33fb6de2427d1af6a5f6929fa8b67bad023f"
+ "04b3ffd2",
+ "0292edfbac38e2224545af8286232763bcb18bae13709799e3507758d0141ac2"
+ "976f30b85467d783abf6fc71df619e1a59e6234f27b632feaabfd9853377354d"
+ "933ef4ec5994c0d50d952e0ece0be1be4d38f11f66e7c3da88c83b4bedcc062e"
+ "09f9af95eacac0099c525f241ea7d565e1b768cb9708f3bcd59177b6766a3734"
+ "88"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.9",
+ "76913e848fb7b9faca91baf4f4420106a94d6ce25d1497fc4e7f859654795d7f"
+ "24399f3a1208af028e61678a6d19a18640b4d50f75558600",
+ "9ceeaa2609ba90eb61e4f749c4cda01aea236881762dfc150d97c11eb6440cb0"
+ "57e53c3fd9b39e560a46e9d3fa3af3fee5ee2d02fa4249af9998f53ed04db010"
+ "e96d8a01ff6b",
+ "01963089c343ed88b56d6acfefbc655a37ccfd96203f218764695ad310c0b266"
+ "65ee745eb010fc83be8c20645c4347dcd944655d9fe6cd9877dc70e5c188cfc9"
+ "a66e71da745cd3e1a7b7f5a1b25b4fc1470adfbf7d8e45fb107c5aeb50ea8b56"
+ "e04ca55b9b652ad834d9c96577b642ef33f164d4931fb89e0c8c6bf91708fda6"
+ "db"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.10",
+ "c339f857e4d0231fa37c06f0956b4d53a6c58e0610d8da4317dc8411d3a0f898"
+ "49b94e8d7ccdb0c7d5330c25",
+ "2490816ac96976ca725eb498e2ff040afe3d6417d32e4ffbd9fc9e3fa68ce849"
+ "c881be379f17504b97e1e0d22d32ff8dfe76bb4549f713b5b8d870ed3659ddd3"
+ "984b6fb39f6ebddc1177ad698d90443968ab",
+ "00b5fb7b1e9d71df8b16c63a1a496e6f7bf772864cb411552b50e0b7f15e4597"
+ "16f5646243687633a9106c346c8c6b7cfac750b4566b1b88aac0acb916c07a78"
+ "0be06df7975ccd8b726078687a8ea5d3903e04ab1d23dc9b1ed36000c9bbc3dc"
+ "8161e9483a18abb8641ebb1fdd0266c084bf0bd09cc94eebb9283c5a5f74e360"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.11",
+ "475865a57bdb91addf777cc9d0a17a71a9f9710a931bd0c3149b2391a353",
+ "562f7970946ac4cf05edfb2634167e14d6658d24cdaef75b407c9004818efa75"
+ "d1645e8152d1fc80d699dfe99a27a7df997a8a66475aafce419598e2a19199fc"
+ "2053e3acdd07fec8ba61f2b03efc7deed815cda8952e21e3c0b9a9352ab36f5e",
+ "03e268d7d180d03c7cbc8507ed1f830ed37a7995712d7d915732243de685d5bd"
+ "99a14a8e86a67cdd60dcd90c339210835a46ceac1936ab3aa9c381882d7694a8"
+ "383d6898e27344bd156fe9282c71322625d68d3070eff01ac8d595f6486d79b7"
+ "88e36912fd3ccf284edd5fcee2409dca7d4f29cc182a78478bd3ea2362112510"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.12",
+ "9e1e53f986599da898d56dc1c7556fefcaa3395d8450d52b3ba7",
+ "0b1763cc340e6e3978626a06d6efc40ded73db535a822ec04c9924d9ec40d385"
+ "2015d7e1029c1393adcf0150308acb273c36356828a477fcf9a29acab9093570"
+ "425026dac14da6cd304cdaa54c9a4c5a994ed68a5ceac7e081dec4646e237e47"
+ "1e525ef8",
+ "06d519a730ea5f549fe19e301ba5152d103a3ead3f89ab3516ff7b344c4f72a1"
+ "c26aa90d5a01a2a65193d3cf6341e59a31fd2d7dfe435c0984d1bbe81132010f"
+ "4358eebfe83faf241e7f35af98b7c7ab91e4f0e8a32a2f57f07f49d5c21f1e13"
+ "80ba0e179a38d3a2ca464fc14d2b74a03a8884aa857b66014702b1bc4e7cc5e1"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.13",
+ "1ae31e0cbe4497ba43c5d15f535fe018841c73145767a6a4c8",
+ "8ff0faa7a2b4ff553ccbb20ff310ac5e0ea92818562ec9a06064f5de7986b4f6"
+ "c9aea2b9f0114238e5a499a8ae20eae4021fcdd8f060c993a9bf642da0256739"
+ "334808e388e1da8237278bf4f47e05015a8b88c5420cebc8bb37ee4352837af7"
+ "6470184197",
+ "04a210f76c0f8493990953589886f62c1c4825012af44bdcf2c99b32a70a17f7"
+ "64a3a97b2b047e39d80cde154ebed5d2813ee84ac9c8d6ec6a96f402dbb326d5"
+ "a6e9c0f787c15e9823c508b3235f3a008dddcddb079e80ff50fe37254a0cc468"
+ "297ee33253a74c1e037026056958ad0778e0aa1250df1c14857cb0d71aa6937e"
+ "31"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.14",
+ "a6e3d1070321d8ff76b85c7093faa04283",
+ "d160b12c76622c3d34d85587e6e81cf054618a346b6752d5369a71c492357a13"
+ "4b7f67f334a4f3b328baa9f0071847d0dafdac225d7b7f071618ea8681fcd2d2"
+ "305c2f64631e623185fc0996e61c84f4180c637bf6ea2d060375f16a65e5b1e2"
+ "b865285da3d8fb1b6a60ea36e1",
+ "0a7003b5861a85a8f72f199dc65c17fc58a924bcc40819e28c9583e821038c00"
+ "05365e909eee4f3266f59a84e325b1bea9d281b4823f2fce44153f03170fadcb"
+ "16a279b2c9587f6b79effc55a3c434e0bc5dafe9d4032648aae7e4ed1d7f141b"
+ "fe722683fa32c89ddd673c3f0c03c85459890ab7fbc1d9a814bfe9b0d12ab17f"
+ "51"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.15",
+ "d0bc89039ba19ee50a7382984e428aed88614f789813018916e2e7eb0db83da2"
+ "8ec23c04a0c2f76a",
+ "c64d10a4b52f490ab62a6038b32b23c63a1c85970d9345148394cd35cfd6f6b1"
+ "590fce8c675beef87cd0345e5cade8950945565426b6b28303b0b0393298cdd9"
+ "5c881fa06533ca9d2d2714d0f13785a61b3a17a78140",
+ "008b197558ca4ce5901458abd8e8fd52d989960f01c216efb581f861148d1a2b"
+ "44eb0b7c15ddc345dc83f9037ddb8fe2eaa2cbed9b1c1eeeaeb865bd29f44ee1"
+ "478c95e9fbf444828eedcbc0170200de3549b22c11e4b433798b9d63bb49f0b0"
+ "2daf5658ceedeaa93c0faeb9446538ba92eb17c85db5eea204ba2f49c3ce65bf"
+ "13"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.16",
+ "ce0a4a5939f6aa263bbf8e1e5e94310356aba57559c41b39442770b61f6b3c9b"
+ "5fe727f319522808d58019",
+ "27cce2d43c71318ed4fc8c0bdb9b791353199f3d89fc12ac47fdb6d88b44c654"
+ "5e9eeed9f4c68515d4f530b8137d7745713bad0ebb7052231f6b4ced187aecd1"
+ "e7a169d86cbd13d50b78be27c6545d8192e0ec",
+ "0ad3ae7e5a98652c1bf345c491903f5517c611ac310005877fa91abcee6485f2"
+ "778abf0a6c73878737639b2672fdd00a3965d7d3d8d7688e77b5459e145ece64"
+ "a9a52c3797f36107c9368bdf7990f3fb6c5cff59f4f8a3d49093dffe7406c910"
+ "aa5723228dae5a9b29a4cc4769af8bd5fd6ece8858a29db1b19c081bf0d6b0dc"
+ "78"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.17",
+ "03bfb259bd9246de3f71c3139c728574b44d97ad57bbdd67019495c2a2004139"
+ "2634e31aad63f63b",
+ "5fa4bbb70e1f9ecb5eb2147bf459d1d06443f025c08e364ccc1b160c16416fb1"
+ "74b44b953638a9688c5ea2d060171f3054f3ca3fe013b9e3188ee39da91f8016"
+ "d4b7331879351f322ae529864d9074098aa2516b44ca",
+ "0178e3a017ed2fc118bb2e0328beb28a98c853b9e5a5f83080c0f1017fdca837"
+ "9207722c25737a8915e0eb72c52285e88f6130a1cf56ad1d96ca2ce4b71ec368"
+ "947bd071f8365910c792575b8cd6fd27e523e85965dda92282d5dfd1c064eaab"
+ "6abeac65e16ae04f0d40b3bb68410b9274dfeea32a43f94083c10780353f43e4"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.18",
+ "162cca9ed4708dd10340e194c35c0a5fa49a5c3b5b247171203ca48a79e52dff"
+ "40f2bca99a",
+ "4d73ffcdc26943a8707823478da31aac01274b1717c50c6ad0c62ee2bcd55795"
+ "2ef13f15ffaf66bb4f45399911c6d65ad187572bc1eba0d286cc45aa4932e73e"
+ "470c5dc8293904025c863fbc9622370490c91c8740b094d8f0",
+ "042bce0dfceca9ff05a6e3f74a6a70cdcbe0dec81eddc88e467f47bb760da44c"
+ "794d3cdcab939249f849d1d43956641b0b79c6861c5f715b9d8d8be9f0766adb"
+ "3f18af7db36ad95ffcd7e0fac1628523e8f69adeb7ff5094a2b5bf92b9d0efb1"
+ "118b85392625fd56f88faa0a16d54730fbc5caf16682e9e41b7e79d2022f7ccf"
+ "96"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.19",
+ "8e1b52cb4e007727c4b5f65d7847f34916891ef9c73ad18cf271f89f182c693e"
+ "5289dc31dabc34cf7f44fbde579e645169ecba6e4e877f7def44",
+ "ba14748e6da7b6ac1833323295adb5422dbd19e2ec72dfd0aafd7bd07bfb97e7"
+ "db108a3eaadcff67b67ec7e4c67004c178346a125dd3b6ca552370594f7f42cb"
+ "334b4485",
+ "094b4030e30c8b462eca00f16bb17019d1ea3125f1c64c671cb00d46e3ad8784"
+ "2852b201496ee2b3d5422893a80c66a30da2c9f1a32ad4d4e7737743ca1b78ef"
+ "7d4a63c5e1e0be7e5188cce942956974ffd481e6478344230c37da5b25f6b599"
+ "a59a0580f1a000c25954f3a463f2895f32b05cc08821b1a023609f18ca7d449c"
+ "b4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 10.20",
+ "82ff62affad8003094cc6535",
+ "1c7f21fd02097907405eaa77ae728865721d9386f5aabc2e0a95f3edb05d46e2"
+ "33793ba1a388e4b0dda00cc32b948ac265ae6a2bf2c390a4dcce110d5e866447"
+ "28f5378136476cf71dc7baac50cc41c20148dd37d5f70a812a294e242de803b4"
+ "8b6340f428d3c9bca96f766fc4f44167e04a",
+ "00303c352e1fdd2af8a8e3a169b5dac54345caa335a71a37e938bf9847088656"
+ "8418ae98d0aadfe79d0c651b3f516e70f10174fe6322cd376da02f226d15b36a"
+ "bf6d1cbdab6dd5654d9925f7253ce991512a44e9fa152712d7b8db7f18337580"
+ "fe51dc32a0582ce26053f1b9492869b9c47df92839c0502f2db4cc4d0b204f6f"
+ "d1"
+ }
+ }
+ },
+ {
+ "A 1029-bit RSA key pair",
+ "11654794f4649a97ac87ef6794f6a6ffb5cdab8702c23254fde034f3129aad82"
+ "5cf3c0cc3880a96fb64e48d7595ede06c31d0acbd1f8ef9cd1f9f6f00b24ba53"
+ "45aba146d41c563baece3b2523df6a9f43018a5f0869b6ec993469886b5d2317"
+ "d59cffd4ede9466a03f6dfec175cad5a85443095c730b98bbfa0489b91bb2739"
+ "9d",
+ "010001",
+ "1d4c4c6e13dab2846ce685d0c493525bb0ad3562596db9ad16945d445ce67c54"
+ "e938f654542b0934480291ac21aed098e85ad6fec6d0fe154c3c342b16999a8c"
+ "ece7faf990b7c8ce87b66fe327fb352ed011323d2b819a36cabecc5aae7230d3"
+ "f8e00245af35af808862e54d925607ee8b58e6a9f3ad8fa728fce26856c367b1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 11.1",
+ "4ea8dfda3a9c2670ca9b80fa89710a",
+ "9606421b973ab4ba2ae22ff538707d7d4e563e8f05f20bc3381ff45b0c2919a1"
+ "b346b076035ae774b32af8ee566c73e20949684e447480dfa34dbb0c22666150"
+ "909a59e1bb22d095abe5025a76d60ec101c780e83a0ff159465c3e7ac0212bb3"
+ "8b2f1e0e6e0b54d35f4c7604c2d093",
+ "09bbcd8b63b29ce95226ec1d51912af39789fce5e77e7be67896c2c4e4c4376f"
+ "a428ec5d8a497acca9e0821e1f6de1067819c48a516f0691cbeacbb19d1ba509"
+ "f04fc01336d90f7396b43aa2f2b5150c28a45f35a9de1a2973ea10286794940a"
+ "b79f129e318cf97a5fd72b045b466d666e5de0b714f212a0b9052a0c91448e52"
+ "0d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.2",
+ "c6e257f3a1b35bbdc5cf420bd7654c52b252df32c570d428e63ea2",
+ "77bbd72b7b8fd28502ecf79fd1c8af8ebfe244327093b824795e95c0b436eb41"
+ "e5f0f2aec43363aa2c08fc33f287e6538040e4280dba4723e53292e0a67b21ef"
+ "77707985b72b2ecade280a61fa73d73dbb2fdb17f775f45fa175b77cb1067d6f"
+ "93a437",
+ "0d21495c4928c26a92c16a907f083335ade8eb0c20b0b45fe0e08ef39ae24ec0"
+ "b5057e6078dd7a1b9d102c24818557e90b83ffda14f3cc373c84c105ceee71bc"
+ "731a7f3571bd7bbba1d4f23ff4df0a84f312990ff771ff118f05bcfa222f11c1"
+ "ea01f6a468ca5a8750804098f846a86430ea23e9f07e2348461ef00ba62534fc"
+ "e7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.3",
+ "2d307f44ddff9c4535a06eda014a191304fb3fa8e3a2be88bb3b7be99f94d133"
+ "9c219a51ff5cadda93",
+ "5fab242dd9f2924b20d378a887b5de21d195769c3b5371c00f4c3f1b63268b01"
+ "0c31f32bb87c9a5229e0d9305f5fc83b8934b998d8cedf916f7a4d7268fe3be5"
+ "1235f8beac800d4fffca6ffddb29da4fa1c7769d51",
+ "0fafb61c3716c79669fcd1645246a0d3b075b28b73822015a8cadc88a22b7da5"
+ "3943e2544de396beeed3b0a989ad20a73ddcd191e8aa5caeb6e9088a4a3ae840"
+ "67f9198e924a9cfe1450b018a6b69dd23758e9251c76cceae840da2cc6251739"
+ "e23b9a42b63446eca0d61599a146b741fd43511c73663a923e3757f18a171c3b"
+ "12"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.4",
+ "1f033388554bebfaa01c",
+ "9d81575674663b3d877d4b0aa4fdc605470abc550b535272c8237018867c5022"
+ "cafe6a4ac83737e99c6ebafe69caa7fdca7027c8fbc437ec5232ce2e2529a0f7"
+ "03e201f7e5103235ba65a64794f190ef425493b648ed24a2197d0ab04d81c7b3"
+ "35a2dafd6b59c943a09b48eac35e35596291f5f7",
+ "001bdf3393342c3813ee3b8707eaf54647bade4c718a4b64547812e010c2b746"
+ "c88cdafdc316f0369a6c430ae7e6c50f05d545c3f798deb1d9a5bb69c5913933"
+ "c2d7792fae9d42ad76494dc9a3e27c211db4ef1985187a6c4d281c47721774a7"
+ "a11c1218d4dd267b57485877aa751f6c2819f81b5054a28a26a53df3ea3482b3"
+ "40"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.5",
+ "f71bc7374bd59c37775976f335244a36843c59e7489ad28b1a822d2d7d0b9a6f"
+ "e9ac5bf43682d63d636ef6",
+ "a1ff9844a73ec4b3befb1a860352cf9b75fc66ff479a2ded5998845a79773a8c"
+ "6206a36436c880a55e18711835456d91454b5ba132078f2037fbda7286251bad"
+ "d12d0a9781af3f5897cd947b1e1425f9705509",
+ "093fb68526cead010a54d116cd7d6035099bf1abffe9331de36486f053a80298"
+ "e4abfab40d3b03a3e7e925597338f1703b04535a9c87c65836f16111aae889e6"
+ "c8d90a2407d441a1c2a311cbd94611a42e93c73a3d21483fadb8f4e246d089f1"
+ "cfd70852b4dc778a60d152d3fca75fd6066704e933bf99f5bb77afc9a9cb3b8c"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.6",
+ "468783d4eac8813432048547ce241f72db1c85ce4adbe3ee2c",
+ "c6e32630ed90d0afb168c08b752259ef4b9e811762f7cf4c535cb4a0a04b1d43"
+ "654ed4fadfc7ddbc3aad0314078b226c4f3e9784457c91c7768c5c37b7600893"
+ "2e8d0457850573ce6b41a43cdda970031836840e4e60a3487b47a185c86f8a16"
+ "f6f221d0a0",
+ "0171a12b00cfd109674e5bf7f84347fda3fe4a8ea2f48e0d6b6d94b49fd7bdfb"
+ "26e32400a71251ab842206921d83723a89ea09930025920e3ef8a887d2bc2415"
+ "a7f1ed37ba8a5d03ef926acef61190001c5ea0f8cd92020cd89667e9ea5f7f2b"
+ "15378a210b8ae914819098da1cbec9c543a263300f994fb0b4928571401c202b"
+ "d6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.7",
+ "af631d76c97fd995e494aa9b4bd758c5c672c5e4158f3aaf874b",
+ "406e1e23f992bb0762125ca463bd0f2efdf1bfcb082a8df506af5f7270c39fde"
+ "01d9eed3226661db22a9c404b7d765fa384f9ad4f51b9369d74b0e37706631bc"
+ "6536f6555ec7fdebd348ef3cf5f8a877f606437c278cb8163ad349384baae32f"
+ "31b686e0",
+ "01ff8fe79af318d756f284083b51b43b66aae83c6aa91a99934b4de84bd5fd24"
+ "fa8d07c7551474665e62360a65984e67a4856c3dbd2c75f246e22222e9f4b969"
+ "516726ed287f423a6747821fbbb7fa176235c850a861f299f7394c2c4307b102"
+ "590940fed1206ad59b9dd6444e1e196e947325224ffaca069e9cdf8c62026907"
+ "7d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.8",
+ "73cb539082fb06dcae3c2068e989e7c0d8fff0fb340b6de80d0ba5d1e0064f22"
+ "13928a4baf20a80348af3cde9de63f886d63e56a3e32cd8e",
+ "28e2a97c7e9e033b49aadcee8fdc07edfdfdb950354b708ce5df848d1b51aa2f"
+ "4aff9974160181422947b133764c5a400657046a49363ffdf1f93ca48b3e5293"
+ "7e1f38fb50fb",
+ "0c72e69548c34ecaf248b2dc6bb64387f4f3350f668e59013560808c413fa835"
+ "fd360e04e4747a0031c8a64a9d7a07b363fad293b703a7dc990f806fb90e3912"
+ "21a116df108f546eae51716ba04501ab777b0c2a17712f71e406275f017377cf"
+ "2488c435ef6c6e7c45cdb98f24477ced180eb3efc8703e963826bfb344f16eb4"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.9",
+ "f2f985b8031273cb5fc89a31ddeb4c67a4e4f38c09d302874209b39c69b71f84"
+ "9588868fa5f8",
+ "c120446f5bdda06c63738f18155595f62bc26567284c35036591cd5d753e4ef7"
+ "900dff33bfdd3b108c102d089880c7b69d86e9ce3d688cda156fd6a99231058c"
+ "c3183396380946e8a969a7fcbe9edc959a0e504532bab8ea",
+ "10e0bc14ba16012698cc76cb82045e2bfdbcb2b118f183067959d7137fd50fa8"
+ "8fe4f9cecf6631a99cccab76cdb7744babd06b2bedfbca7724dafd91e6dfa88b"
+ "ea2b44a8cbb06219b15c2ae76872fad288e8438acd395ce5cbe28a712b67f561"
+ "a1786d75343ed9ad0d0a5eb6faed07b06aef03318ff1afe472db4ee3e21ec129"
+ "33"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.10",
+ "39872cfd6cf74b4ccc1a70d973b31899a67aeedee5d671e05bd60112e64512bb"
+ "e43bb840",
+ "68ac3f9697b750754fa7532e4161c12018e033a60251c8dca8387816f42379ab"
+ "978e15578ae2e94c1776488b0cfdff186fa6d79888f8169ee449eaddc8e7f5a6"
+ "58d0997a934f586e31f74730be603f1ee62fa6c08b0bffae6b88",
+ "09b77007f15d659efccaca66c1e7d962e047a1e149e52dcc0e1adc9e183bf73b"
+ "5f2348d34328241b407f61822f6d57e1abb322d302f4530d2cb9a41a2770238a"
+ "1bdf875edd797810d904e97a4d7c515132d6abbf3a4a407486dd004ea38aff8d"
+ "4ed3825fe13142f136fd1d713e80e0cf225769b419cca54c156e54668b306b5f"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.11",
+ "74d56bf8d9c180dc099371a5af72",
+ "337870f0479cf1283a0c87c9c4af54ba8f850644d59a2025263d2bdc49bfa663"
+ "6e7518f94b6ab18f85b19321209b769f0c1975d1d5ada06fd2a76c82450e4e09"
+ "cdadb7832ffb8ae7dcb47410b287804dddc7493d610a81399b6df6df5ef15209"
+ "2984fe2776a4f930546be1dc18313c14",
+ "0761ebaad8ff1c3dbe710f60e3be9f289fb27a6b5377755b71fb384c5facb160"
+ "3c953e1e2ca11e784325ae42f321ae5c58648c84f524df9de9f93fb4b0c2e097"
+ "97ff2d11407073b95a786df51a43f79982d86c49fb9e5014b1b768760a513026"
+ "6d0699306a904ed2dfe20138d531c5dc4bbf4dccf10249a6e2b355f7ccb326a4"
+ "8a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.12",
+ "611063b5da123ce2129617df38599557b95d1b05e6b66bcd49afe9831a0421a5"
+ "be4e48",
+ "10f9df30ec9777fcab5a924ded36fdfd6e1f381449ad99d20aea0e3972ea604e"
+ "a22750d0601d10a377dad1a94f9b027340948123827398bb22b1445f71c505c6"
+ "23aaf516cd9fb3e977f778cfdd3a5d28c2299e4b2abd9f98c4355a",
+ "07f2d58bc4163994d76f491edd69743c45dda0c38ccb0769de9cf9f4fd0055d3"
+ "0a0cf002800d76ed8c12cbd36af051a9d7337b29bc774dc3c4012bf5c28aead8"
+ "c3e036aa41398a8b0fe991c0bf66b5341c99d9377d94704ad490a9f8746fc5ce"
+ "f726e196f341f93a1f1eae2c13e00cfd22062f8eb3da9dafb95a1e7b81b1fdb6"
+ "56"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.13",
+ "80764f785fd4176e1641e129a35a9b31b3a89a7567ad6c1f0d65ec8af95fc16e"
+ "15281409",
+ "2036d098a6e935f9a411201d2bcb629f790a94db2ec69867433b1761d7c6954b"
+ "e91a9fc719190e108613cd584cbb977687046924bca6b2fe1a54bf76acf77b36"
+ "8c39650f6d0a498dbdedae3f4c21040a8aed634de4ed8af1346e",
+ "049c61444e924772f94a795ccd99eb2fe430997b91b42de6163629ab98d25a71"
+ "e7f96886a57e979d9c94c962209c1f712c70571a81f377eaf74e80e70722e1be"
+ "3d1337c5045f797bd57df2f5ae5ef33ae579e93b38fb250df0c2bc59b33a7486"
+ "7b8f3dfe5ba785d728b89d96b3002bc0054db5bb0d84fda45db4a1f2628ab112"
+ "30"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.14",
+ "0abc2bc5fcd040189f8422f1ca045021da95",
+ "e4732e4990699fd74740c852ae8d4d707fbd79460f88740984ae53ffb9fc3962"
+ "683ead0d1404f53151d1aee80fcd6a1ff65fc88ef08fd76d9fdca8f9e3ac7d8d"
+ "82b82ece789c66c5402280b3e568101ce2a2a7b2b2f1e96519cfb41e60493d76"
+ "8eb5b96ccc49bb0f6ec711fd",
+ "03d8ae604f92953173c77a01ffa090aa0e37a38a47c97219c0b9f864d348746a"
+ "f7f4a6321129c6046a994ced1ccf3324da937153888dd6c67019a7caa7655a36"
+ "42838edfa0e2ed8dc25c14bff8bff565c718f8b6c92056c9bbe8d9308370c7cd"
+ "75a04e11b6e25aa6c3c2cddd172a4b6aeef04fb835b68637cf0ca0b9a911b8b8"
+ "74"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.15",
+ "8f9835efb69cca8c07bfef4d8f535d0cbda5367bbd41080a",
+ "32d4be07e6c7fb81d5208c2501c5df7c56d1986dc6d63110ad21d81e57ce113f"
+ "3dbbfebe0f80c016b719e9d5c3d9a3bbbb2f35be95d456222b51c3d65b388e7a"
+ "daf6b9ceae1fd46a6e05ca1bb199c27bacdc8b5fd14f0351aeb3fdd6dc1d93f3"
+ "b53156efa3c6",
+ "0e47ad4d92d19a1ebcacbf875d801927d4fe5afaf66ed8015c559b566a9f3cbf"
+ "0abe8a76fe7324f628c2e4f34584a50ff77e822a54118efa9bae9d0fa50294c6"
+ "180baf3a8b0c7e453a7437ab1a19cc00307a8c6aed95c315b24b4790072456c9"
+ "4460995dbb1fe5a12b4cf4454296f7400283cefdce6b00cc8049dd5dd8cb2af3"
+ "6f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.16",
+ "6dfbd93b0078d49ae4fe1e24cca97d0a9affd7bee062aed29def0b1c0b3aefad"
+ "811d6e7ace8b49d7242a9fe6e23c22",
+ "319f9cda2c93388ebe1a50e76c9397559dcaf14fe10352aa511dc5baa64dc152"
+ "fcc79cbb23d4e69b12b9f27a7909159887bb04129ad63516813386374f31892d"
+ "4cdc4fe63969b5bfddc667f946897d",
+ "01c5ce836be2208a3d814e7e60c27674acb7cd3e31c024d9d38fc22953aafe73"
+ "af5240434dcf54a388992eac36ec8464d9a042ac58d18a70398b8a773e6669bb"
+ "3d76eeacdf1fd152474099bfa662a481dbab4ca46714958745e2b7832a59ccb0"
+ "053649b7e0950743333f5fcd6f65197ddcb4e1bc12a66e8e92a8659faee57131"
+ "e2"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.17",
+ "e5879ffce0b629b8857c195cf5d09f7b93bff1f7a9f2d8a45a563bbbe9e62d",
+ "bace2cea0bfec25a2d34d72992c2b8ea0aea17b7a3a8bed60d1bb51013347b2d"
+ "036a75a4ec3eb2c1788d44a9e1c5c88d041e82af878155ddc7d81b3e27cddd20"
+ "409dbdda4a64bf8311a7b7eb77299312661a6e37df3502f86a22492befacf4",
+ "01e4faebcab89d7baa3e0393f71684b0ae53df8eb9873e65a716ec2f41741f8b"
+ "7816d2e197d976fd53a8ee7f924bf4bfd41042e16445e9060b55a0b6dc16aaf3"
+ "064491d18928223950393328c147dbd03531ec012d8c527502e7eb3dca509b7d"
+ "e16995924607c8b28a2bda9bcb2c7781461c76663b887b9643e2317f0ea1d1bb"
+ "14"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.18",
+ "0a2e24130e8a9d28dfcb9df9765f4683e9da78425a28199806a93b322efa8849"
+ "3ac37252c29a264f3e85ae56538e808dc55642a4885f054640f69c8981fe",
+ "20431ef31fce19939da545a08530112db0fa07138dd86db1cc65e2b03fc2be60"
+ "7c3e6038ebb7891755b23129fb969a7fe10610f2ebc3f077b2c8f4601e09ab4c",
+ "0c14b7d32d3d4ce2b08ee44f516aee2990b6305240b25d2334aa31752aef2802"
+ "1639f76a4c4719569b30052d4bd08b3a07f23be686237e481e67bf3f5a01add7"
+ "56da772c7dc13d32298b9bbc3d33e6df82d85c089d347600497a8b8ea4de68ab"
+ "b90e5c6aeb269a97be426cefacdebbcc0c1f2c409bbc7c72d90bdb426b13ccc1"
+ "9a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.19",
+ "7efc627ba5fa2825aae0ca94030e704708d35f92239826b42e2d4dbbe402ab7d"
+ "196a7f54880cf2c5a4d0fce53a20a32b6830e62dcd00dbcbf33b5c0c704401",
+ "f0497919c142f3a98ef55bcd5988234fdc8aebf736d47af97090a7a9dde0a735"
+ "09f9cd413626bb8ba767c9d638491c286e67bf22d670d56b24c15bad70351e",
+ "01dbce3b3f84b2da06b167e206649d424a42b8e9ea5453a16b5fc6c2e9cb17ed"
+ "a1effe4e7836a5e58f99e531530b40171e4b51fc0b92de3031300936d2595e39"
+ "1009e2e53c32f759604a6dbad9c970900fa6e41a35083f787b9bf3bebceaa1a7"
+ "71841b5e6e4c8b509629007b467e3cec8a1d0323c3c5dbc34d8d4125a398c9d5"
+ "3d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 11.20",
+ "593d3fcd05acee3029815e1e76a890",
+ "1235ee3e7a9df5967fe98d9710ffdd5f7eb22dc07147af436fe20aa526bf0b94"
+ "190cabb5213de98a23f5ef275022a2f73e60e9efe2c034c55ceb26aa806cded6"
+ "739ddb2cbd3ec3b555204a798465c37c6757195686a3ea3c5657c360a0158d99"
+ "2d4febfa0429eeb7c92a468434c5b7",
+ "0f699881a1524618bc25d4e514e2073068ea7d35384bafd46fc282e1d855119e"
+ "e969f211c7184a07030647fc40990ecf2ea40522865d91778a627eca8e50c2bb"
+ "9760b045daaf1277a4fa983576ca8cfad7608329c1881588017d63722b70e98b"
+ "e524e0033995982573d3387078c8b7c1c5f9aef264a0484684b3426643737d34"
+ "bb"
+ }
+ }
+ },
+ {
+ "A 1030-bit RSA key pair",
+ "261fe0284459c2fa6f05546bed585e1ee0a130b71c2b8a6fbb3bdc75787b2655"
+ "d0ed4e325b54c7b371a6fcf2b6788277a50d4705ba23c596285da7e3c9304a41"
+ "e7cc488b44922f7be2b47c16319e337451173d40b1ea481d1a9c1129b1feb7d0"
+ "9f67497aeb98948f1abf3b7786bd3b87047187c8f37015682b3f2de50e078e8d"
+ "0f",
+ "010001",
+ "05df768372cc0a64d3c21418302423139f479573e50b5c09b6e3be23fbc9aa1a"
+ "76d32799a047761ffc21079448170104cca5e2a14ce457d00d807d42c76a55f6"
+ "16874ba7f7eaa1ce63cbf132deb081aad2fd80d124c4da86ec6c020e8ca82dcd"
+ "cd3554e69bb19872262a5031ab5db7cc8c9259a146d58b1db94cc7e756253d5a"
+ "a1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 12.1",
+ "7de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4",
+ "33d62cd667823fbf13d592ae4d02a2370d1d99db06c725425e0d12fcb4834ef9"
+ "e5499d607e8aaefeba819649fb3d61c705f5e9a3a2f896276189a3200d2faff7"
+ "7679e056349a5b9b7b4449b675cd48b6980932c2cfc46bf89a7734f68dd9f4fe"
+ "77e1d9cf1f31b21c4c61",
+ "04caeffcd51c3fc9236346774da0cfa77e9e6465f6437ff46d9fa458b3623412"
+ "c3103009fbfe203196df729626e0ee3afb6b10a5acd72e84281d9d9bcba3e0ef"
+ "77dd84f3db192d31b5b666f76c93810681373baa58e6dadb01fa5c65ec89fa51"
+ "cc2474611b9a7cb00e862fd3d49b1cd31afc2db449e09dae2d0a7d4df0bc320b"
+ "5a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.2",
+ "97eea856a9bdbc714eb3ac22f6eb32719669c42f9430c58950c64c0dabff3a9e"
+ "2043416c67caaaab7c68ccb3ca99a3",
+ "9f141261cec4f2c52f969125a36f141027088250d36b17421cd0961476190646"
+ "8afab7622c0d02193691744791e0d35b6bc9f3377e10b2856c8ed9199c89f4a4"
+ "1613d3c40cca373a7cc63c5260fe5a",
+ "0d26a05de93b707b8540fdc19889d2d1e7937157d32d303c528de35e553f9420"
+ "28744af6a0402eca0fcf5a85261ad475d8710cc9f8b11ba2c6daf1d672690c68"
+ "ed11e035e9c660ece1d80cdab800ead3c6e078617a1b0d273dedd8d65749166b"
+ "d07774fb4c1486aa8a0adf595dbc3d10ffaef1838498a67555c77b6ed983d5b9"
+ "de"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.3",
+ "8e3e772f39",
+ "9eb731fa6d8d5b7581f8fad2c8225bc96834af61db3d409dd56304ae23ea6269"
+ "63a4d80440c24e431e419760903ac44bfe41a75081a5462bae6547c0e7a06e91"
+ "60df9c01fa6c5354c83318db656dee0a437787fa46394e552ea5331559b4017b"
+ "b6a0e1d6fc8a65b45da0c45d88954861cd6e7a417e037b1b05",
+ "244a8634519af49f569b6986ab477964a6b2920d843a1d97efd7fef83e81bada"
+ "4c4b562961ef4e1fc333464b926bd74b07ad50c65b681683d389fe41d6d213b6"
+ "469f182b14b462d72c1ce3928ca806d966b52d42d0bfd60c9d04914d50837cda"
+ "e09b330e372744dce17f18e94d711c8b58ea449f1449d369faef514683d30160"
+ "79"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.4",
+ "dcfae7718c247c40f9a2a3c3535c509280c873c3",
+ "b93bbea6c1853f153b5e01e7e4e5d0c63d9dfb245fc6cf64043d7a9220b0b81a"
+ "c2af656b99714ba430e0a39695d25ff269b0b9b865fc4d4eee5e07a5b5be3543"
+ "82aaa414bc6208545c86ce02388c07b376fb0298c37d1ac39ea189b0adf780f6"
+ "e830bce917b50adb7a31",
+ "0c412052d4ef4ab51b2f623705f07f41fad64daffdba6244efd47f519de2e71a"
+ "01a6c57d1f28b6bf7b5c8dbb9fe7b149b0ebaa53596199376df490323d25c217"
+ "bc71be37f181035cf457eb5c06d6a3ded3d66d5b35f06181bf94d0ec13ec447c"
+ "708233491c554f9e991f6bcb8b78d33c9c36955b8dce5179ff8bc59244f66790"
+ "87"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.5",
+ "d71dd87a13991a0da2c74a58b0485634b3e04fec9e3f1cf2604a93bed79696fa"
+ "6378eb1ba0e5d20470a4",
+ "0990599258e97a2ebfbe10977225c416762e95d2553a801f726cc249bcdf3221"
+ "32585719fc12399acd7254ae77da343fe2a9a3acb11c14e214e2d85a76708c3e"
+ "72173da5d99058e0c8709edf28c36938769f1f22",
+ "0ff9cce7b69d7fca48d7c4f6ccff248c3db88bf1b7852cd9d8525c3b41e44a9b"
+ "540f208ffbb8c85bfa890ac02e994959d6b07f64814078556f8ec60db357acea"
+ "f839115fad41f8918d69c21a3affef6eb14a5d2cd0645cd706b58143394a2735"
+ "3682e3baa198002e1680f28f34be089a5784ace5ca6b110899dfb9582f2e4b2a"
+ "40"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.6",
+ "5e4b158f8dcbcdd7e308385b40190f5def8cf3305fc49de63c9e35b40236aee1"
+ "f456205a5267a2aa7d88cb2c11af7f2899d01da1b2c7466ffef7",
+ "a522f9808d9c01d8ff79775f7b22098fc5fe3254e1b04eb1cb850e10e2c5065e"
+ "23274dc0a05587436da37559335fe7093fa5e7a2a9c9a4dcaf235179d0e98fa3"
+ "3e34b616",
+ "1c0e86a6366beb1e12d6bcfa6ad49406c8b7e48d1d5be45cbd83194987496faa"
+ "3e21927ec662f502ac3f91a4b4b91d160c1986a5ed092766883b8555e3c9314b"
+ "44ba3383db287423af91b413918c0802c7778e46c296dc9f04cdb8b06adc7c53"
+ "d859f442ccbd5ffab5af752b979bf523a40a1d08d76063ffb3d5cfc82f15ebd6"
+ "d4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.7",
+ "359ba50756a80330409d3f236a340b90f42f732a87711fe22352d4c8250d4547"
+ "5e32b95883e1609755a13cdfc1bf394c5c67369eca1f9a33e8ba",
+ "f9ebddac9de1709a06bf6bbddf5894e23b962ba0c064bfcd7cc576603b0a1a1f"
+ "f35d645ee87ac6f821a6a151e6bbb05bf3e05cd9a6e2cd9c6cf553bfb07bd2fd"
+ "a040dfb6",
+ "083360e649059d00658dba21f2df28a2764c4589f7a77d5af99579a8ab4480c8"
+ "26a77c2fb7954f4f31fe1d9eb1bf40e809577f39301ad3ab95b3816c90ec3f1c"
+ "d629c4396174bed9fe1e0f476823e53b41d135b49a02b00effc761ec909423af"
+ "15855237b77ee07df25ab4e858467d4ccfe80843241bbf88eb4f853ef4b43ba3"
+ "ac"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.8",
+ "a9f39f8ba06466250c265df0ca46570a160112cf38fd745999",
+ "88b3c28bd3999a860b8de775935b8ed78fa2f27c268b243a0245af8672254719"
+ "f23a4b7fedc00d54e12e9d701f64699424b6b87d14d9676efa959be21a04b643"
+ "5d251003dd153d7d08ff28d93a9320dc1bbc3db397a54894f20579f93e4ead65"
+ "c31a407eb4",
+ "19839650b925f1f96d611e4dbb914993545c67390c32935fbf82259dad10f237"
+ "30eb48f34200465a20387277e2b961e08318d2077447c9109271e4ded8ff3dc4"
+ "f379eee455ae96081a1ae24b96ca730a62f7acc5a5ea5228e3a48ea6741cb30e"
+ "829d5509ccc6c287c7291f3a1d89d626bc981577de52a11f12ae2143d3b0b52f"
+ "86"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.9",
+ "68",
+ "538b095e4f2ad67730687421915242251d07f661edac7fe79e31d6c345aff59d"
+ "f388c7182fff0c0427b59935c691dab8bc42be47d76911880d917b862718b4c1"
+ "c1888d4220b9f8231acdf12d9b85186be0950c1aff84cd0fe36586a50e7e04b1"
+ "72ca9c859e2ded6b8ea579dd5e6eee772ccaa6b4a5d8ab1731a835d6a8",
+ "1e868adb0e653280604e8d3bc4d96984a20aa09d480b4dffac62ba78cbb7eed0"
+ "645a6d94d9d2f2d1e917c146b41faa3d1d2c190105368fb48406a1d2426af3dc"
+ "c85bd02d5c26c897ccb22e575912641a188ef4ac47a0a9fe9aa2706d8e1061f5"
+ "d93063f49017003b2309ca7d8d36703bfdda3f7f43df158a15bb22139aae1510"
+ "77"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.10",
+ "356587e6c6c0b46c2445e018635276ab845fd1076d107f",
+ "e5d33e4d93c70844ee4a016556242d08e8e62f1a7f794779e223ee9dfb231c3a"
+ "520f297e5073e4f92f535cf144557f94ee1e1e5cc6bf4c0c0c8e5ed40d066356"
+ "06f754cc2dd83fe02c576ccd2b835fd0f53a99083f4d15bfe9268899ef09ff5f"
+ "2f3cec9f9b8a7e",
+ "15d364a4499b30a5f78b6d7d4f667a1f76d715158f280119b055e1f2663fc796"
+ "e33c0eb64e34a8dada5c81754257a8bdf0ed8115f607b7c9cca481f74520b6d9"
+ "ac98f5e72c2baf3cbb6bd9baea5d75860cbdae3403fd5c37964aae64366ab09b"
+ "c9c67276951448193bb4b1afa27079c34170a26956510d442764229908420fe8"
+ "0a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.11",
+ "e153276a6879678fee19894828d6262ea39ad054c89edcb23f72dcda1b0073c2"
+ "87620218d92d0eb30c62afbf2b45df62d06665f80525b6727f95e34229e682a8",
+ "2ad7142fcfa3bdbeb755b2c5b5cf13e6969eb73b7a06bc29bcad7e7530a59023"
+ "0f6a43fc03d6c3a9c641e53a4177d5750291ec6d4b33f871668ad8569077",
+ "178e49770a4c8ffb7f65f382cdb576e608e975c4371339102b952a1e71cbcb91"
+ "fdcd0c0ed5a85fbd263da6a74e491fb04b60a5961d8e6ac724ec8a8161c22ae3"
+ "10407f59f7e602da48aa2dad683e88db1d84295e0fba5ff2f673df32854d01b7"
+ "1a89460ff0e6e1be98aebfa227e397eacc8b23174147c44e16201ec6babd165b"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.12",
+ "fa4eb931a7e2090f31edb1ff7d8361",
+ "437fa151f43405db22422cb35d1c5761161cb9a78abcb6f06dc4e7a869481f40"
+ "b21ae1d33e075c485cd8501a3caa6018325b7f850d4d8f6dcfd2affe19d3e6c7"
+ "0874e7101114f0fbb9822581bae6ba2ba1e7498881a5dc5bb8852738a82fb06d"
+ "1527b4334487b324013e32bcf17bab",
+ "226d776700c5e1ddb9994b3291f1d334b69dd863065fa83421e01d5206ec2cdb"
+ "8990cf78973109dc9f126b6033d6d5d6918ec850d69c713cb5bbe32ee59e445b"
+ "cb4e50c6f164434d2a6ca63969a29b25036415b0f7cb21b4f8b34a8d9b74653f"
+ "ff4f5db9d1a6b5152a644836b68b8ede9dc5a169dc60dc5fac468f2427845810"
+ "62"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.13",
+ "588115e53709eb15a3374c25329e883826e3213f37a1b7a65de12df23172f17f"
+ "a496ff492b09173ba0c6f58c293d47f148",
+ "078185e083cbb06fe1a749743515f3a0b4b26f853b10e568e87082ce44412ca6"
+ "7e59888ccc0f503101521acabfd98fb7b5c11d8a941ba03c495aa03e13522f48"
+ "7f6e1616bec2072b3996faee29",
+ "0e7e50a7b247b0297dec65c9523f67cab6b52a025f53320e9486cd207410cadc"
+ "74e4b03fc06bbed598b022b63b37762a65fd351cb2727f3d8035a4cdba9c6a31"
+ "e4ed6beb4fed3134eb63dfceab4f5f2459e59fca0174758aab3753b5c193c81e"
+ "11490f97b622b73fa73f8eae7da8393484b8297971a3e923129ce4357b645cc6"
+ "38"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.14",
+ "20f1cfaa6367c7c39b54a0",
+ "4a1c7b70f783ba0d5a26d4645cf05fa610f5be0177fdde9f2c345057db424457"
+ "faa430c9424a54f7e55fcfee6faea4244c03977481edfcbb288837c6a48dbd72"
+ "96677a24e06cc9d85e688c14090fa2830ff4967933eaf0db694b6ae402caf9c2"
+ "beff04a52a2f847fe40f4ffbdf3d58b7c4fda8",
+ "1e528420bcbba7d59c6c40d446d1aa956aff0305365b4d7ce9810f22c34f09a5"
+ "55e5ffbe5175037f903eaa6c40563636d381f45325b5e61a2c705112556402a7"
+ "dcbe86cfa54a6e6a50378d05e21c95cc6c45ffdd0517f77a36b224d1700a1f3e"
+ "bb81d3678a66e14534a80a598bd71726fe322e739c17eba508da8a031a27f6bb"
+ "28"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.15",
+ "7360cdb6c15996b060331e9f2a368995c064adda56559527782c170c691bb3bd"
+ "3b",
+ "58dd80f4fdc5c95dd9eb56ac80a02d53e8cc2efb3cbac6727d75b1e7b35e0542"
+ "19433af5aae198fd62f2ecd2ab8e263877b5c91ed513e235497a63192db9a9bc"
+ "b3bca97ae9bfcedf935644b2d3bc20e02ae5e7424e812a2949616b8201",
+ "203bcde1b412e3cea25b8630b208f978ab22c1da8125076e10ff91d7bcfaefd7"
+ "dcd8391655c886e8a945a7f57a74ce2dc0e8ec7fdb17cf195780d3ce80e0dde7"
+ "639c677205b8f9ecea115468977bdea3500b239fce0d7a94be6de333ea7ecc22"
+ "c07e65d0ebd65a390a185f181789e7ca8c1ac2fca828bb8d28227e38c9889ce0"
+ "08"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.16",
+ "319b8294bdf07cd40685e88009fa7b3f1290160ef33067add5ef4d80fd",
+ "4e07d7f963be24ee6d8bd4dd95e9e3334930e03e658d296bb795486d724e0741"
+ "dd507347a5b57b79c90d3c90c1aea71619091acc8198b55122da5099582e0db7"
+ "da3cbd3cfd85298f31554e29cbcba1199ce470163ca0337cc414ad3276708111"
+ "d6",
+ "04fc7bb6fb6419612b6ef54b3ca00a87465195c37f7f940c233ecb1d4a505d3c"
+ "56ed23e09e03f1454f04b56f6da25d0a6fcab0c400874ae9806ee18780b75c6c"
+ "a56629e577e8e7b5d2fc2c440b9800195b58511bc3a7954412c8f273cc0e9d97"
+ "1abbddd7028e6f84876a3058a454fe2f33c75e3dd062f119cd3eca8106b6bfbe"
+ "a4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.17",
+ "79c682a2b979fe5c9632af1831c2aacf0c6bf566885bf5256250",
+ "5c2a956d4b5f06f750835ab8b29cf7c641d793c556e12aaba956dfde4632d5e5"
+ "02d59041783afd1da7b2e2d24e22d6447835bf6d77c6eebc0d2d64e7ed2c1417"
+ "18ad8687c597b7718f38bf1a3316edeff6b72e2851828807bcffa9b8e1a852f3"
+ "faa807f6",
+ "251d4856b7a7580d53880162281bb4e41bdeb2a87ddbd5ae1b307d4448be1f11"
+ "695ff722c432415d0c74baa3fc0dd51166ac865b310c4f5c8707986254c89604"
+ "ccdabce6c692446621898b4f5a08bcdf6462e518ee3aeb75e26d8f63a06fcbb3"
+ "df098ceebb0fd2f637e3a7937f4d19e3a1924c16082edc333cb6de37637246e4"
+ "98"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.18",
+ "1e0d1807a2bd496bb0cba841c77158bfa5f8aa77d05675c64a5eb1856591d348"
+ "54f865925b371b686aaab44598b4a16ab6b79344d3c23f7d5bf173b842d78c",
+ "dbafa5332f0b552796636d8a0928b7d87d9cee3d4be6a31c77e14e0e5dfdd403"
+ "efb98fa338816e1262c06496fde9d557c00cc0dd35fc33accd79a3150690eb",
+ "1b2ecea5fa9003fab6559857c6d94f957003f4e41c094564804fe69639e540b6"
+ "8f263faaeca199697a48858b8a0fcea491057df2fb8b35d093d894aec17c5cde"
+ "5dfd8f33512bcc66cde76da07336985a97435b6efee4ee09d3a28aff34ce6ae8"
+ "750da41e16ca47e938818e44a9b41fe91a6a801d355ee8d660e27e4fe2ce7f32"
+ "5b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.19",
+ "1c105d5ebea36646a97284c17a86c4",
+ "c6f80340a6557e0753a9573fe4f5214977efdb082a50eb5d5c517d46729fd2a3"
+ "4af7cee1aa46b79d47e25d83090aeb4f502298c0313724fab54e54bebb48d6cd"
+ "9bebddcbee0f07537727d65c50e7d4cc0c6d19fc480ba57867262cf2eedd9cfa"
+ "ba607d658287eba42b469944ccb612",
+ "05b23dc0c62d90c1771eba378e43179d7ca6af515e2619ae4d7c8fc8bda378cb"
+ "f7a1dbba1a14f494c4e0d71338797c7ee06e1a79e9ff2856fbf74fe6f1a7ca6e"
+ "5b9ca283c4c97e61cf9f4073e032ca27d69b1b4eebea77cc95a9281f26b64a05"
+ "a93944c82c5a13428ece21fb4401ad426e7ac1f05bff84b347cdc4dbe52e678a"
+ "ed"
+ },{
+ "PKCS#1 v1.5 Encryption Example 12.20",
+ "f10402f00205c52757ed6e9d",
+ "e2aee7fcf43cede07552a2dfe5b5a9ef808276d8f10eb3f9bc50f1bd940aaae6"
+ "34c9d8a0788d44d41e8a5c603649efea83033231516c69d33e12f1f5d3f0ac1f"
+ "c23a9b3f5da4e0ef6e4550cb43fdff02b25dac86272d66db59cdd635f9c0dd0d"
+ "aa0857910c15881b160d70ea53405aa959f4",
+ "0b9656317832a940c795bba58daa159a4f733e826ce55a4ec56433c51684444c"
+ "78e2e2fcb37f85ad877916522d8a35a43f53c59517a818e521e1982a5091bf2c"
+ "68b00ee49abd90dd776c02f64f34f680a88eee05ec088892bc0a9555b3f20c8b"
+ "ee579c0ddde1511a18af98bc1d9cf90b81bf132abd58970b3e84d814e27d025b"
+ "73"
+ }
+ }
+ },
+ {
+ "A 1031-bit RSA key pair",
+ "555dc2baf041b7f09a0478423aebcb5f49b95dbe1570e9a542128d332287866a"
+ "c4cc63e76f8e3aef22c9753a545199942452418a67d1a2230ddb6f4222c663d3"
+ "8e80050eeb67956ec5f54994a0bea695fa59fadf2dcfe7acb54ed9da3d0beb12"
+ "2c8a691b0bb51ae65a774d75b1b349cb68c517cbd386ae482f05ee4603ecf295"
+ "5d",
+ "010001",
+ "059787bb0123fced98d9341b7a8a999edb5076308e6d0011203be0ddf9a4110d"
+ "0b692c1e2bf3902ebc03a0573ad0c193afb167b3ae4b5028a5aebb2204ef23f8"
+ "e58360be9484951e34711176062e53e3f63874fc9e3591a9d9068aa5e6c8c7a9"
+ "ab08e9792470066d71a07c3433dd703a42a6b3a9b1bffb3149498dcff8b35756"
+ "ed",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 13.1",
+ "7bc81d8146e359",
+ "76655e4ad8fb9934d1847cc90c02473c572b5fdfd164a970a3cd96bc8cd796ac"
+ "802c50282290ead4c77aa5cc2a7e343418c9df47efb88786af4cc8d1821c5007"
+ "3909e84f7b451af4a32aee6c7cc897eef7660e1c4c535d10039d3aa2035c9851"
+ "0125ec5f2a2e9dac639589ff8bb39f07438defb7d13377",
+ "146d6512dfdffbc02d5d54bff3e036a35b4c2aa944d6f6724793306537081bd1"
+ "1ee568a4e9719f1e31f2d14e18c2da624470c5b0ffab397f9231b6ef4634f63a"
+ "18285df3414517a51f93586d66b03cab1e78a4eb941b9d3d7f9203b59e1cb3bb"
+ "4864b646dc17a06411ebd5ff03372058881b4a24b24f4c2dcd5cb44c2eeabe6f"
+ "72"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.2",
+ "686a810a031d8061e41a776a7dfbdb3af626fe9769deeea460ba2867acf03d9f"
+ "924d321e8a8f425c2851929867a326ae275b49d2",
+ "f79b49f6a6be3e68884c80dfe1e8501e544ca782238843d419764112250edc1b"
+ "69c7d1c3587fdc75987c62cb4c33bb81202f72dba7eee24bfcf89d4dae150c07"
+ "272458fb01b6cd270925",
+ "088a47f11cb134dec4b5087725e8a5bd04f7fe582a69914f683ee6de7c324fed"
+ "7e07f57005c0e0df7500e370a42efd6fe5b290199519b19806b6e691698afd95"
+ "17d780da0bebf70a26d65c5b64e340a6405e889555dfa0a92c429ae9c3ec88e8"
+ "88eeda045e410e3a9e6199ab39eb1ac864e228c2cc1b64e3361695b5aa113dc5"
+ "a7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.3",
+ "18544aad24ab075d3a",
+ "23204b8ad94575f6e2f46c797bb873aa3f461acd05e7db7846a23157592d52e9"
+ "a9a7043819c48896275ed9df0b1e540493c077ea15419afa87dc35f9fdf7ab8a"
+ "af47eee1d33ecc28950645f1b691382d87541ed06406930c7ee1109aa5ca75a4"
+ "90934ea8d3b2a04ba1521be092c868f7ea5be378ea",
+ "34d6e546d69e2706cdfc6d9e7418f8be03e45756a8b19b60c21d273420aa7d5e"
+ "bbbf460ef4c84f6d4777e6bf203ff9185fd57dc723b58f35c1e9b5fff47cf95a"
+ "e569a5cb64dd9cb8d6407c0ba5efd148f18b5696b047daaaa277ed8d4528614e"
+ "e3da52387132b7a9ccfe073be50332c9e2837353c67daa0fdfefc3b652cf7d79"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.4",
+ "d90fa38f",
+ "3e09f6506f7f719147ae21e39453ae0b416098da103af84c0f7cefae500199c9"
+ "855967a8300a1a7f8d2cc13b91727eebd93cf77d3facb19e83a840eb583bcea6"
+ "c6113a9c6f6f1fb5a0b332559a6b431547457cda1d3dcee341d171c62e95e7ea"
+ "ae16ae0eaf1c1fe810fbb0b7138cfa3d66c63850f381e49a2dad",
+ "27133f43791b39227c8e954e1caa830fa65995f8a9f88e0d1f756785ed5c8c78"
+ "54fb1a9dc4a95fa44dbdf0f28599c472849379750a6a1bcb42cafb5bbfe08c65"
+ "106dc840cbec8ee2cb5a206c8118aa061da4d21d1b5c46117f77c896bc71cee2"
+ "f8757aff5cb2b3c34774558e8b82edb4ef9bf2d4f2ca4fc597fab40a2d74e523"
+ "3a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.5",
+ "fcbdd0248df857af175b4396875c006d5114cc11164280043808aa79886c4caa"
+ "29117bf3ce45a9be5507c6b8bf0d30",
+ "2c9d1457ba4450df4021e4e51183f795d091c07f6ae0dd962d5728c54b7fc3c7"
+ "72d79d7bece1bb0c996c9ac07f9954dda7687bec86bcdb3140b245bb5e01275b"
+ "38d1f252335e36c68c0e58f4ce117e",
+ "2ceddef202691aae4271852a8983de7c214cee00dbe1a15884f4c3c1de7a3ea0"
+ "1eccf47ae86c269324ae52377337b6ca82e85d553fbb2ee5f977dc664e142f1b"
+ "54538faf85cac27c29f2ed0c404267335d48ea40e8a3ddd896bbb3e0edf0e16f"
+ "9e8944683b8cfbaab5eaf22530f158c4880bc3e460c06a240342210aa87b7909"
+ "68"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.6",
+ "25f2a306eabe6e3a1830dc936bfa41cdebb88005175df4a3c9c4642301456111"
+ "5aa8",
+ "cb8e0ff41bab01a142f96e7d7cd392820a82a1736674b92135ef33089688dd30"
+ "b2c2f7ba111af78d3f76a37f667db3975fce64ec9afb0968507f7b31097eaae4"
+ "881b3624065616ca090c204c1fa4be134850ea5e90fecdc845b9d839",
+ "4c7ac81245e7d4de3c4dbfb315c468341cbf22875735c5f80590505853068d6b"
+ "e7039b1cee6d07ecb7669c42f6b92f2a71f645f72cbaff76341637d2f1d6b1fe"
+ "ceb07f21e14c70fb77bc7f87b031c2c8f2ada4ec43e912682c2f49639e757157"
+ "1877fc481cbf2698b37315bd4b930783f47945642b7d815e0432d45dd1d0d3b2"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.7",
+ "a0daab4f9fe04a2a51bf083270115d0d06dc2921cf8dd13f5cff2604bc551efd"
+ "983d9b25b7274f3ccb0adcc11b1a3954ab9db4",
+ "c81d1c02f06e7ffd6e03b81b7193aabdac5663ab1425a67d1a2950885f5d1c4b"
+ "725e209dcbce9f7bf296752342f184fea06a7d6cb2bd39b2a318075164a2e761"
+ "b702702b019246c1e50e6e",
+ "06c06c975fc6b9c260d3d8813b5714248beb399b7d68fcac250338cac54c4072"
+ "959f62038444e9e666bab5f936067047bcaf4ba4ed68c6c8185746293256e7c7"
+ "2416658154dec067f4250dc6b29bbac18e821e49a4c9b163831f7bb38392326c"
+ "6b4685464fe4f026c9ae4dbc5849477b4c260aa4ac02d21a264020f10ca11b4b"
+ "0e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.8",
+ "743cddb361c0bb32476495ad5dc63a2bce5fbac1c8c20393693267d843f28b8c"
+ "f3ea13e374e09d0aa3f7ae5d8f72d8e6cb9dbd",
+ "f72ed2d069b8ae5027046e0327b987845809b4e816c8865824fc4a2301b45680"
+ "2b189cbb43f04832ac25c848d74fbe1d625aa98ae05eb62547761c78b81761c3"
+ "03f93df3fc0fea3c5a7bb1",
+ "383ebbf159e1d0a21c74eb61e3643cb631be18c7a2a54e248933587d345e9952"
+ "72466dc1bd613addb4cd7ba50192fc2d894d7fdaf78363b079d998019f164231"
+ "cc2d752db76a9f9d0c5204bfb0f9930553096b5b7680b0894fb99c11425c67d6"
+ "5d965e35128e154746b3fed8d016993070a70e07ebebe06f2f4e976c9a63fbe3"
+ "20"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.9",
+ "e53192febcd36958bd0803f2ea0afdbfdf993b58a9e4ee70df95b06d4e7d74b6"
+ "745b87f581f342f8aef9ae4c3182c4199b6551fe18f8d3b9ffe4",
+ "ad982fa729f27fce8a674903ecac694dd33413c78e3428aeed469f84d9575c6d"
+ "a27529f2c14b53b758d20fb6b247c829c5fb1a16af55079a7073cca05625962b"
+ "6d1a6bef",
+ "221d88a86c9ed37aa09cf572549782e58ca8d4851f016acf289ee8bf23790b1a"
+ "8f148c165508bc3fdb1ef9c9011627427c5f32e5cab850cb6bc0bc04a11da2f0"
+ "1813f341417b3e632bcae002977d64ffc962c7fa7572f56d2617e2a52d3ef917"
+ "c44a33b71582aff1390b7c774d607c8d578f7bc90b3580d77b0373191477bc14"
+ "26"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.10",
+ "d0eb480e2745779c8a30fe820aef56d4ce39ef84ea40c7df0c",
+ "465f91e3f07cb72283bc2bbe528b9ab3681654fe20b61a33f123ade52e832ffa"
+ "8a1b74a4443cc89295a21a2aac9874da0a5679d18cb5c4cd690bd0a20cbd9e9a"
+ "a072aa8713448f95e5d6a6e624d5b9085cfcecb7992f10ea2da6d626ebe543d8"
+ "702236ee6c",
+ "06f3f8c70d0fc4e74473e68fd23cc9df1edd4235b428b772a083b41c3451625a"
+ "6f15dea4bf313bf4f03fdc4fe9f6a2071ac69aa3f0fc4157efc621f9594061f6"
+ "c19806bd5d759ad023cad148e447d259b62bf7342591be83baec77714cfe2b90"
+ "1f369aea680248babf068710cbb970484f324a235253a31e022534abec7b3996"
+ "06"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.11",
+ "1c4297f6dfc07ffe5759aa1eaa5b79378afcdd1a9a33a2133a39ac",
+ "a7af2a8601e408c318fd1e0f82445b509544d5ec97a7958f594b2054c509f7ef"
+ "fdd416306b2b2c91b5a637a156820d601a23ffdb31fb35d305aa9374578eefb8"
+ "102e8b7244191f4ec74aa26a0b7db36cab44999c81b36157016b558906e5d708"
+ "8d5132",
+ "3cdf2dc67a4aa531cfa1428008bd0544abbd032922dcc2436da0b5d7ef9a7017"
+ "e6193a8baf38c58e91962d65a375f08c1d55579cf94a795c9c70b6e42e1643ce"
+ "f540dce1e986dd998887b69552444b6de93ba7d5f7648354bfcb702139ed3954"
+ "947d7b180b6c02bcad8243a0ab27ca665276291b46cc318da9b5f60a04affebc"
+ "b0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.12",
+ "00927fca7f5ec76f548dd48263e339be",
+ "debc2c1f22d932ffcb897cf10ae62c3e051e3f78463ae67d9561cf1a73d55c4b"
+ "14aca6c21d83baf976cd8bf246c2297861a6b1e9c9ef3081c51c4b687c67b5dd"
+ "0fe0f7553f738c2c8a5f81d1268a0c2d4a461d635b0e59d23ba417abb8045e9c"
+ "10d66b0ec892f953c6f211f02ff0",
+ "49b92089b52ab78c33b5bb3032cf7024944ac68e139d2d56068c7a262a53e780"
+ "9fb5b01565cc6561d7133046875230ac2175647296cf2b4847e12b7363197253"
+ "21bea264757de0eb498872d89a4d7ce4a1bdb7335daea78ba196fd50d90382e6"
+ "d62f8df7ae685a1dfc849e11997dee8860d10f707b0d35365a812430731e7a50"
+ "8d"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.13",
+ "8b6df2d6da631ac8d5556a26975428fc4d20ef5b4a1f068ed2e5",
+ "ff2c0698852d1b0ae3c5c5c9be26e83c9044842c1607f5f4086a6d6cf108adca"
+ "61eaf665400d7cff2a3adadfafd80c64956da2d7d7c135abf5a0d176062556eb"
+ "4d8b75b95cd11ea9c0442f846f037da8772902bffcde6559e1b59e60c6d0f989"
+ "6ba5c3c4",
+ "41527669803339ebd8f2d1cc186c7e8ebb80cf4b949d8a284365329f3ce46ebd"
+ "ac0a969f6761900cfe342bc84c7d6951accf45280baf24a0cbb242a94218ef9f"
+ "d371b1e008246262070bf554ed57007b9739791635861d86c65b1a8256f425f9"
+ "f3ae519e1b1bdc5875b878ddcfc1470feef2aeeb014b7e33efb9f4dd0783d171"
+ "23"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.14",
+ "ea039669bcd7a8cdceab585591b56361e90bda0ea440104964e889ece18aeb04"
+ "ce0ab5b1ccb230ae03255a39",
+ "204faeb313965cc1a18faf1039fdde681bc43b223e28bc471c50423da0bd797d"
+ "6a8c738c54033c8e559ea2d10c3b79b80e2efdecfe891cea2ecb3451a1a8e2ec"
+ "2f447b798d7de5641bda4aa990b301e1dde7",
+ "4ca1c85ce3c620d42991cf41733ead26a09311185fffe58f41288f6d0bb6845b"
+ "2d5acf1aa06c78d71f769396a9434203e38bb01fd88eb23e6bc51ba0c5f3eeb3"
+ "2713cad4d087805061ab473a1567e79bbf4eae4936f18d0205b3746a17e0648c"
+ "52223dd9f9997281b535ab2fb3cff03ca890f710aa88fd2d0f392ff4a88d311a"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.15",
+ "0f462bebc6",
+ "4eae5d5492d944ffdb042ad9501681adb3eb6ab528b6e8135355b623ab55a740"
+ "87b19fc59b8534da9a88da29f66f71f9452aede0e3e93907709c344956728574"
+ "b66fb9a6f3383d58a0136f94c4ed86ca9dd38bff070fcc2def29bdd6fc985970"
+ "967f02fd6f9301cd56d048a442d702409a98a132ab6bedd4fe",
+ "29369eb00a3f878438c938f9d7bda3856c45a6d77c1788511b982c58f63dbea3"
+ "3e63ae1d45c2df6ba80f0de997592e1f8a3b3a09ed760651453e109978cfde3a"
+ "600a74faa8a91b7c724f973cb80b96835f050b7dc09d2f157476c5b7051f94d9"
+ "c0f317e1f188e30980795b096cf9bbceb5636b3db987054a5608752275962997"
+ "e7"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.16",
+ "514d3b380022b3782e8a77d77bf24afdf92f3397474dae0d4bd6e4fa31ca6083"
+ "df496b36626e7f8e1c919f9f2e",
+ "d4d3a9e8fbeb1dc607b4dd7887ba25c3d0bd813484bd5376dc83efb58ec5b256"
+ "2cb44f985e59f50b9ade3c66716cc6f42e51c60a2f4d8d75bfb9b824105d1ee1"
+ "5835f5f5f254fc6f680eee0b85af547c17",
+ "19fb391a310087bc3d08791fd59994be8012dffd76a02adbd479cc0c1556605d"
+ "4da2a3461c7c71a85ed8cf85e08f45dade518c00af09f493ee8a5546ffbefb05"
+ "3cca2eef0684763cf780f2e097bd8e5c2ea84cb1a8b8f8496cc918167f656cdc"
+ "9e1d3b2a2338b64c61e90ecc274a1210e3db5783ae3c00abd3748a810fd91491"
+ "14"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.17",
+ "fba16317b093083e3720aa064817e74ca751a517874b692650c4147f119f6890"
+ "702cf8b14f0c1882212d72406c3a45d7d9ffa4312410a6",
+ "9cc9a4bf8cc275a6b9b13510319110917ad85324c5a4345e58f1fa47275ee592"
+ "1569dcbcbd723670cf4a24ebcd57f57e998c4bbd4a95679d60baa0abe879668a"
+ "2cb6ed0fb94e4a",
+ "4c41b9cbcc6fa87f23f17a36d051e7780a070656cae7beba14fa91c555b8588e"
+ "8809e7d3354e7ef5e0faefe1cf392e6fdad4044aef08e33e6fc201c547fdbdf7"
+ "c73d3be096ed253f9df4af52e13b9a1925aa7393a6429530209201e55b20e51d"
+ "5005d06b58353bfafceec37d60e1ca0d9dddd8680bd0a5d692e74f2dbdfce266"
+ "02"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.18",
+ "5ffe82e033544245b84962d3927c2fa59972ef59c237a386a51bd0ba1f2c1f8e"
+ "45b46a05ad97db49d3acc6344f1edadf6564c28ce1",
+ "cc2359bfd0d57bcebf075b87a585a9bde6593eb24961eff1987e735605d4e30e"
+ "971937f6f3f5be5278fd476dc660ee0730cd07e5d1f42009a333312d9328f3b0"
+ "085c4075bc709a10f1",
+ "058b50e0bca6b934c01bf7c33bb615b722ea41807a7d2c7cb3d438e28dbe333e"
+ "d6d837477af84bb006bbb10b36944f15d4f6d28b5ed249d5690c0837a16e157b"
+ "a8802274101cd44e7fed72a75981c97566bc70e5559702bf5b62fb09b2136056"
+ "73aaebb7fe9b1ae6d80403a20133803e1ed2350b8e15ff019a700f2abe87d6e7"
+ "33"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.19",
+ "22633cc3fe7a7b4f00fa999c4fe0d882c31bdc0d670c0cc3d288961fbe6372e0"
+ "e5324642c7b1fa852e1b4f696f12f55866",
+ "3edfcaf48871d291d5b7f7723d92d9515152b6bf52b823699c588f75f34e3795"
+ "550d078118e286c96e9007aee154f57ce7f1d46039473a4a37a9b590a37eea59"
+ "947fe8587c956988bcb174e97c",
+ "3debbc6cfb0eed87166bccd54c7597ad36ca0ac96cf16676e1874bf5f10a0ec6"
+ "9c3be2259678eea63a1808d90665ffce9af0827ee629edd65943437f8ca0a671"
+ "172c521cc0d1dd01e22f20a6c79c427ada8856000c4e035d9c5ef2e105f2c9f6"
+ "457d9ee95b43bc4be3294a0ee1d5c833ae91078aed09e792bb42c25e00b087e5"
+ "61"
+ },{
+ "PKCS#1 v1.5 Encryption Example 13.20",
+ "552b384c5e5174f51f380d8b53e3c897b48c669a9c2d11985b8654de7f76d962"
+ "396a37b95341f99dece4afd71d3c84e1287b0f0f86eeffcfd97ba188e3799e",
+ "2e2f3e3f46d4740cb26cbc65aae2afe49d0be66639d0db10dfd6af606446f3b7"
+ "de98212f86174bdfa5b2e2358507453c20ada69a4ffe0a35e12efbab3bb44c",
+ "149291eeb536fc0703f7bdf1f031a430cc83adc43e09686491266934ef37eaea"
+ "b11bc7f39149ab33436694593673ccc6390b529e64d342e9f21d176da21fa65a"
+ "bd57eec60ddec7d1a093dba376445f1bcfe5a6aace9f1342af39db8ad485ba22"
+ "2d39126228faeeb49bb3b271fd38e11525d803154e74084b75c3dbcdff2e3d10"
+ "42"
+ }
+ }
+ },
+ {
+ "A 1536-bit RSA key pair",
+ "be0ca01f9c172166f912391e5d58ddc30d5dd0279a49bb312a31e4c8a66a52fb"
+ "4e8b6742faacb224c3039f1e198f3323b888ba0e35bb94c511bd22b886405a71"
+ "5e409de3bceb4fc9911b0e9c3b1e42e257d5bbea0722b5d5dd3537569dc75606"
+ "46a750b87eaa6f3a405a94bf2ada72b50a4b0187bb9d00ec451d50a6a91a1e2a"
+ "91192a7fd756b900141fe88f96e2080dfdd80166a7bf67e37144d09e3af89974"
+ "e57c72b03a2b88fd2995252ace4f30e2e47c2818057240536b58db4207509e59",
+ "010001",
+ "f37d28d61f2899a5c0e0a0749d1389387c64c8c358a971dad13cff85c59a62dd"
+ "a7bbc0f7e5bdc65dff9de9c745404631758148168dfe6ac0a2876a56053bab2a"
+ "2a9ff272794dd5d8139eed10bcfb4df33020d59e3048fd2f0c431426145e36a1"
+ "d0a6bfce4443ef3c7e31d4a92fb8517a49f788c3b4e137395a4beeea63e0e0ad"
+ "c3224f980925037df6f5b26c007239b4f01f8a9a61ea0b5119bc9d5496a95b60"
+ "ea766ccbade037e340324f25f02e7245c236eae4367a6468a7a0938d85c0a1",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 14.1",
+ "2bd6e3c1defddd5a43",
+ "e784d52503e6291f258e442db577f9916382a0d14c7b9dccbdb607af01f0258f"
+ "dc972397da1239d4449a58286ece2008f718f690cee73a027fabf84bdf7ace45"
+ "f7ed2d77324cbee90ecc6f1e7b86cc2935a47ba156650b42fc71aad07099a27e"
+ "97fe5a3f25fe1348e442391212a5cf1b445a1e70191ffa8fcade635d2e4465f5"
+ "f913c53e33b59152cd8a149784f27d831828af2d666a5c309b56d0719cfd8073"
+ "4069a23e092d8315399f95c40ad7fd0bb5f94377",
+ "85ef3e477677bf76071a27bbc7395715cb350796e44f1b52a08e905e08ff1256"
+ "705a9bf0152e872bdc74bb1f2fc8631ef8812d16946a30b58f4464d6e7b2450b"
+ "e45b48ccff5d8ecf7a00b1b78fc8fa54713dd696a14acb6800c0d3b69a0b4443"
+ "77fa303a7d66db4927918a4bfb0fd493bfaa016aebff995330a6dcb6215dd3bd"
+ "b35d7cd61ccf0e9cccbf51e9ea658ea31d1243444c4b72fff01ac93f28eb7f67"
+ "c1832e568ed72fd957d5b4fd2f00b6023171b85ab0caa1030ed3e3edc9503145"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.2",
+ "104735d9ad726046473df4b13b2f5fa285c3d233ecd46170582dd228cdee464d"
+ "a5095e208cf8fbca05388b",
+ "dc6a631e297545d2f6fe9c69a5d306a10916d7e7ef0dc953f21b6a041431ec8b"
+ "a5ce1c138743faac5497d699f2ff1d4a44a3e0637cc5e5e638cd73677d09afee"
+ "3ec9fe8052947a73334c3270472856f307243ac58bf8638074667d7f7c18e3ab"
+ "327ea3fc7891f1c58ab47e4ffa6e7d9011a33d9b40a2d789ee4221256230ca8a"
+ "61811b0972cfd986017526181d24eebb32cc",
+ "921d2b026d6b7e22201de77fbf679990f9aff4ea7fe7ce4502215f9e7aa418b8"
+ "5f72eadb6b6942bb08a08be7da6619aa5f1d2ff961c9dc2c341ae32a254fdeab"
+ "a2f6450ac4474b6274f0c346f26da4ed555a8c951189dc8369f34d76d837d6f3"
+ "8a9518a6271c5b56346225a5ab8da6032a5930fd5b77729de632e1752fc72a0c"
+ "34aece25657b281be8932c5650c982fa145fde0bcdd48a73aa0288b4de461133"
+ "f27d51e386016a72726a9ede1d32dfc7e6f9780c04eb70ffffc2688295667333"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.3",
+ "317e6f5e17500fe94fdff284bbe50301044d1422d3ca700598",
+ "466d53c8d0bb9ed460caa63d79bfb877bc4ea345cab4357e639a95dcae379ddc"
+ "ea5d64fee99fb6f75ff24eb74d440344d147e43314a0f89f8b96148215368eb8"
+ "651f6d3ca0d08d0b4c73e6d1a768409826d43c2f81f30840605c43d0fe671d3f"
+ "024c70d0b89923cf904e39979962cd515c1674292aa30dac700db4eb7e63d56f"
+ "df08c22470f243861945d00fa4e27990212cfed4285df1edda4b0aec913559f5"
+ "9d125590",
+ "141fca68dd2e4d1de5086dbb785ff47d81e39c311d917a9939a6ff5b13439ca9"
+ "56c9742bcfe450b5bd035b541fab307f24fbfb3f8b90215b5604676e5696f3ba"
+ "95fdb8d090a6c24a29d990fbff1da2028142558f0ad75343c72f38823db7667b"
+ "05e16b5192b9336007f758106c328bd476118df82ad07548a726921fb2e192b4"
+ "3c8c30cc9b8434630e27fd8b23ef8d8f22be7f73aecdcb2b1ec5539d5fbb2cff"
+ "9ed5e7f19b49183d221dfd537d4f37032ef32f63b6ff74ee24a096cf45592709"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.4",
+ "90963ddab37891e7288b53be5d9dc567b1a07a1566c2afddd7727324ba",
+ "a49f1215175ba04c274abc051f0c17a08a63648943db2e8c7622bcbb1dcc567e"
+ "be6add8c444816c9d436ee93cefe23ec41ddfcb0a403bb6dbff0ae5d6fcdd764"
+ "dac1a72a484f36471f4f3bd725b2db5afa6acf530e4e4e86b4fda8782047871c"
+ "b055ad68c841de545a5540c8cc12e7e3f15814a0039a81034bde9c68ae2285e6"
+ "16b7b5555f98c613ce2ef666a022465c6367d0bda40c12e941f6998a14a2b5e3",
+ "8ad5bf78232aa36fb783583e71bc1393037d13e77454a9dc1111434e75dd8020"
+ "46bab42025420c63961ea0062657ca5065deb653ac78eb6498cf14d1704cec59"
+ "1169608db01fc93d0d68e62801b465a387a9c72f7eb35b0ba53a5efa98c9f0cb"
+ "7c7cba1804cd701d0297b66005ae25ec3b6cd4cf3194a3fa65d98c4b95333079"
+ "0efde74fa275d2a79d3310a5bcc2c81c91fc25562ca939f8d9c175edf4b07673"
+ "d53924e27b1552881c10831923715d149f1f319e38e91dfa566c5453bacc148b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.5",
+ "3d81021ff6473337e04b92",
+ "9b7029731377e82697fa56b086ce49d3c4b1549de81e3e99e16cd972297a560f"
+ "f483f2ef5b71b00fc684744f224e857e6d7239f156d7b6102f2304f8a55050b3"
+ "756c548f6ea26ea6f7394d2bb379333584e3b481d073c0a58a0ad787adb480e1"
+ "f20a1a590e031e6b2bb7f36a93610ddf7083a50768c998623f6e64376a29b4a4"
+ "18032d2739bd4e747ddfc77fe3cf2793a29bc767bfacc713e5f10e531b4c7189"
+ "97b9bb6b6515e071132889747e546b13468d",
+ "1b884b067d0bb1597f5fab933095755a530d9d04e2754a5797ffff5ef9cef189"
+ "5499982300503b3febcbaa09d36b7dacc30df3c868f01a5f17ed4a72a85b6adc"
+ "80a26a1b81976b393cba9b0c82cb1e2c583ab6f314eda29a433221b6e3ed5351"
+ "5374bbcd2b96f5cb5bd5815d1a5dcbf080d2d37cb96c4d961dc47e130db7b8d0"
+ "182e3369def4c0f6c42c6c20531af1a19036def08d4baca71b99af3c4e1ed527"
+ "d51f37d0ee1ea2c8b8ebf4fd5279851dc320e742008e04044d0da06436613d1b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.6",
+ "5c745dd4a8c592934ed15e22fa9dec4a4dc20a9f",
+ "0e6abb829a3b16d08b0bd43eb95c791af2a33912ea833ee6893ed5ad3ee744c8"
+ "b2dd28fcee808d3f01495825be0fe6373207a878d4a525ea72cfb0bb58a26776"
+ "fb39eebd335f04cf7186be61c5635d95e560eddfd45dd86a4e670d33568d83d2"
+ "ca203ed28d90e48b064d09a75f828deacd5b37efcf784fb11b17d6d9f2315224"
+ "f8e763791bac6cf46e1c23b0b0252c19edf040d35f592553265b886b29ca56eb"
+ "c5386371414d82a340",
+ "2b0a43b3cdc99d6cfc74da2a86ecd7d5762475d143e5486fa9cbebbf27d8e414"
+ "1ef72b6d4f13f664b3d2e9ec32227c1ad5b76c0d1befbd658968c7db14952382"
+ "49bcd95e7540254e65749823b8a34bf6a1410721df34f3c8d579f36aed9e0bac"
+ "231e54c27f7673197d19f51ce6acbbcb7b1a55e38edebeed3461073e80c79a4f"
+ "c3093130696bfff2bbcb74905f2d3444338057fdfacbc4db81935b29e99e55cc"
+ "c1d48d89e9dc4a63a011a62332cf570262a06359cc36c05a6fe18afb7832b32e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.7",
+ "b0e77f42c1a1e3f4155723a90db88eb153cb3d3a28eddf259c47056a470c915e"
+ "c955f83189f71aeacdd55c335f",
+ "fb3601105caa9a2fdd6dd6c5746f4fcafef441bcb0fb8a2cc03d0b57349f9321"
+ "af9d9984e64e2ec485c9ad755f140c0b66db1cfc26691c267731d1a3afe68720"
+ "2a9677e42e844d477b75bcbb8c97d99fcf72b3fb6d349fa9c476619147217a04"
+ "dc06aa3c3c176495380cb92c0a7e097b4b4c5ffe04631ab1d1bfea03678650c8"
+ "5c170fa4a1d64a4c135e61481490b62b",
+ "a4bdd492fec79c3a79093a44334272d9d17f543d0202c39e408bfb39366be2de"
+ "61df50ac458caeddeffb69e213ca92b7495366347ede733ff399aec796c3c3b1"
+ "df349f011da01fee7d21c1c261843de88208560c0e8984b95223ea3731db91c5"
+ "937a79b0db9387591ce32ec7f583e600f52444dfa7671ce8273898fbbca3a4aa"
+ "6832cbb3543abe9647e5f8c137728252ce5440fce10e4d4ef75d56b814d51964"
+ "4441411c10a2a14c350472827c99ea3ee5fda3880f341dca8d3d3a4e5e05ba42"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.8",
+ "b87f04b3350e1263daa3f9405e6fd3d25d8efa132556a49571f5708a42527af3"
+ "1db01edf79820f9326645fb1",
+ "ec8d014d6eb8d0239a9773bdd320bfb3f2ee8fc27d5fdd91f3f3905dc8a4c5ff"
+ "13529aeee461854cccd4e09b624afa647a7c04814eb1e57ba14df4c795b42e84"
+ "c4d08629245dacbbed27399a725a948f3ba2f8b64d2602dd0d5f55cb23eaaffb"
+ "3a66508e4a689ad9eee644e6a26d438f3663fea9bd0312bb0e7e5a6dee04bbe8"
+ "a0745a73d5ac89faa096a52ed3046d77de",
+ "775dc324fe9d5e05ad015013d65f0eba0dcd52ff9dfc1795ea93d0f433579896"
+ "86fe3f8b046223bba5c7849acac3123543432616c3103ac2ba8db0a1d29940bb"
+ "a262470e5e53be60e0eb724d07cd912aefbb87fb51980e9e1ac194da31929541"
+ "ca43224b152be6f2df6c5f0442b4f4d2cc2fb02739d485a01162bc8dbbad1476"
+ "eb06e245ab36c4c72d3f3607d05084a0f6b72dc8bac346bd19091b02f5982c91"
+ "457c7b10f4472b57184524214b23825b59f434cc48a2b854cab50ff79e59091c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.9",
+ "e195a036a530e1c2a9d7a103358dc2bd25b101bf704450ab8e5062cb63df5610"
+ "35",
+ "0ef881defc45ad3f3e58b1105e49b423ab89124a65b52cfd81cfd542b91e7c4c"
+ "1a6071a2cf12b4827ed5d19cbaf8feea54bb3d73857ee87c715c71b9ed1c07c3"
+ "afd90fce40448bb57e3524d038809839e36a4f5544c3e181e8c2e293cd5754c8"
+ "6574ade6dfce0ab34a80b4d48a9d42e7115d8cbcb1fa28c8a26501db7d0bb496"
+ "d01dd69265a026e1a97e9d3a1a65a8aa8ec2df0634e6f2651ef43540",
+ "1ad77a007ca437abd0159ed4b0b6815416f9f09d1b1215fb7cff115297601a88"
+ "30f20917863563853ed78e9c3d7ba4c97a05cf19dd329248471a4703a465178b"
+ "85d4ecd542241298c2fecd413e23a70c8a5d47c20e31c2dabe3c82a954502727"
+ "49ae2ebb89985d00b63dedd9596d0516d12a78c374b7eddc7dcee8e4fdd16c1d"
+ "fabff7ffd4c1fd61ce04be8e4975c5cd71e2cb0e541b8461bb81fb28cce77365"
+ "3e8b16b28a8c207428895f28535587a5c99d46ba4df9ae085018513d69aba3f6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.10",
+ "042a3922aa871eea0d78422ce78566abbb5b08c2ddf1ee30cf",
+ "5ae85114b0027a23c72bdb46ae7bb887bec5bad7a9884e93f6f4fd0bc938bc72"
+ "410cce96a14f4de199197735051efcdcc196f3adbfaa063cb3f7a234c6cf99d7"
+ "0fbb7e35b6aec66414669391e3cbe721ec991a1e5dfbb038f270368593749b20"
+ "8d089aaee2ef35c3daf6238b5fe42d13dde407df14f2d618c979c97d2de02933"
+ "b57fe8812204862b2f1dee983f24c2c596ea668e637d0a6ae6dc5265276994e7"
+ "e4f02b6e",
+ "1244de880e0f7852e996959d762fcad91565a4d0ad3bc52750d4a0440f0b5c65"
+ "1aa0e6f492061b2c8624c52ede6858fa2518ae8e8b116558b2c8076c17ae783d"
+ "8db25f0d8fb1f2758a82ab971fa7283ef0749a37be2893f89437fb8ea90072b5"
+ "855a2608fc542f5d2e0cb543f4fac528f94352d01640fc2c531b79810c00777b"
+ "c9e10dd9ea9996e74087fadcb71aa14300676571614882943f4a561412c05467"
+ "dca66ca49f8229351823db8a6b9f803d709c1187ed7410cf910015595ceab63e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.11",
+ "f31d3d0c30fd65d7b98b709944782e20525ca7c1f42d5d03a0f6d2759df1919e"
+ "ea82f80f1000fd5cf859df59871bac82dd9076cf",
+ "044bc377e8589fa5af1c17347d50e0cbbf901576f241de690c8816c129cd9f2f"
+ "b0831a017bec30b82b68f698311af6e07772bcd898fa0c27f62afde895897784"
+ "4625552d9bcb5a81aa3d7415b242a03b12fc1d3fe2d2ce6e5f71c4a4a4c7ca83"
+ "e0656f5002ac36d8d02b69ae65734498f131952cea481fa2c2965b6ef0517ede"
+ "50ddb09b3ea7026d06",
+ "86f66f0c250585065943de2f711fae4ff262700e0d3306a24c9430f87cfd93de"
+ "f4c3447cc7210fd94a143362f4f945c6dbe280bdef5d14f75eb7bb31320bcbd0"
+ "d88f0ccf2c95a74cb458c6272b58bf743093c4bba2d7bee9ea2dd30cf72fe293"
+ "c90c97430a047b17266391c51f5c398ba3df8cb74ba3e372f9555ccc97d6db76"
+ "14ea06d5c48c1c6006133d0e9d6995799385920ad8afc3deadf631cecc559caf"
+ "f495b08d683fb22aa697d71c696e46b1bf4fd76b8d0b39f179bf66841bbb9707"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.12",
+ "6a3555579dad03943543ff74e1747c257a83d35294c2539383e235de69",
+ "5d92434edbd4f5bd27197171f853ceb726303083ad4567a1d7c6104d192b9bcc"
+ "dfd0daeda274e5cdfb3d0c5d19c9682581ec7adc1a87e08151415d5a9adc1af4"
+ "50b1ba88d0ef32ac2d1f8ae345952814753af38e12635cff8c092159b4e75dee"
+ "a1983ed3d2d9ec2fe7b9a2e16a141e818b84cd9b71c129a8b3c6db620232dc03"
+ "a2401f731ff8a63da458a7d878905625aee1fc094dfb07b4575a7f0aad233e82",
+ "9310272d124bc5cdb721889840aa7715e767321700cb39b2b8a5a82ae3f02eb9"
+ "67e8db46843bc1bf62ed8bd2abe81434497f9900640253982d372b2bf7c1b09b"
+ "d5019674a834fbbdff3568a2824aed4a8048d2b861362775bd5f0d63b348363d"
+ "1378691f5dd1d7961074ed95fc9007bd5f5c2923c17c42904e2bf9d248779fdf"
+ "b203973841a11290c7e9e9356d4eab170e431bfe454a88010d9aff33700cee55"
+ "c704c82a7ffb15e253ef84f4019e12438f7c7386dc535b19ca86af71d477608e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.13",
+ "cb79af5aeafdf2bad21dfe62926642cba804ec7fd0ea5d5408ace9edff28e7e8"
+ "dfff6df383af144021460476c0c82c",
+ "5fcea257cfa92c84f0b8937d173faecf7503ab162e0baeef7e4c511f3e32a324"
+ "ed40e242a852ba57895b7cfe4d617961e036f663e0228a29cd1a95acac08a255"
+ "26d1ebff0ab3f033edbf1ae276a8d236736cc7af51b5d2bdc83dcc7d7d3bf5b8"
+ "22af2effed7efcb617e083e51be994aed6569b2383b941aee594c7b012e6751c"
+ "37b7a54e2a191824a130d55cf845",
+ "11fa819d3a638804eef1d9560a11f5230a0badfd66eb684e7d69dfa2898c8e0b"
+ "6e04af8efc7061081ec59e45857642e8b20041af508d9d4e288220f9fd389de8"
+ "b29124ce747eb68e2eaa8c8f6fb493f611ac09b723095d07eed924f6ab8e09ff"
+ "93c5516d1f0ebf62c5f022f5bb4f4cb5b8f5d487a17df7d012d704357abf1748"
+ "67ce40cdc55011b07139bea45ca0e581780de65417cc835ff26984fd0feba187"
+ "69c394a2e485023e31d3b0a888a7b14c781dd85bab408674f5f57e4b763d8435"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.14",
+ "d16233fc775c319f157aa200476cd6ed64a1ea",
+ "bb33b22b5f46794be83e6aff34a0e411d1f3f4b8daf9b5858724effdb969c955"
+ "25c62dc44bb2b083386003054bbd3666b78282606fe6ea172731bee11672d601"
+ "de32423d83f463cc2930f5fb79da1534c415c96582756594a999b226354248a0"
+ "9f141caecf88839078f77f40bd4851349c1fc75e1ece6fd6966bc9c9d5ec1209"
+ "6ed5043546859e4f957d3188e1d9060b59c1f7f62efbfe825dda45353e6fd4fa"
+ "bac983f944f4c2c79cbb",
+ "10c20c0c71b11bbece14c81483dcfa730c23d4dd61b8755b39949dfd4a3c5033"
+ "2160eec6f7710e09c7a97af93f7044b92f41d09fa3e6c6ce1f6411484ed47540"
+ "a1b59e23c19334b66d6820c2d44db0f6aaf85aa27f53a41f856bf6a591365986"
+ "9ba4abddecbe87413ac95be64009593b5ca2d0783a16f608665755245393fc14"
+ "4fe3ea5e9aac9f1f991a928538b46997d3063cc1a69adc192a40c76f92d47a05"
+ "80e3c02120023ece7032807b7c091343aa873f6a4ddde43fb2dcc379aeeef654"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.15",
+ "d2f3c2e6f43b0fc9fc2293b84588e66115",
+ "b9816489525cd026156fb4e8a4a8f34aea8a3aa1a634cccb3258918fe85cb8d4"
+ "aa02a52852a8941d3ea6c048b58cc6c75685675625e5e4dd7df93b8acec07967"
+ "0b49f3dc6e0763ed4c8e2d0ee9b5ca5bb62de006919838e4b69ba105d4c5a4cc"
+ "6dca67b12193a032b692739644cccf723f9f69e48b94c0bdce5aa35f75dc5392"
+ "7b81e342ce72c6b65cf75eaecac5fe0dea93885ba420af9932d84ca4b50e07e3"
+ "28ec5f816d2d8696b20df75f",
+ "80f1df25f36f314b982c9c8aafc0b8a1a2f174abb2980869c29d19be1d2d93b4"
+ "fb4299906c357fdd40e89a195492a9797661f05d3871d1bd0a5c45d8f9b0fee5"
+ "65b0004ff5afc5a6f89ad603e82283570bdb4c6e0cfc313e4e665a9434b32fcc"
+ "773d6edabce85fe7c80f03302a84e208b5bd0aad91ce62fb8c2bf54ba66f7e8d"
+ "002192162920a46e36dea5661fdd758153564074b8559f88936242fc0998148f"
+ "19eb50fc11fb24a7ed8c8349658fe9d31e6274d45d6f2b609bb5ccd17e284c99"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.16",
+ "21ee5812e3246dab9c3c259b2137d65f98a05e5740465ca22c69349700a42cbe"
+ "4ffb393fe28199339c51031cd3b22f2f0a83",
+ "e9de5bd355e6aff19fa11a2d0d3edc3f6469bd3c757206d66b3f09908ff618af"
+ "4801ac77b52cde03d4ae749d02155e5c70fc995f487672d280635855db4b64a2"
+ "2609b0c16067163c519042057cb36712c7c2fefed11f73c28bdb9d25f0636a4c"
+ "aa11269e5fe65a2b175686a15f1e48d28d345dd9a1b2900a24f9ddda3df3a69f"
+ "fb9cf5045ac4a193ae902f",
+ "7d8c531d4d3549e0bd2ee162b682539da61722b88ecf8c7df6d6b81fef5018bc"
+ "4ea10a7e1a4eaa0215d9b3cdf41347929eac2748ebd779945c9bc461dc51f48d"
+ "f6527553f07037e533ceb1348a46a7ea797d85a26a9f44c58869996ef11469bc"
+ "c10b756c02d5c0e61883685cc37d758dfde4c9b7354e3b4f316ca7f7fde659c3"
+ "fd5e332e1b6392a2929e131766ce9ba1d971ad246f3df0224338638bb653458c"
+ "d4b526d961744dafecd5998ad72aed3c34599f7a4098e3d2df9d13a21ce2370c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.17",
+ "a034a6c166cf0b25d2dde53af4b833b478c6b0d2fb0cef137fbf5c2712706491"
+ "237f7b286d1211d57310f8a762b1b3bfe19c9a4b16d3e0a8",
+ "d84417972287130a24a606f583297ac911528adcdbbd7de14a5b489b6786f9f6"
+ "f7e0b73bab538eb6c45ff34bd5dc43eae8d8c43f716516a60da247536f634be0"
+ "65d94e7f92adf52a967ee05fd9afd732333f99ad058297b28f8ec6feff802844"
+ "a0097df91a97702c483aa1c7892c7d43b6b91cd4d85d3ed2f1e955395706c3b3"
+ "39baf2a0e0",
+ "904e040723ab9788a5ed0352eb96c7f3d707cf0dbc258c51dcf6243406f0c742"
+ "c6cdf20767132c095e6c82a5025be7b4134d8fa4de187f8ecf12fdd3beabdb06"
+ "158aef46c3fed2d1833406eca7a69eb2d208a2f6f440d54f6be5dd564709eda8"
+ "12ac0629a94c7f8aee78beaf9e9378c8dd9c620374bbaca3941859dd702f6f7b"
+ "25a238459ee89759de9422b5bb6d2857166ca2120e634774a0d1d42eb8d94815"
+ "a1044bea8bfb02da5862cd9a745f1592478c6f57bfd13a5fdf4b8faae8a4bfc4"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.18",
+ "8fc6394cd6e17533d1ff8ebbf3e1aeaea330ed9f5a6e1efb83454294c6ce24f6"
+ "904a0e",
+ "be1c1802db44682e58c61fe38757ea0e384ebadd7959484b38bb235755c46177"
+ "e671769f36573d7cb0ee7e82087b584b58bb3005303368c6590ad9f2882cfa74"
+ "0d51dc55eb0c790f5bb6b6a3bd71f8b2146bb9e8034c35b7cabcbe10936ffc5f"
+ "0a8d7b30476ab91685aed8fa958e73c1eea3044c56b4b870da89371a93b89652"
+ "79b55bb92cc316c23ef0975351c749817db5dcd86b94adf603bd",
+ "b83c718ce5c6ab1e40ffa5670ac166664d3a6833cb3bdef462794a25d53e1704"
+ "6006858e63f88ab95d04f4fb6774f7005dbb2e22d519360d5e1338ad15308f6c"
+ "6412549567007e021cb237ed4af5eef3bcf9b731599f7253ceba8304f4ee8c34"
+ "3339d0a064eb77f1e93fd1cc7ba5fc3bb8184ced0e8697ac47b74620c494eab5"
+ "86ed9fe76e07e4bd2a2d1b95595b69c64677a8835d56ac639df8f643241b3e2c"
+ "4688d2adf228de2da9bb0a363438e751b5250deae305a3905e7e077a4e8c7466"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.19",
+ "89a12d22bf877d440a2e03aea932eb5183379b3c8b90bee8fed6fc6dafb0cf05"
+ "27",
+ "6072895e4780c8f77e0b195fc9f5db7833f7b6f5c81c1d30cbe9e80ccb386606"
+ "9f8db6963ad46d52942a5a73f6a327a94ed119dfce4c3765843713b619f9c438"
+ "3203d55e2ab61da8961a81037f1118a78297eb366a1c51d9f9466b715bb62999"
+ "e0a9d6e02501d47f97db409e3886e1366c3eff2ba790e26243227aa1588082bc"
+ "e6d5cde3ea7efbf15c6c7dfa545472fa9e93956a4551d5a77ca00e26",
+ "b7acbbcff0fa9fca6f0bbde5a2f0a1e6a0abadb32c89e317255bd18d12e1a60b"
+ "3e002c1d69356448329a49b5bd241910fa0ce03b3e68a590507599391ed15397"
+ "92293fef13174dacea6d2a05b39f684828a5d6d217f84b782c8fc9843caf6aeb"
+ "178f0e2c6bd2a0e6f7b809296117cc8a6bf73735846424adeba1ab31145fca3b"
+ "8af768c9d0a28e09d58ad496423108f08caac174acd1f3ac43486961c5c90e1e"
+ "fb89bddb7bb39f4ca3af5712f553af594cd5d364132914261007aa1d5f216b8e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 14.20",
+ "09d6948ce1c1f24c6d529cbc5d6d6c1beaab5695b30caab744969bf7f9dbd283"
+ "335e98a9bcd65dad2b4f0e3cec890b05e67fe97823d4",
+ "eded62a650f7de3b1280229d5fb1c4408e82dfe0317e6430fcf471b1e28da8cf"
+ "6b4bf4c5d031e3ee688b640772aa5008e5863c707a4022c329a6664e71101206"
+ "b54db5406e7fa9c8226f42931119620ca30de7d03be143940cbb4d1a9c86e986"
+ "3c987bff07023de19864f733da0c89bd039f19f4d8ed616f7c6e9494185b604a"
+ "1a7bf7490fd0d8",
+ "7addb05cbf0b17aa508a0b170c4c5aee84ce06650d08c9966d95d3071a9a8f3a"
+ "93f96a875399b478c256d0415e74849598211f9f9d0b89367baaaf174b7f13d8"
+ "490baaa740961f52d7e353c504818a000b03674d9ce493dc3a4ee9161301f61d"
+ "e521aef3f6d41d82e1c5dce02e636e7740a183f8023ad2614941d9b161cdbdf4"
+ "8f8a562c8ffe44f57a746f2639e5e83bcfd392d23e1fb4a8d85e3ba5e1cb9c0e"
+ "53f0d91b01cec0f0ef9dfe3f2b3065bd55b72fb17060abe8830aca004464fe7d"
+ }
+ }
+ },
+ {
+ "A 2048-bit RSA key pair",
+ "dcfa10ffa74665aeef870974ea99b2ce54547c67f42aaa6dd01a2ed31fd2c242"
+ "af5d960b1f896efba3543d6554b7b12687a5c688568f32e026c532d25993b97a"
+ "7c2842ec2b8e1235eee2414d25806c6fbae438954eba9d2755dffeeb1b477009"
+ "57815a8a233f97b1a2c714b3e2be2e42d8be30b1961582ea9948910e0c797c50"
+ "fc4bb455f0fc45e5e34e6396ac5b2d46239365c7f3daaf0909400d61cf9e0ca8"
+ "083eaf335a6fceb6863c1cc0cf5a171aff35d97ecb60ef251c7ec2c8a588361d"
+ "c41266a4b7ed38b026ce0d53786449dbb11a06ea33ccf1eca575201ed1aa473e"
+ "d1187ec1d8a744ea345bed7ea00ee4e81bba4648601dd537dc91015d31f0c2c1",
+ "010001",
+ "21950851cdf25320318b305afa0f371f07ae5a44b314ebd729f5dcb15da7fa39"
+ "47acdd915daed574bd16df88bf85f61060b387172fae6e01262b3864c2d3c22f"
+ "94e04a8159422b4ed279c48a4c9d767d4966071a5bbf5d043e16ff46ec1ba071"
+ "6f00bbc97bff5d5693e214e99c9721f12b3ec6282ae2a485721b96ddcf7403fa"
+ "037d0c57ab463c448de5cc12265add886d311ea8d8a5903fa56c5f1c9cf2eb11"
+ "cb657a1a7d3e41352dc3e686898c4ce4305e8b638e1b08a2a86cc9eb9866f349"
+ "9ac77b6136b81cb276d614cfeb7b6ed3f3bc775e46c00066ebeee2cff7166b57"
+ "520598947ff6210320b288fb4f2c3f8fe97b279414ebf7203000a19fc0424875",
+ {
+ {
+ "PKCS#1 v1.5 Encryption Example 15.1",
+ "2aacec86f423dd925ec158822a748cbe6c31a0",
+ "cc4b87f674497bb0e33d9e2a4a8070b7d78b5fd2c4b4f6ebaccd4ee505b71fca"
+ "fe2156337ddf27b475af33f6c3405b8e3c0c206ec2812922fcd8a3661b8619bb"
+ "c182f807f3a1072e62ca2bf1fa8b944e58a0e203dbb753f9f1b6ef627ebee598"
+ "967b387a5f9636d8b641b38984b1ca037e3aaeaa1710f51625ea85f8fb9a6e02"
+ "9e64575814d530fc146b3445ac4201b4e408adf655f67843d8871cace5d906d7"
+ "fc038fea885b96fb8eb1a721c6c14abbeb78fb4c798a19589959898455a31684"
+ "3c6cd99ef58c2b0b49b8ab4191b402a54c9297310cd224b17f214167725c48fc"
+ "c61bc47cfaccf15eb3b0",
+ "6042e745589af03af87520f93c45d8c35985ada1161a37d822e9f9460fc75fcf"
+ "0179d8491b8f5d1e4de8ceb31e07c4865c5a3efdbbb69a8803b89ee65a430a58"
+ "09c707569150b580bb686a94c5541c46adcd827960ce244ff688387d1616e85b"
+ "4d1780c6483606cf924b54f080cf4154e66829bf6e532481048ec41fadc07d75"
+ "5bb34bb28145219cb30d47d0d618709180e90303ff9ef09018bed3da75761da7"
+ "94811f96bc9e8d7c4ba1b5946bda0bd313faec4c993ed2748eed8cce4bdb520b"
+ "a7db165f9fe56aa8454d6ff33874feeebf29de2df5b7f00aa1d9fb073fc4067b"
+ "58dc50624e127f711dde2cc2cfdab4919ccf28c83660dfc227b0f500ec1f904f"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.2",
+ "5c8bf2acab08bffefa6480952b24daa5019d125fee",
+ "5e163070efddb79f4764f8a81d44460b5c400bec7037522920f772959fd4cf3a"
+ "ef2f14454dcd9e862512ca69db8368a4cd8d1a44da595d6b439391c93146b123"
+ "f186083c4b6447bf7e20815146ac7549efb67460e8ff1b2bba5c95a51ef813d5"
+ "dc4e6c3892bc4f439c99117ed06c14a6c540fd4c65d195d8c61ea7796838e5a5"
+ "dfaf11d0713c191e8a0b8080f7a77e703ab36622f1c648b765435b9027971811"
+ "b1152d972fb76aa89205033d9578187ae63488fda3c86b2f28e779ac4c89cd25"
+ "2017d1a9958a52c5b87ec1bf9cbdf7de0e97c58ba11ba3a33705f3f499589a3a"
+ "72e2c0fc5b16fca2",
+ "44e671e03bb66780ec0586d56f8f6a49415ad4bbce226d75d70f06ce29deea7d"
+ "a1afa8287e44363c510f34eb8bf31ca2472959269c18df0936ff12c6166f4f45"
+ "96cb1caec41deda8c50999bf4c944d21375b36753191b4cb7caa1b43e9116cbf"
+ "1da8b201d297a4d08bb0e5bdc8953270f7c2809678c44bea75e81fac22d27106"
+ "302bb69da074b6efa6688cf835c80bf5e4553528ece0b7c1b77b666ea34523ec"
+ "1fcb3e25054e0bb8e4ba027e5c21bf7a5143bf041ce9ccbcfafa878082fe41f7"
+ "8c70bf4e53cf487c1aadb01915cedde8cd9fb84efd981ac98cd57a8256d4e9e2"
+ "d0862dab0454d3ff4fb985264a46995ab068a74edc7ed8aeff5fa30f3a7d7594"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.3",
+ "e2004b310739982cfa9e95453a",
+ "e93e6412337ab7b0f1b569801a3c164a6f23e3c27c7c55a8c5ac9eaf318855f8"
+ "328b5d7ab4cb8619a00e9941ccaa948570527182617443c1d21e4a6e21b3f6d4"
+ "f698a61ae029172cf4da039d91585a87dad128c2fac5531b2f45dcef9b9fc331"
+ "c804488528847c90875d19075fffb005763d88e08147669228a9aad01625bc61"
+ "112cc7b772f321d433d4f26978209d0e79676af3b8a74b973f52ab919085f352"
+ "355f856aa40ffabce543d4e76d454892989cb383f3e66bbb0e8feebff7c6a54e"
+ "f2625fc4050e6f87a323132a4e671268fb83cff2d82251b79cbe32daa8e55320"
+ "2fe8872261f60d5bb511f2fa2f1421a3",
+ "2bbf6b0c5cf20ef2f6c5a0aa48454f850aa5f6bbeb030db4e2bec11fb200f01e"
+ "4eaef044d8143333338e5e66380087660ed0173a76821285677e371f28ec4500"
+ "f4d59fabab2073e734365fc6b094ee0adbceaccfe24988ce615d605fc3408c03"
+ "be221c993f61aa724fc8714a8a4a1815f9e9a99882aa46883e70474e3329b991"
+ "e6d53dc6b500861992343a6da89a8bd6f37f34e5deeef80e7d56b93a45176066"
+ "3650fa455d5541899a76aad1c6275ec82c4607122659b508cb5dc026acf93fa0"
+ "1a5fca3d81c1bb20a5a5cf357a23c95688ea42eb1ef2c9d46ae37f8cbe615c20"
+ "84d989b892f0167b23be3362face808d6a5eb896194408db7c01639c5862304c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.4",
+ "db6af1292305278c5b3383f8a41d6c83522114c988855074065b23f9feae8ea4"
+ "31fd5da36f9babf9dc61df2e39234783047338ec4f",
+ "cb851fb276a7491cd3efe4d3395016c1ec2b15094a1ec6d930d4ca21b420f847"
+ "ff6868f014d209ff807e8b1f71670b325094c0f6e32f84f768222202b21be36a"
+ "286b30e082ef3bba647cebeeafe310694418d70a679eb2010780dd0e96553c43"
+ "cbc6d00eac22aa71f24821c4d6c1778e786cd8c7bf2cbbf214e203e2ef2f3335"
+ "78cf1a947e27e59996290cbcd6ca3f8f96ba67e0e34130cfdf86ef48e67c90b8"
+ "b72e6f4255017da2d1f3aedd7fb1d9de42efc037abe6616ebda8d0b40bd780cb"
+ "db68ce54318fdafd",
+ "c99a9ab67cad0c41ec847bc27467fdf5bf61ed6d04c65f7d9dd8bb7007a8a9b8"
+ "3a3c38a9cb925e3e7b3c407d64669315b35449e75428ae961914b0b91023e783"
+ "191f9541b67865971c95b0be18931eb1c847c26a2983c0584eb217c99c705f5a"
+ "d8cbb09f99b06bdf7bd12628ae3667c12c7227d96ff9c108dce3225106f62f9a"
+ "4a3a8117a992f288c3b5979109878fcd59c6796b1998482ea82f301c939183b2"
+ "dd47880448678acba12d7bc8a552eb327634e92d0cdcf71effb666ad902d9e26"
+ "ad1860e29281d02fb0c5493bf74ac02c9440436e0d75322892777d325ec8452d"
+ "e758cc6a5cbb02d341f45c9ac8edf150dad71582dc77958a8544b0b558ee2a0b"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.5",
+ "e799e4ebc869319ee22580",
+ "3a0757cb49a3fe6ae80d3742068b5c8068b8c5885420011093c22099edaadb49"
+ "1f226f856066163ab5105e7879c7491c1835985dc494210ef78bad4816d9b694"
+ "c9c8be466a4d178a7ddecbce5365400d6821b6e9ae0e03bb69adc4ec734afdcd"
+ "ea6dc0c48596c48b2735ef70f3734c186d0318378d2bf8099688672fa38591da"
+ "4ae6fc112b727ec81984df7b56c9844e25b0fcd81d2be7d18d01646a6d9fe225"
+ "d3697c34ed2e336cc0373daa28d882e497757b0a6510862eac10d3b24adb252f"
+ "30d434e30a6376469d80b95711161778df35889b3acfb1f653ea63072f35a3c8"
+ "9f6ba52afbbdc28f23d38f4d4e79fc397c10",
+ "3a3e725c6e4bb0061269618cbb8a6267d95583abaa03d8df85a4f6a5cc359bf1"
+ "15260ddb70ae7c66bb8d87d6331ff1b0b54be5648e83e83a91c54cf371496ee5"
+ "ca0273b19f700370c2c8cdf4281338a6e72f66324168ea8cdbc64c609ba96791"
+ "c791b5ac8400992a8c66fb09f4e313074912af0cb7415fb215eb97faebbef1a4"
+ "47239a91db4a34fca4d84346259ee0a1dadd10b7f01fc8c53e420f88cdfa0cbc"
+ "f62be44b8a7940864ff8137edb122ac2dae5410a47cf0762e20f2086cbf66ff4"
+ "d1a9f7270f009cb2e07d9020b48a76d24108e9989bf904e4a71ddb91740ad7e5"
+ "d1b68ec64e3e66cd0e897dcc665739ebac451993f02cc5bfc63a602f558381da"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.6",
+ "099712b826ba67cf929225bd612ec065d451ede231c8d5c20404d470e79a7a1f"
+ "246e3eecdcc75f085329f8f17b81d130300fc3b9f093a2",
+ "81cd64c84d7765fc60e4de3ba9b4dd21ddfb74fe2dfb7cf619dba4cbcc176ed9"
+ "4e6f37ed1a97e3bfd36365d2644d3b6ee6c77109fa18412ee7cddd3be8d4bdee"
+ "94c096f072cab6f1886e3a84a7fdb5aff3dd83f7e5c5b49bb1b38f8faa752531"
+ "d89c88393e9eb8f57edc5b9fe6ed2bc95d272ca995f7e259b00832d98b872312"
+ "cbef8a048f6eb7919784aed3d31eb4b12fd80760a134c9d6c334c2dd3dfdf497"
+ "5cf1b51e87122b973333449608ffbb2cf30a02bc46ea247b4539b18607bd47d3"
+ "cdf0877214ba",
+ "786b3f599d1b743e23582624fa2c94a36fb6bd33fddd576408cc854ad7cf667f"
+ "17380af20b0b730c6be98c018076b9b5041daf2eeb025469300aa4364335be26"
+ "7d33b06b4a7a797a3c0aa5fd3f916a55dc274c0a2487f125f9da82596f434c7f"
+ "bac7ece2ef6c83e0348bf4f2c083050755b56a9c6347f39c76b0e0eedc615410"
+ "25c23aa1855c0b22b446fe1ec5f1112c5a7fc285efdc8420ec01a3a7c33f735b"
+ "4555092a9e8de16f3f7d469f88cd75c01c7f2e7d546a1b9e7f4984fa29a2cc80"
+ "d310f9d7818df6d9ad6cc205374d52e8e17390bde72f25b712a4269f23aeb241"
+ "a666e96496cd84b833fb53d0571f7ac2d1964b8f2a7e13336d9a7e03041dcfcb"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.7",
+ "5f2a5c7f93e714eecab3a55a69c79a3cbc15bd19df27989a9bab59fbbea9ffcc"
+ "663bf8e1e7407dc273",
+ "e01960826d1a69f684c9c0b85d84dca5811c89a2c0742f33a2ad199fb657a1aa"
+ "9813601d29936a43d9b9eb4d3289cd7d3706ab86b4d66adaa7e0a13451b2edb2"
+ "bc771091110cdadd7ee2e6aaea2b35cfae4ce3b1da1816684c89c0b3fb2f8779"
+ "b25ce0c12d42b1d3d30b8f20beb899916e4fd0a1588637192e0528ce6ea54c8e"
+ "b754fd7ff0032581a9505998e69e14f072bf95dfeff014df99ed7853b982e889"
+ "4129a1d27c53eaaa234c8d14a7ffc5f5e2187cef79ebf52b3d6c0665895bfb87"
+ "e4bd610e358f3526da0592c9e502b72b76e46566",
+ "77d907181cc3b1bb1981e8cb22f7ad75f882e26afd281b64db70c84c6a50fe74"
+ "249e22fbee90e30d0b70ae2f7e12acddf678f00d227e5361542662430269feea"
+ "34124792afb3f87b30f950f4edf22c4404c9688dec38ea0b99cb3dc384bd88fa"
+ "3183d7e07a2054d73ea51d4286bb39dae3ae6d0b9651f1ea488f805f2a216ea2"
+ "1a5676b97d1b11d3b4036ce167fef64e0eba419af673983fc6ee01c637b164e5"
+ "aaacc99adee9f47d219254696c8fceec6c74ac4e39051e15269401738264f0ca"
+ "5bf122c55c9e5dd847b1d5774e7408c3684aa974b0baaf40edc22a0357af72c8"
+ "16cf731fcb63965360699f269997b8480f30a6b5d57e12a5cc54ec0c805fdcf6"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.8",
+ "556139593eee8b6e87",
+ "2de2a57224f5f5b12e223eb5f82b9f47249d25559379136eaf18e2f6c833e3f0"
+ "1bdeea9c303bd9677c2a85717d593a2802aecbc6b3b71f2c7903ff690e3f3c49"
+ "57dd74cc9c2a68dc1d319c1e1787bbb7f0e6e51e39a5badbba9fd46766197431"
+ "2b557af18952549f6eba9df49f70eab3689f9fa8fbea1c97e1bb2f093e6aca9c"
+ "380edc546a19c44f91f6dcaa289bd114fea1b036f99b1a57f86143d8675bd07d"
+ "4deabc9d510c617099449ccced5c4507b79e851efeb18d06b199810bb6b3cbe4"
+ "1273baa7351602e5f95213f96955ad5fdd3a2052dbc75fcf60aa2247f2d4e603"
+ "da45370de1c1da687e268ee44667f94dad13bc9b",
+ "4ace54a752f556e36eabb11948958412140c80c31b61dc40f81a6b1217a01ce0"
+ "67ab37f53df4c77d9ea9c2d7950c8cd49700b8cd24d4e78f7fa3462962cbfde6"
+ "d02fb0e5036564932505ae1c851aa6d1d84efd04d578ad68273a36a8ae23d145"
+ "2f94a9378817713e764a0917452629b5dc75b57b0d5e6a728c83691172d2cd95"
+ "f8bad07db468ebf545b7f3f2c863b6e20c67c4769ded0391a336f3a5d87e24fc"
+ "f91aaf774bee77a789a5908009c7a55eac92af4c3d461e7b40616ce806194bfc"
+ "2074c3f4f13559700b2708a0b755789670a3626a14638811bb18e15b1025c3b9"
+ "bef111176bc1f2469ea99aad20860573d6c6a1fe40db51e36fe33800101bda20"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.9",
+ "9a1396622d066c10560858c2c4cd5c04449e2b9550c5bc9293761a9104411da1"
+ "8a57d9b6a997333cdbce77e9fdbe6bb831",
+ "f17861acffb24caced90ba38aa7ea0f2e54eeaa62ae66498f3c28f996bcee253"
+ "bee8199e3eb80d627feeb6e0b39490edf76d16a2a0bc20093252a9d7f1f9388b"
+ "061944852afbe73ce413a3fca521b9474e678129464d91b82bcaa59f56ecfb12"
+ "4f61f50467130105b2cbc6943b953695cfcd20c9b6ef53f3f210331d3932dc01"
+ "0c735929096b2e68ff16664b0b90a0fa1be460578592b0cb4d6ca45ea06bde3e"
+ "8a1ebfef70d83ef79b3a74db060fc0203b74807f407001f4b4d99ec5158e8e7e"
+ "4b102a515de95d2b70fe1fb4",
+ "100ece634525d467f6d4a6b66ede1cc237f61fb2b67023a83dc456b92cda183e"
+ "d6620fe57d5a67332c77233ac1e8725b36f8e1b108412ca6fb35dcd4d81677a2"
+ "b30d5eaf25e0b9191b38f7eef83f9121a808438c92ab03f520807bc9a894705e"
+ "af4eed066823a67aa2a5599cd95e58da7c094836d2afeba39dd009a64ade0305"
+ "3376f02936cf3f56bf64c1f3bdc07c45a95b9fcd9396cd9a8d41bcc56424937a"
+ "1371b3847c905b9ab58402393d4046e4a015c14708f74ce7790eba8af7920724"
+ "40bcafb14c0f8108971187c80f463a1fff258646ea16e51c6ee361b661a14f07"
+ "cd4f5a82c709f494f1df0f803b6f64a72fb9c450ffe268fcab487d4d63013e41"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.10",
+ "b3824fb545a83f82ef8223118284c5456bab600adf79f50733b6668fbc515da5"
+ "963162a6d7d7e96ff91aff12eb3e9311e221e70bc0",
+ "b8268e4bce7e53f2e8be98b192d63ad06544a80d6e62d632486e15e575ba706e"
+ "3e768930dc8e411f8eeb0b6e8f060629da8a242368e479ccb331697070b4b352"
+ "4e69169276bab0a94514ccd660702528ed20b5d1df07779a62c65686e7d66846"
+ "6ffc748eb34344ca6f305cda3dc3e8f01c43ea9179da462147f4d3ec92f888b7"
+ "eeaa410e12c86d8942c7d012f45c61ffa6e2b78f843e9a75d9673214d558caf0"
+ "1b45f93686eeda5479db8052792559cc236a4a1ee65d3ca60e09a3c184d4b395"
+ "d70b8ef88d78091a",
+ "c0e98d50894ada849fce8983f6f89574034d6cf3b8352bfc50724a703dd4f42f"
+ "4006ae008ad97233cef6f16ce1b423f52c6b677ef005131ba987f98c722faa49"
+ "42ecce2c99663740a1a1e98120faed97fd03ff36fe73758e70df17f31f1f3941"
+ "812d34cae6c39de787ef5704bc39c920ea5b0eb1833e83b45794fde0ff0005c6"
+ "2733c70a296ca0bd47f065503ddce2d649de1c328ddf6032a33fad46ba041dc0"
+ "a994bf0f56a465f1625fcb81ce01fa299fc2b3c80939ebe6a673826e2b2f12ec"
+ "dda5035c9509312dd19f10c35c8a8b0da63c085197006a9be236108eb98791b2"
+ "6e2808b5ccd5acec738bca025b24182ef4ab9cccb171a69fb423a46e037a4d0a"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.11",
+ "a3a7da1bedb2ca99fcdeb7a46d633eca35062df2896b695907a7f971d2cc50b6"
+ "e3d2a367d16e727f5697c0",
+ "f018a9b13fbe560bfe9552ed8a8606beea90055ed3f62bb2af07f692cb60acfb"
+ "6d5907d60e0a597a54caeaf844911cdc874faf956953a27d300e9b715b104df3"
+ "c232c3c96382cf5b5f3d07b230b525bb330e319d1a7c82d153af817ef11cf72e"
+ "76dd50b0d7e5562265c8345da829f560d6a54e6f1e288a3dc2176d19a68a0b1c"
+ "5c92b16b8bb29e4d01dfbd0b18079bd40cfcd52335b3a18bc4ee9244760eb494"
+ "f5be5b1971886ca2beece0a3944fff8be6b42d96e1c2c72e4e90f87ed1361546"
+ "7cfc91c26eb38a7af9f56686931a4726da04",
+ "25177bfe12619b44f4a4fe7cb76de93d4ed4a05a31e5be8cc4e560661de9a34a"
+ "e317cc02ff63106708328bd3f78763ab3e57652c63f105f7971d2d8d701e6297"
+ "a79c787b7ccd62a53b39d9c03946e66f488a92e8e17dc6ecb0f65bf01e3affee"
+ "997687311be0e945add63fa3f400382cb8ffd8915754018cc75e828226b5039c"
+ "d9c57fc6d99cbe8ea4a3d29cbd09d54d95cc0734c23544f8e1fbc7493e06d16c"
+ "0a0ac1530d21f0337e262fd9d27fcc4afeb574d66866d4ca84cfd6e0af2bb977"
+ "a5d99a5b0b3744042d332b936bbdd869e5f2c883b400ac8bc0683e679063429d"
+ "98d494f31804d65bb3c974aa72e6657d4c1638c679c81a16453f6b0baa3f0517"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.12",
+ "49f6f8a4a86a8aa09763aac85572b0e7ee776aeff8a829000776ffa6",
+ "6db6a827ac2a5e0616c0f443b23458e175acf9a3b255f5c8525e7253424faa91"
+ "38054c3dbaa471f27fe855c1c0cec362597a1a1e6eb4f298ac3eb734d31ff0ef"
+ "1008c0e02b9b06e29315fc094a7ed26b11ea55270a3dcb6706f46a9450bf8312"
+ "881065130248d2644766a79966efdadbaaf575ef4dd35a937ff0bfbf3d9561c7"
+ "54409be7b8847a608d791fb987eed46afeb0db1ca975c05f61570dd070985f13"
+ "e4e0ed7a8cb391ce4d420832b45a8b7e9f90884e611898f472a0ac46c57aa7f8"
+ "468aa19d9c7b312f134322990393881d32aa1468f6e5f8eb85a2c3c2daed92b9"
+ "3c",
+ "0ff95f4a2a0718d673f9202c809f1045101f52b9dba77288fe288cb277c4dbaa"
+ "35db9327eceec3765ae033e0b6b777b22ca6be662003eafa2bfbda606fd8cee7"
+ "eee06c6a00c945a6556c60b00869f999971a8c57afe1ddee7a7577047a0db90f"
+ "62cd247a887f3227ef6da907a75bcff19aa30c908f5835ef10100adc7f6ad6fb"
+ "3199790b3f4d6ad19a0df5027fdb8f846604e02daf3355d956407779af155acf"
+ "a5a32e6d6174dc90131dbd7abe585dd759fa3cb7e9f721453f3e354fe7be0b11"
+ "8ef5b87942b5fed4c30d7a08fe2464eb79a3debab37b6d3a0ab31577de7e9322"
+ "9b49d1e8fd5632d026d83ee06aa78534cee3081b222ec4cd9488ccde4e152905"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.13",
+ "12975db73d",
+ "6a4b4fb805807272965bff2f4c800f964fa3aeb9fb433b40c8acc598b4840298"
+ "93a219c9532134c06ac8425c28a5f063c284200a045643489716516a987bf81b"
+ "a186f4ceb8d8d9dc1d73f2267fd1988d6a2ffd68cd3669de2b04700943d0d444"
+ "ae3da8f0594e6261e5fff607f04df31e3d9c9122d76fb90f3f82c393253b7520"
+ "165bd1f319ab3b875ecc6ab3ed0247d03770f8d6471d69cd13ee257c1fc8b30f"
+ "19b93fe4f2fc9c21492813d1fc852af70cdc6384d2ae55b91e39ae6c3b19fd1a"
+ "7deaf718c05d57809596a288fc9aefb815aea29faf6783c00535fd71d6254940"
+ "b762f507261f209bc8ba9479bb3f5d64642319cc3186859c",
+ "2715d6eb53aee6d4bddd3be9b663144a410d0381779f799dca880792ab431af9"
+ "989deb17369dc67438add82bdf0a59dd3bc278010258c7df876984ff527678bf"
+ "9b34c07743b5d22f4f30cb5d7d8a6cfd505824f2e094024fb04330f66da7cbc0"
+ "1d5ecc8dfca1ca9e5091b9d9c8e38d0ac3931de5d1fdc833738482a7fd152c1d"
+ "24e69ea01dd3e1fa772354a607d62c60b561dc5ccb012b712f5c2da1892c3120"
+ "ef990d74611ddd3566af1acd8b4850061c9128f82ad112da9f68ac88393f9a5c"
+ "2c1020aa77e9b62e2d1e985fef864cc1aeb451ac839c720cb973e7b5df24a98c"
+ "cb6e67726629a366fea3f9a9521daa19b04430e810f2c45a57d4253bedb91da0"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.14",
+ "8de0f5a413a7f786396f09a45e5e774f3c609ce6f1b490dde222b322d5340e9b"
+ "105581f4c5be44eabb3d1b23f845",
+ "f871a897aee845c3bb826990b731d2777cf476b5cfc5596df3a523ba6979c7a4"
+ "5179da5fd60f810bf414c54e182f2601720ffe8a50d7d9d11e564318e9026f07"
+ "c5aaa13ef891283a9663c1e3d27b93817d01a56fce33d5169bfea62a8ee6c370"
+ "a3aa8c7194d9d353d0981661fe85816250e0324eae1b847fc732919160d01e11"
+ "92ac16be0eb8e995e48640276a2db7b87f84b3fac04ce862f02238623f62b92a"
+ "2e327b01b8c7b9e5ec87055c6cb7b55651ab5ac989833b034f8be0116f28b1e8"
+ "86a2ced123298eb004075a6b5b71b1",
+ "d367aca8d4f17414e9bf09ad811d78db0e850c45c8f9d7024475d3e56e3cbfbe"
+ "6ee8abbfd7745826417cc8ed52f54e00a92f817ef983e98d100a1f990db1e290"
+ "a8516d609bb32e502a77e11f76200b0025765e9bd2859ba94a696333a5ebe2eb"
+ "25ba9d19007f64360cc075cad7f09950e4b7afcbac36e6ecb017cf4a1f25a4d2"
+ "b951bb85e81cb2b4eb6f45cdd400d2ac4e2169896d941582449ce30f69c17cb4"
+ "49321f65e44df303878627621351f52e5a0752e3b5eb126361697f53cf246616"
+ "5c3fbd662b837580b76d459ff04497e5fe1b3cd18c4d58ffedabdd04a8c108d8"
+ "59b65298639c3af80cd94e2387a8694409ef9e0b78b6f467390be108579c9b2c"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.15",
+ "9e78c82bfd0f23d391e7600164019aad28f59b14154404d9e966133c103fc37c",
+ "bb42247db240bacacbcbe8c68cb0f70e460a4973dae65699358fef8270d65c3d"
+ "0c455a379c563c597b28f4ffa070e0ec1ebb9ed427fe89abcd4793c422c33887"
+ "8c8b145b46c4f71378a0fd7d5053b86798bc02d93293fed847f18fe06159074a"
+ "c189d956232074db6ddcf9941a70f28b60e483395a2d210154b62abab8750f5a"
+ "ebf1acefe2056f5abd2f0e0ec494afa82fc59bb357f116a94ec1cd0603b52fe5"
+ "6d31a43b87aa637788c724cb6f88373c92f60711bf3f3594e23dee2fecedfe6f"
+ "5fc886e96aee7c746822e56cba7ebdaa2a9210ea8198e4c22de9298945",
+ "818dcbba98c346793c79d4bb785aa640191b05f8835ff73974443bce357a269d"
+ "44646e8c79102dce22923978a3941ebcb9904fc1bb1fb43f11275e71eb7a84d2"
+ "74be104b00af9225e2a4f7f5a048abb66cbab6525d1b115da8c0bb08deeaec7f"
+ "80eb6c39504dc4eb38154ce4b691b4069319b293c25dc30b8fb38bca153e2fa6"
+ "1b3376ddc3c53a579321d910a171fc42aaf17050ed6d311a7df5b9a5cf3a98fd"
+ "69aa85ac2346c16fa03b1e53d103d6f5a04b0d9d3f1883531e2f6341fd91bd63"
+ "a5aa993b6edb9992e5db17a7be555eafa3bbab32086e92b8b791066968e00f8a"
+ "177161440ce538579789c2912ebd7ad019be29376cadeec2992107c9db076049"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.16",
+ "6d7208b2ffb01ad2360c4609f3bad31579c8d4005cc960142e2b696b26e94f2d"
+ "99980bad384105b1899557af890525",
+ "72ae49971828ba5423ab963cdb18f4bdfdbc7473cf70fb77213441f1d446ae48"
+ "109303a260c091ab5199d964e62163c24657247173cb0511b9cbb163459c956f"
+ "9c0b1883b691b5e4eae04f0af24ea328c6de882cebc4f89a56373282d60af2ba"
+ "967e257ac401a37f9441c11f2e0e421b2d151eb243a97eae5aaa86cd38df43c2"
+ "6a1d6e3b12c13fa3597b85bbaa1309452c7e9b325d8c73fa799c575652737b92"
+ "a247d23c4c701240c53dcfe2ea697af61c072fa76bdb052a58c919e69ec57b39"
+ "a2a6c47d770ede6710fc7bdde601",
+ "4b56dcd304bdc7f0ccb70d2c586f5274601ee60536bb218061671350d6d3ae2e"
+ "284f07b5ed630179269413122b98376090f7a4a4f6434af73ac40c7af4b6d7a3"
+ "e314702ab9b85e08731da0d12ed3f0070b0d2095053b3f0d09d6c2cd8f98bade"
+ "d91148c35b7b33c543653ccc32d836f5f7f2ee39cabd0bd89dd9a4a94e912b4c"
+ "a97f1851d017451f6096acbf20a65ec5a29f08f8135c7318a2216d1b7d103795"
+ "c7ec8ee57a79280f9a844bd6ab7128820e1fb5e82554fec02a78aa8d3fd6a13e"
+ "0fad0ecee7ab611de4b0a0481f42b8d0b55cb8813d1ca6e2615cf5ae8ae86d0b"
+ "5d4695507549f7a37366a445fb55b7c4b6b58ea699dbe5ddc8193e2bf3d5b840"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.17",
+ "7deb6d404148232c4821634d3df9bc",
+ "e6f83c8c993e6015af430409684e627f3d9b84ad0555c6a6c09113a712472abb"
+ "36f61192326cf84082aabd1ec95f4d1a92d9107e30610c8d2759556d5d61475c"
+ "a3f3cbd949fac2203c423d56c27558e6118faa0f6f684ada13c3153f6d255338"
+ "bff734e95f60ad2919abf28815d3cc0b1efd385d0d4581b0ee8494f2bbe29959"
+ "91ac1ea81540cb7e885668e5a52eca9057ed9a1fb23fdf83b57551358c23cd43"
+ "ce0e7a33c72566b88fe59343f1872446d32c44b3990aa4db3ee593424c8e0946"
+ "d261e3270ef4076bb35df3c3c6da4bbe423f591b5c93ba56c5cf01d4f0a94096"
+ "7109d39b939df282532e5483108b",
+ "aa6e6e4af689264d61bfa8f5086d8279ddc2289c5541af453519c44b95eae6a1"
+ "5e7e7bd15fd31a4fad5f7c85905efca226930d67daf558b715b21f3628f61a3b"
+ "042c1a38f9af3ada82ec4488c8ade5f1da81e1a8ab90e1b312dcda835f9e925f"
+ "2e72463fa833a08b93253fdfe8cf4e5f3cfa91107719a6a9469acd7125ae67b2"
+ "bd75857c59be0abe984074e295478af2740e25894e56a6250ef7362194138103"
+ "743ca9544733d2505571bee00f178a2cfa38e1f8f22fb23930d6a75dd17c689a"
+ "476d8715318595108fcce895e3449eca97a7ddbae3e6d6f0e35e666d6fbd7878"
+ "48f8681337b1d4c5238b1c24de77a7e675e7aed8dc13dd9eb1068798517c0b6e"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.18",
+ "031fc3a3eaa42b0d9f6d7dd5993d6189cbb2e0e96faa33d61f317b6b3c00",
+ "16ab6485cac0397114880e6f72bc1f1ef34ba27d1c433d77f3372b1fd5b21ba5"
+ "7a505cd8f35b75242cf1b76d381c68342401eeefc84253a2de1a1913e438773b"
+ "7bcb31cbab258f726ac934a87126969adb7f768c1bab8754a13a3ccbba6f3dd8"
+ "d0ec6a7c6d687d0495b6e22c9ae767afc9d94f2e45a106133c42c79b52c26ad4"
+ "b67bd8ece55e84325ca6f49c8e9531f5f6b9cac35c933eebe3b9a11b9bb1c9ea"
+ "8ce6d2285da908e5919782b5b308fe478d98e49aea543bf8ca1b22edf43fdbf6"
+ "af31cc8cd4fb7de2d819afa5483eacdd56d7787bc8bb1622384049bc309a66",
+ "61c754763043b584e4a8546b79f0a3e2e0f3b3e2db6c94ad817e9281f485c082"
+ "08fed4f4d7d0a78c6c311a07c75b9bbe8504f4b7a692990216de12585c009ae5"
+ "8c26f085071f395e5af8925f3933f6d9f412d425546454e800b7e3aac78b7a08"
+ "b92e798bb834ebeadc4b4a6356af1ca09bf586745f616d51748cc7a37b48cb10"
+ "977e303bbe10bf27c69bdff0ba5cab8f62d0587a09d6e022823233c8c7aa4187"
+ "2223ed15a74accb0f1f822f24d7594ed9925a1c6c0c0f9ad0e071eb6b5ebe1ba"
+ "b6ba3b6d99a31652047f469260bee8710e370f04ed707593937a08dd82264992"
+ "311f4af9884cf8ad34afb9f675993c8abf41519839f76fa1e931bdae1d08a634"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.19",
+ "c9c93afea997b1ee36fa72720354c704649bc6ef44f5187c6c28542b9ae955a7"
+ "193fffec867bb62e219e68",
+ "52d4c3bf0c772c02d3bb711d7f146d8c4976f83081be4953d4afeb078e5412a3"
+ "2c3dc737b59bc454c3de93a1aed07c1ba64d1de4368014d04f6440556a4a1697"
+ "9d0803cc2922da97ed67619012f8f7d3b1a45584b0946af6dbd4a0857d4c2db9"
+ "9a17bbd27acd9a62e67f8879dbef27f1046a867e6995162b2a1a1cccdceaf45b"
+ "e1337e5fa8f85edaadf7508d58f326aa7cf301f441ba558b60e0fac6e0d19920"
+ "61a0a469be021626890ee87e68139bd519ae773e3ec481b7f2b377331f52f2e3"
+ "86884f765723e26cd4a8d968614c9c33dcdb",
+ "d06867022a0faf573d62cc24a6e06a44cd3d83eac5d0809ebf91304568cb1b27"
+ "561bb292e8776e216d1d023e753c124b51867b94dc60894d62c7dae5fa1a9faf"
+ "0376e1758cb6adc71417e83102528f23f4c5e5b50362a39e2aa9768b1062086f"
+ "a8c53ff1c39a0ee03d383d24bf490722b786daec908cd7151e185ddd17882678"
+ "027e368b0512cf98413f3e596fa3db4ec196ae5ff524a8266d760e0051433d18"
+ "98ffc230e96a2f0bfdf2b24429adfa918aba1a450f76783472301293848bd82d"
+ "5a338431d6cb1c106dc741d234bf5a80dbd325da64a394a0065f22028d0fdc5a"
+ "df0d0de29f22fb8c2a41331fe1fcb61589e0ec7500ed8442d61846df6cca46cc"
+ },{
+ "PKCS#1 v1.5 Encryption Example 15.20",
+ "69b7644855f91d1c61c8498e4ba1ba4d845ba882b173",
+ "b22fc7de85c5f75a2f32af1bfbcd5789715687de06e66d064ae3eb8dfb07a257"
+ "5be0e9e6f29f50d7396d078b36ef802f751a77cc92d7614c91dd279931fce007"
+ "ebf915a0f14e312ce91fe5aa6fb37451614fe37c73fc6f6d6f8e52789b5d88e8"
+ "6beb1633f5ddd5c070f14fd3cfee97dd4a643d35d45dd9bf34df8c310b48592e"
+ "946831b34ef3c0b916f17cb0acb2cfc1c25d0309acc1124f265c1a83ed885c87"
+ "fa826fda5710b54e16ec0f448cdb7ee0580ff7386530ea461e042a0b7742c461"
+ "976bb5a380adbcb00106f2671b6cce4f7267752f8066804278350b01753e31b3"
+ "8eccfbe90569f6",
+ "ab4267972c7796839388d4ad87ded74bb653e9a7050e282e82192875689f70ee"
+ "1da18a1f7322092cd29fd00119922a6de12601980aa9fa6e619e2775e87adae3"
+ "1695c1304e77f52cce016665f2267c20762643c6003c016d8480443c701df6c1"
+ "d8d655549600ee455b70e473319b0d4445e0b7552a1f808e88f3264842735ae6"
+ "1df0325ed03690d6d5d693ad1fed22668450379db5323dc01c89affae369b9c3"
+ "01c319c37ddf51edf46e09b21e5de91483e8e3cb21eeb7057bc2ebdc3aaa3d65"
+ "00c92f99b17b3180bba047d76073776336b15d054d79a440cc5e985ea543fcaa"
+ "25db1dd892b71bb74a5cf68263d8fd58f1a48e6c2fcb8c0b71a251cfc1a20157"
+ }
+ }
+ }
+ };
--- /dev/null
+/* pkcs1v2-v15s.h - pkcs#1 v1.5 sign test vector table
+ * Copyright 2011 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Manually created from the file
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt .
+ */
+ static struct {
+ const char *desc;
+ const char *n, *e, *d;
+ struct {
+ const char *desc;
+ const char *mesg;
+ const char *sign;
+ } m[20];
+ } tbl[] =
+ {
+ {
+ "A 1024-bit RSA key pair",
+ "a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991"
+ "d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1df"
+ "d5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f1"
+ "05acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",
+ "010001",
+ "33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e8"
+ "94a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9a"
+ "e55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c"
+ "31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 1.1",
+ "cdc87da223d786df3b45e0bbbc721326d1ee2af806cc315475cc6f0d9c66e1b6"
+ "2371d45ce2392e1ac92844c310102f156a0d8d52c1f4c40ba3aa65095786cb76"
+ "9757a6563ba958fed0bcc984e8b517a3d5f515b23b8a41e74aa867693f90dfb0"
+ "61a6e86dfaaee64472c00e5f20945729cbebe77f06ce78e08f4098fba41f9d61"
+ "93c0317e8b60d4b6084acb42d29e3808a3bc372d85e331170fcbf7cc72d0b71c"
+ "296648b3a4d10f416295d0807aa625cab2744fd9ea8fd223c42537029828bd16"
+ "be02546f130fd2e33b936d2676e08aed1b73318b750a0167d0",
+ "6bc3a06656842930a247e30d5864b4d819236ba7c68965862ad7dbc4e24af28e"
+ "86bb531f03358be5fb74777c6086f850caef893f0d6fcc2d0c91ec013693b4ea"
+ "00b80cd49aac4ecb5f8911afe539ada4a8f3823d1d13e472d1490547c659c761"
+ "7f3d24087ddb6f2b72096167fc097cab18e9a458fcb634cdce8ee35894c484d7"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.2",
+ "851384cdfe819c22ed6c4ccb30daeb5cf059bc8e1166b7e3530c4c233e2b5f8f"
+ "71a1cca582d43ecc72b1bca16dfc7013226b9e",
+ "84fd2ce734ec1da828d0f15bf49a8707c15d05948136de537a3db421384167c8"
+ "6fae022587ee9e137daee754738262932d271c744c6d3a189ad4311bdb020492"
+ "e322fbddc40406ea860d4e8ea2a4084aa98b9622a446756fdb740ddb3d91db76"
+ "70e211661bbf8709b11c08a70771422d1a12def29f0688a192aebd89e0f896f8"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.3",
+ "a4b159941761c40c6a82f2b80d1b94f5aa2654fd17e12d588864679b54cd04ef"
+ "8bd03012be8dc37f4b83af7963faff0dfa225477437c48017ff2be8191cf3955"
+ "fc07356eab3f322f7f620e21d254e5db4324279fe067e0910e2e81ca2cab31c7"
+ "45e67a54058eb50d993cdb9ed0b4d029c06d21a94ca661c3ce27fae1d6cb20f4"
+ "564d66ce4767583d0e5f060215b59017be85ea848939127bd8c9c4d47b51056c"
+ "031cf336f17c9980f3b8f5b9b6878e8b797aa43b882684333e17893fe9caa6aa"
+ "299f7ed1a18ee2c54864b7b2b99b72618fb02574d139ef50f019c9eef4169713"
+ "38e7d470",
+ "0b1f2e5180e5c7b4b5e672929f664c4896e50c35134b6de4d5a934252a3a245f"
+ "f48340920e1034b7d5a5b524eb0e1cf12befef49b27b732d2c19e1c43217d6e1"
+ "417381111a1d36de6375cf455b3c9812639dbc27600c751994fb61799ecf7da6"
+ "bcf51540afd0174db4033188556675b1d763360af46feeca5b60f882829ee7b2"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.4",
+ "bc656747fa9eafb3f0",
+ "45607ad611cf5747a41ac94d0ffec878bdaf63f6b57a4b088bf36e34e109f840"
+ "f24b742ada16102dabf951cbc44f8982e94ed4cd09448d20ec0efa73545f80b6"
+ "5406bed6194a61c340b4ad1568cbb75851049f11af1734964076e02029aee200"
+ "e40e80be0f4361f69841c4f92a4450a2286d43289b405554c54d25c6ecb584f4"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.5",
+ "b45581547e5427770c768e8b82b75564e0ea4e9c32594d6bff706544de0a8776"
+ "c7a80b4576550eee1b2acabc7e8b7d3ef7bb5b03e462c11047eadd00629ae575"
+ "480ac1470fe046f13a2bf5af17921dc4b0aa8b02bee6334911651d7f8525d10f"
+ "32b51d33be520d3ddf5a709955a3dfe78283b9e0ab54046d150c177f037fdccc"
+ "5be4ea5f68b5e5a38c9d7edcccc4975f455a6909b4",
+ "54be9d90877515f450279c15b5f61ad6f15ecc95f18cbed82b65b1667a575809"
+ "587994668044f3bc2ae7f884501f64f0b43f588cfa205a6ab704328c2d4ab92a"
+ "7ae13440614d3e085f401da9ad28e2105e4a0edb681a6424df047388ce051ee9"
+ "df7bc2163fe347520ad51ccd518064383e741acad3cbdc2cb5a7c68e868464c2"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.6",
+ "10aae9a0ab0b595d0841207b700d48d75faedde3b775cd6b4cc88ae06e4694ec"
+ "74ba18f8520d4f5ea69cbbe7cc2beba43efdc10215ac4eb32dc302a1f53dc6c4"
+ "352267e7936cfebf7c8d67035784a3909fa859c7b7b59b8e39c5c2349f1886b7"
+ "05a30267d402f7486ab4f58cad5d69adb17ab8cd0ce1caf5025af4ae24b1fb87"
+ "94c6070cc09a51e2f9911311e3877d0044c71c57a993395008806b723ac38373"
+ "d395481818528c1e7053739282053529510e935cd0fa77b8fa53cc2d474bd4fb"
+ "3cc5c672d6ffdc90a00f9848712c4bcfe46c60573659b11e6457e861f0f604b6"
+ "138d144f8ce4e2da73",
+ "0e6ff63a856b9cbd5dbe423183122047dd39d6f76d1b2310e546fe9ee73b33ef"
+ "a7c78f9474455c9e5b88cb383aafc3698668e7b7a59a9cbb5b0897b6c5afb7f8"
+ "bac4b924e98d760a15fc43d2814ab2d5187f79bed9915a93397ebc22a7677506"
+ "a02e076d3ffdc0441dbd4db00453dc28d830e0573f77b817b505c38b4a4bb5d0"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.7",
+ "efb5da1b4d1e6d9a5dff92d0184da7e31f877d1281ddda625664869e8379e67a"
+ "d3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8b34"
+ "66f5ab15d69553952939ec23e61d58497fac76aa1c0bb5a3cb4a54383587c7bb"
+ "78d13eefda205443e6ce4365802df55c64713497984e7ca96722b3edf84d56",
+ "8385d58533a995f72df262b70f40b391ddf515f464b9d2cc2d66398fc05689d8"
+ "11632946d62eabdca7a31fcf6cd6c981d28bbc29083e4a6d5b2b378ca4e540f0"
+ "60b96d53ad2693f82178b94e2e2f86b9accfa02025107e062ab7080175684501"
+ "028f676461d81c008fe4750671649970878fc175cf98e96b2ecbf6874d77dacb"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.8",
+ "53bb58ce42f1984940552657233b14969af365c0a561a4132af18af39432280e"
+ "3e437082434b19231837184f02cf2b2e726bebf74d7ae3256d8b72f3eafdb134"
+ "d33de06f2991d299d59f5468d43b9958d6a968f5969edbbc6e7185cbc716c7c9"
+ "45dafa9cc71ddfaaa01094a452ddf5e2407320400bf05ea9729cafbf0600e788"
+ "07ef9462e3fde32ed7d981a56f4751ef64fb4549910ecc911d728053b3994300"
+ "4740e6f5821fe8d75c0617bf2c6b24bbfc34013fc95f0dedf5ba297f504fb833"
+ "da2a436d1d8ff1cc5193e2a64389fced918e7feb6716330f66801db9497549cf"
+ "1d3bd97cf1bc6255",
+ "8e1f3d26ec7c6bbb8c54c5d25f3120587803af6d3c2b99a37ced6a3657d4ae54"
+ "266f63fffde660c866d65d0ab0589e1d12d9ce6054b05c8668ae127171ccaae7"
+ "f1cd409677f52157b6123ab227f27a00966d1439b42a32169d1070394026fc8b"
+ "c93545b1ac252d0f7da751c02e33a47831fbd71514c2bbbd3adb6740c0fd68ad"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.9",
+ "27cadc698450945f204ec3cf8c6cbd8ceb4cc0cbe312274fa96b04deac855160"
+ "c0e04e4ac5d38210c27c",
+ "7b63f9223356f35f6117f68c8f8220034fc2384ab5dc6904141f139314d6ee89"
+ "f54ec6ffd18c413a23c5931c7fbb13c555ccfd590e0eaa853c8c94d2520cd425"
+ "0d9a05a193b65dc749b82478af0156ee1de55ddad33ec1f0099cad6c891a3617"
+ "c7393d05fbfbbb00528a001df0b204ebdf1a341090dea89f870a877458427f7b"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.10",
+ "716407e901b9ef92d761b013fd13eb7ad72aed",
+ "2a22dbe3774d5b297201b55a0f17f42dce63b7845cb325cfe951d0badb5c5a14"
+ "472143d896c86cc339f83671164215abc97862f2151654e75a3b357c37311b3d"
+ "7268cab540202e23bee52736f2cd86cce0c7dbde95e1c600a47395dc5eb0a472"
+ "153fbc4fb21b643e0c04ae14dd37e97e617a7567c89652219781001ba6f83298"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.11",
+ "46c24e4103001629c712dd4ce8d747ee595d6c744ccc4f71347d9b8abf49d1b8"
+ "fb2ef91b95dc899d4c0e3d2997e638f4cf3f68e0498de5aabd13f0dfe02ff26b"
+ "a4379104e78ffa95ffbd15067ef8cbd7eb7860fecc71abe13d5c720a66851f2d"
+ "efd4e795054d7bec024bb422a46a7368b56d95b47aebafbeadd612812593a70d"
+ "b9f96d451ee15edb299308d777f4bb68ed3377c32156b41b7a9c92a14c8b8114"
+ "4399c56a5a432f4f770aa97da8415d0bda2e813206031e70620031c881d616bf"
+ "fd5f03bf147c1e73766c26246208",
+ "12235b0b406126d9d260d447e923a11051fb243079f446fd73a70181d53634d7"
+ "a0968e4ee27777eda63f6e4a3a91ad5985998a4848da59ce697b24bb332fa2ad"
+ "9ce462ca4affdc21dab908e8ce15af6eb9105b1abcf39142aa17b34c4c092386"
+ "a7abbfe028afdbebc14f2ce26fbee5edeca11502d39a6b7403154843d98a62a7"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.12",
+ "bc99a932aa16d622bfff79c50b4c42358673261129e28d6a918ff1b0f1c4f46a"
+ "d8afa98b0ca0f56f967975b0a29be882e93b6cd3fc33e1faef72e52b2ae0a3f1"
+ "2024506e25690e902e782982145556532284cf505789738f4da31fa1333d3af8"
+ "62b2ba6b6ce7ab4cce6aba",
+ "872ec5ad4f1846256f17e9936ac50e43e9963ea8c1e76f15879b7874d77d122a"
+ "609dc8c561145b94bf4ffdffdeb17e6e76ffc6c10c0747f5e37a9f434f5609e7"
+ "9da5250215a457afdf12c6507cc1551f54a28010595826a2c9b97fa0aa851cc6"
+ "8b705d7a06d720ba027e4a1c0b019500fb63b78071684dcfa9772700b982dc66"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.13",
+ "731e172ac063992c5b11ba170dfb23bb000d47ba195329cf278061037381514c"
+ "146064c5285db130dd5bae98b772225950eab05d3ea996f6fffb9a8c8622913f"
+ "279914c89ada4f3dd77666a868bfcbff2b95b7daf453d4e2c9d75beee7f8e709"
+ "05e4066a4f73aecc67f956aa5a3292b8488c917d317cfdc86253e690381e15ab",
+ "76204eacc1d63ec1d6ad5bd0692e1a2f686df6e64ca945c77a824de212efa6d9"
+ "782d81b4591403ff4020620298c07ebd3a8a61c5bf4dad62cbfc4ae6a03937be"
+ "4b49a216d570fc6e81872937876e27bd19cf601effc30ddca573c9d56cd4569b"
+ "db4851c450c42cb21e738cdd61027b8be5e9b410fc46aa3f29e4be9e64451346"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.14",
+ "0211382683a74d8d2a2cb6a06550563be1c26ca62821e4ff163b720464fc3a28"
+ "d91bedddc62749a5538eaf41fbe0c82a77e06ad99383c9e985ffb8a93fd4d7c5"
+ "8db51ad91ba461d69a8fd7ddabe2496757a0c49122c1a79a85cc0553e8214d03"
+ "6dfe0185efa0d05860c612fa0882c82d246e5830a67355dff18a2c36b732f988"
+ "cfedc562264c6254b40fcabb97b760947568dcd6a17cda6ee8855bddbab93702"
+ "471aa0cfb1bed2e13118eba1175b73c96253c108d0b2aba05ab8e17e84392e20"
+ "085f47404d8365527dc3fb8f2bb48a50038e71361ccf973407",
+ "525500918331f1042eae0c5c2054aa7f92deb26991b5796634f229daf9b49eb2"
+ "054d87319f3cfa9b466bd075ef6699aea4bd4a195a1c52968b5e2b75e092d846"
+ "ea1b5cc27905a8e1d5e5de0edfdb21391ebb951864ebd9f0b0ec35b654287136"
+ "0a317b7ef13ae06af684e38e21b1e19bc7298e5d6fe0013a164bfa25d3e7313d"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.15",
+ "fc6b700d22583388ab2f8dafcaf1a05620698020da4bae44dafbd0877b501250"
+ "6dc3181d5c66bf023f348b41fd9f94795ab96452a4219f2d39d72af359cf1956"
+ "51c7",
+ "4452a6cc2626b01e95ab306df0d0cc7484fbab3c22e9703283567f66eadc248d"
+ "bda58fce7dd0c70cce3f150fca4b369dff3b6237e2b16281ab55b53fb13089c8"
+ "5cd265056b3d62a88bfc2135b16791f7fbcab9fd2dc33becb617be419d2c0461"
+ "42a4d47b338314552edd4b6fe9ce1104ecec4a9958d7331e930fc09bf08a6e64"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.16",
+ "13ba086d709cfa5fedaa557a89181a6140f2300ed6d7c3febb6cf68abebcbc67"
+ "8f2bca3dc2330295eec45bb1c4075f3ada987eae88b39c51606cb80429e649d9"
+ "8acc8441b1f8897db86c5a4ce0abf28b1b81dca3667697b850696b74a5ebd85d"
+ "ec56c90f8abe513efa857853720be319607921bca947522cd8fac8cace5b827c"
+ "3e5a129e7ee57f6b84932f14141ac4274e8cbb46e6912b0d3e2177d499d1840c"
+ "d47d4d7ae0b4cdc4d3",
+ "1f3b5a87db72a2c97bb3eff2a65a301268eacd89f42abc1098c1f2de77b0832a"
+ "65d7815feb35070063f221bb3453bd434386c9a3fde18e3ca1687fb649e86c51"
+ "d658619dde5debb86fe15491ff77ab748373f1be508880d66ea81e870e91cdf1"
+ "704875c17f0b10103188bc64eef5a3551b414c733670215b1a22702562581ab1"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.17",
+ "eb1e5935",
+ "370cb9839ae6074f84b2acd6e6f6b7921b4b523463757f6446716140c4e6c0e7"
+ "5bec6ad0197ebfa86bf46d094f5f6cd36dca3a5cc73c8bbb70e2c7c9ab5d964e"
+ "c8e3dfde481b4a1beffd01b4ad15b31ae7aebb9b70344a9411083165fdf9c375"
+ "4bbb8b94dd34bd4813dfada1f6937de4267d5597ca09a31e83d7f1a79dd19b5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.18",
+ "6346b153e889c8228209630071c8a57783f368760b8eb908cfc2b276",
+ "2479c975c5b1ae4c4e940f473a9045b8bf5b0bfca78ec29a38dfbedc8a749b7a"
+ "2692f7c52d5bc7c831c7232372a00fed3b6b49e760ec99e074ff2eead5134e83"
+ "05725dfa39212b84bd4b8d80bc8bc17a512823a3beb18fc08e45ed19c26c8177"
+ "07d67fb05832ef1f12a33e90cd93b8a780319e2963ca25a2af7b09ad8f595c21"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.19",
+ "64702db9f825a0f3abc361974659f5e9d30c3aa4f56feac69050c72905e77fe0"
+ "c22f88a378c21fcf45fe8a5c717302093929",
+ "152f3451c858d69594e6567dfb31291c1ee7860b9d15ebd5a5edd276ac3e6f7a"
+ "8d1480e42b3381d2be023acf7ebbdb28de3d2163ae44259c6df98c335d045b61"
+ "dac9dba9dbbb4e6ab4a083cd76b580cbe472206a1a9fd60680ceea1a570a29b0"
+ "881c775eaef5525d6d2f344c28837d0aca422bbb0f1aba8f6861ae18bd73fe44"
+ },{
+ "PKCS#1 v1.5 Signature Example 1.20",
+ "941921de4a1c9c1618d6f3ca3c179f6e29bae6ddf9a6a564f929e3ce82cf3265"
+ "d7837d5e692be8dcc9e86c",
+ "7076c287fc6fff2b20537435e5a3107ce4da10716186d01539413e609d27d1da"
+ "6fd952c61f4bab91c045fa4f8683ecc4f8dde74227f773cff3d96db84718c494"
+ "4b06affeba94b725f1b07d3928b2490a85c2f1abf492a9177a7cd2ea0c966875"
+ "6f825bbec900fa8ac3824e114387ef573780ca334882387b94e5aad7a27a28dc"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "ac13d9fdae7b7335b69cd98567e9647d99bf373a9e05ce3435d66465f328b7f7"
+ "334b792aee7efa044ebc4c7a30b21a5d7a89cdb3a30dfcd9fee9995e09415edc"
+ "0bf9e5b4c3f74ff53fb4d29441bf1b7ed6cbdd4a47f9252269e1646f6c1aee05"
+ "14e93f6cb9df71d06c060a2104b47b7260ac37c106861dc78ca5a25faa9cb2e3",
+ "010001",
+ "0484ccefad7a4e6f35a96ec8e30eacf5e368b31195febf087df57053810c2bb0"
+ "9127453a4c63073bbfb99024914ccc067266560186a1a267331b7d4c8bdfac96"
+ "fda9f3f70bec4eeabce7cd5219343c2e491cce827e44ee230e4f69589e575ae9"
+ "063030442a31c82cde30dc9c79cf64e7a0975e75e16ea45815488b455256eeb1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 2.1",
+ "e1c0f98d53f8f8b1419057d5b9b10b07feeaec32c0463a4d68382f531ba1d6cf"
+ "e4ed38a2694a34b9c805adf072ffbcebe21d8d4b5c0e8c33452dd8f9c9bf45d1"
+ "e633751133588229d293c6496b7c983c2c72bd21d339272d7828b0d09d010bba"
+ "d318d998f7047967338acefd01e874ace5f86d2a60f3b3cae13fc5c66508cfb7"
+ "2378fdd6c8de249765103ce8fe7cd33ad0ef1686feb25e6a35fb64e096a4",
+ "64ac093971f8f096a4c1d4a543662a2e5a1281c950987de898707f029c159bd8"
+ "32cac55d9136e0e9b4a80bf6f21b68cf9770a6349ae51e7f09dbda9d59c45837"
+ "37472d4d6532c7177ee98108d2cf42cd085abb4922eb29d96f3d0f6b1d0d43c7"
+ "39ccf1ba651675e1968b507d51902f38cdec0b6132729045325fc1fb8fd558e8"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.2",
+ "c111464e002e4ec618a8e263dbcca91fb18a00a18b440c4b5597bee7db2aeda8"
+ "31e621fcac8dd81cee3503242b33b0daa987fe2f5493ad2d06a15007590040ce"
+ "3c2277642fd27f3f255e3d98d89dfaeb86be34e0b8fbb935fb928560fa292d26"
+ "34625a507dd580a89124b921293e8dfeddc281d79eb3a569d59e0db8013e53f7"
+ "d4c2f96e5f2ec27fd8ddb01825d17fca406daa6224c7606d2c915282096a7805"
+ "5a49621537b4f025a6e5b2129bc8c1a407",
+ "6e7eaad804945eb04670dd8676b7057d03ac3e226465b1fb8403e6ae7983e0a4"
+ "6a89a4eb32bdc8e7ae5a53d48aa64bc9c3dbc8cf9cd6dc6a68fceae9e29f4745"
+ "fa49e18d184dc5d26c4feb351fb4b228c4c18cabdbde8601724ae3803db305f2"
+ "a076fa8a57f4610b8a6e0ed43575be5d5bfc1630479df3bcbc515177afe4994a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.3",
+ "29b85b14b2da947a4c3ad1e5937da192c6050865af9504a5445370e43d3a8da5"
+ "d355fd58766b2543ac6f93108783c13ff28b2be56083f0298239e0ee9681ee47"
+ "c6",
+ "80b38ce735126c8545d91d18ec9037654d46e4f3c51a6b8618e15f72cd207500"
+ "a470017577d0a8c55a2ba334383f1f8d99fce2460b3297bc037ef64ac4a3098c"
+ "6aaa24a4d0144af102d0dda17e07dc695923932e568ada00dc4f7dbfbcdec43c"
+ "c908388017d2eef04e60dfe4d57340fab916e2b811244cb1e4a552386fe3ed4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.4",
+ "d3b7aad37a4890e0365b86c7da9491e73cdf555d1b02b451816dc52f9630d590"
+ "de83a5c93961012522dff6dbbb9cdb0e71ae51401964af1890e89325dbd626f2"
+ "da013458e39eeca583e89e4c08e5d412be498495886e0551cfe742b8b5",
+ "9d8a8889a311b486cbe2225703f5d4ae2a54c2bcaaad06fe7648b9e2d85edda1"
+ "a07d856d6ae9bd5cc1e5153266ec7f1e1df3d929cc44700fac926458414c2841"
+ "da83328e81e0b9d6c3885e767370ad5cf1f576d9dce348caec5e6443e0aeb7c3"
+ "f72b7dd253667023b9a477ab34df8f2067e225adcb73ee11e159eb649147d602"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.5",
+ "f658188c8f9de60b5e99a29f52d3b889201b30d464c3b72792a302095dc1e77d"
+ "45e94f5dab73dbb313543857ff91dbf473dfc145d73bd5062075d192a3fbf4a1"
+ "33e7e568df20b8cff77b3af687aa22559ec1",
+ "0a95a44f6274e74cec451796af5688d4be010893faae27d490f4771b003f7046"
+ "cccd419fc819d7331955f41eac9339f546c584a8b42a5ac63290583ff3eb6b29"
+ "cadc754ae58d5a5637b6609796e8055173ff20a9cce492fd7837468615e84108"
+ "87f0b4a59ff252a8259776c8ffdaa67c87dff8983ae679d1de22ea158d48f68b"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.6",
+ "31ae5f83a0fb3ac9255ffa435f70e2ab655566e5fb8b78b802c187cff1c5e40f"
+ "ed06978c5d5976eb4ca775806399a6fc4db50c1f88661ba68abc21fb2ccd537f"
+ "5018f36ed1f7d45383fd469e77bab3e8a95dfa1b941e430ddec552dcd82f5d10"
+ "d29cd10a22d17ce2425928ff5d0710dce7d9f83b12e04c1a0159c27176e04acc",
+ "3f11ea739f329c9d40046034b6c0cfceb49bc3201a5f25eaf5015aeded02189c"
+ "e0b0cfde19125bd288b7d0c062321a5bdc2cfa4226f5104a1fbaebbe7f72f5f7"
+ "927e1eae26fdc5ba92f2d3f869ebc32d9018dd04ede86de5c454f1f7a1b2e2d1"
+ "940aacae27796355fe18ac80975353929ac6a838458b5d9dc7576e3887ee7bca"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.7",
+ "96ff99f15060c973a65b69a8b5b63adb3325320da937297584ad4fad5c3c7469"
+ "019e9cf72acb315f1e491927bba1948755823eb07e3f20acdf78653cae450e47"
+ "bc54baf8ca1167a5050844e022220ee6658a8ddd95632e9adc1a6c14379c1c5a"
+ "e5a0ce5dc4020809622afdecf81f18a51e28666d02b1dcda0a27b8c3d2c27b2c"
+ "07b3802200017a7c124a4337cc4b6ea2aea75c68b440e37947e3619bcfee055b"
+ "b2edabc4244907e0483dd3a17d8edff3a650293fd4abf5c45d1a5b6c5402ba2b"
+ "81b7b0e0c95ee949b2a238c19956206c124e0cd9c24620b36a83bf93b96ef204"
+ "bde5316c1f5327c0a621ecce2093c0652ddf321768d74502f1908529629bab68",
+ "183f853d0d03621870e3ba586850c5ea59fc4e9acf3794b9ad59a1bb80181e77"
+ "b111d6648647e139a39ec04f86187491e77b4d75c060795bf7270846d396e0bf"
+ "ea8315795e79d76a919ea76b06eec13baf4ce8afe1e34bc22457d7b7992e0842"
+ "efade179b0aedaccfbe2d23d3eb314e1de91c871b9db5abffb17477fba233a06"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.8",
+ "3a176c793a546e2d276fb8ffc328163b494997a5302aae2e5045a2a20687ea6d"
+ "1f181c6abfe6090c8dc40256db3de08322647fb795bba1713fb57e33d53e0e13"
+ "bedac6a658ad4ab491223881198df29367faade8be9fcaa4e483f7b7f3dc7cbb"
+ "f97a17aad88c26cfc6410f945b54fc53db55ac803d8b73691b1484847d7f3b7e"
+ "9394e55f0a51fe61ae84523c94b22e82396db6cfacb72e0ee494aa0f1fa59312"
+ "5443ae1555a6a933face0074791dc2c29242eb",
+ "413c9223a2e9b122cd872577e52f313d41dac79a26cb1033da0b6fcc4b482107"
+ "744bf490fa798dccd0cbd118ef39c0f559d87b89335db09be7700fb09fdbd340"
+ "40a00be5ca42883477b06e4e10a7cb11768fcb02c34fb106e522860d10693906"
+ "260f43d90612990393a8ffac9fd70ca37829111eeba6f3dee54ef1c16268b33e"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.9",
+ "068a991b32b676c64b898c67e1137282b43711b0d0671c247d9f7c48f5043e4f"
+ "c206dc65af8906f252f0245205ea084323d4276be5aa0fc5af9c3f34b2fd6634"
+ "df572fc313d273b53e9e36b946e7e672f98d857d7eddd3dd04393132f461f22c"
+ "990026166f385be1595c7f23f89ff57e05a7be285d105615485f356abab1ff2a"
+ "b927d609952a627e468ca7590acb5213f43139f8e2c9d4d17c6bd7914e53f02f"
+ "d19a131ff49cd25ede8f418a88530a8239887f0fc797edb504647964bf31caaf"
+ "080d5817a0",
+ "575da9e9befca1829546e8293815001132030e749ca51088f168bd150b1394c7"
+ "acd5978bca03f7b9d92a29b8e2856b0da07f0bb15c0b33e05487991ad97a812d"
+ "c904aaf0fd1e387ef1c270c6868d3ee1c611577bc4d07ff456b2439832908a3d"
+ "cc4fc0990472fda3cc6111930b99795d60c0e37888e87ce00bbf3c1cf307f9e1"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.10",
+ "d6839ee6d07450327e09a03e1ec280e1c8d11500dc390a49a9c9828749c3e9a4"
+ "bee2ba576f6d1217a8e7854a907eeb93dfff92308ad0d94e2b381f92b0e84a47"
+ "1bf1f37a68e965f65859d1fdfd6fea844079c40370dceae2",
+ "a7c5f6d0de9cf8f41737f23ae3e8cf609aebcf22d5de1213d9573cb94403f89c"
+ "0f7088fffc61106fa609c7371a8d7e1bcd221bc1ad94912fabf2ffc02f848456"
+ "4c225c069bfc6da9f3f9f4974e08e1fe56f748ff790597906a954e383743a37e"
+ "575fef074f060f3dd15b5ee0f94dba69d86c99223fa9c3a61a8cb2af2fab1e04"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.11",
+ "33849c67df9a6ffac3da90a8cd31731a0297b9d6010a03320f8845035fc34309"
+ "ad",
+ "1b87051f1591c8ae7ee3cb24267039a728405dbf231caf21f3247f05858b2a51"
+ "650b81bc5377865e4c1e8fd0364152a16bc58f7d2ac01ca679cc49dd048903d5"
+ "5ad05f102c74b3601f25ad30624025c30b6f0f7911fc22458e5d435f388e3fbc"
+ "495fa0c610c1298f821da538403a93364d2eabf1e3b32f8110a7e03e372ecbc5"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.12",
+ "b3dabaca2059a70e25cbddf4aa5925995754ace43c5d603640489af48fea6edc"
+ "4e19cbeea2c0db62ae0a104c72e4cd56cb532f4fe577b36a8198b4879d7ff804"
+ "2690f662773f3d6393f25898d2",
+ "26f13770263fc5bdbeadf88fb4dd307a38959b16f3df946ade864b1e7e914d36"
+ "4ebf9adfd86a70022dc61b43fb1fdf8696978e2d1f6a2defee75adaa69a39532"
+ "074050be708eaf031d5fae0ffe245ba4ff3c5e340af5dfec6a4cce0e18876cfc"
+ "1366eeeddfce0f835b38e81881b1fc5832930fc79b08f1fb34fb224233f4c468"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.13",
+ "099112fae740888ceaac7054d597351d79e159a958d8121578e52c837db3543c"
+ "fa6f8e7f1dbd2a61978645a4d385b9bb1c60bfb11bb3c8752ae31f996dbb5262"
+ "8f93d52694f182e69035a5e557ec718262f403df5211f73c6de0d55a0ba7",
+ "8d8c8f3a86f49edbd125c83ebf6d52e765161501482154598c283abe94027787"
+ "2b00d0777c2e697b7883cc321e151c80116f9fcd177ac4c7deddf03ca1b2c593"
+ "31dc1c8e947f1eb2aaee8cc941ddc5f374a63d6c9938ecd8e88cbcec58929cff"
+ "ddef0ba2175885a80dc4cd92d6b79d9c6a81696e16f9a83a10ca8efaf1975f55"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.14",
+ "aa17e6bbd6db19e54bee1a7f0edccaceab635d7628fcaa18ecfafc401cb3feb5"
+ "1f9a3731f3802cbea81c733028c9584b6b78e2055954cf9104daa677aa40be9b"
+ "7c65b07ac4a8bf25c1149e054735cf3ce332d429bc73802445dfb3688bb81948"
+ "b57e276af32462f7ad804d50c93bc7e9ef7537695a271af72e4bd47ce5fa9d62"
+ "f2dac0333623f49eb9d6d78034ed1df6e12bfd04261bbe5ce040e03ebe258d2d"
+ "052a12ad4e3bf253042301c76458ed910c5ffa705c747ad8ca0c1c6228da2c97"
+ "e138",
+ "644ea076214dbddd30055d7c561892279b46bab1e12253424c28f449e172646a"
+ "f3498c7afcbff768e046a7c2e3d9c0e7128f877b92195aa2bb9f1cfbdfd15bb6"
+ "5fbd23efb294fbb11a3c66056d6063853bb23c274665a13ef4f3c12f5921a419"
+ "e949b30c0bc0d77d6b28691d2364d95bf68be8d5978ef1bc9852a4f06604474a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.15",
+ "28249c387a061440e98638e1ed78a4865130e57533d789108c63e15fd8019bad"
+ "2cd1a7552bd8afd206d978eb1f2cf3f23afc4b34e6dd7f69c1fdf4fec25268d1"
+ "865551944922906dce6dc441f94a466bf8391ad82bf5940e447110f1d15de129"
+ "3129fb4424a1717519d6d428d66b7a109142acc915f1eac96def2c3290b01d05"
+ "990bf8023a6a64712f63137a8e",
+ "5702060669ed47bbca11b91668289ea3f5e746ad2e386dd1bc2a8bab1746ba2a"
+ "64bf15b3fc2ec8b0cc99d854fa3211c955c455d7ff2e1ee239f54f386a42bb25"
+ "40a8758f3297e552de1ebe8eac70f35487942bbadad5bd957390ff1793af3d30"
+ "d936b6f79b44a9b63cee62d5584da3a1fcffa5b6feeec11cd63b180f0bfc5b6b"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.16",
+ "e491a156fdba316a2a20a12eea50be774ec9aabeb1c398e908bea32968217ea4"
+ "1e966db7272f0efa37c90ae4e9f38621a627a9d12c8b4e8060c545c56059e9e4"
+ "8a7f1681367247335819ba127e65931e1d9fb70dfddf4c9956a5b04c52bcf8cb"
+ "dfcdf2291964dafaca7ee70e80a2759cec735d01aca8ff894b689b93783da893"
+ "9c6209dd683c60",
+ "9f205ba90df2d4014926481f9b3f45a89d23ecd84f5f16e67334c4caf3f3b9c2"
+ "01a798d4eec56276598823180e078d0aef4f8fba0b25c1fda3e33654c474a9c1"
+ "1a23b08710913dff7656f0e7ee22cc44c999c095a6514a9d2fc0ca4ef208de0d"
+ "9293b0c5608baed1074a0cfd57b99ef8ceabfd3472b7db3ab9606d13f9bb439a"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.17",
+ "06add75ab689de067744e69a2ebd4b90fa9383003cd05ff536cbf294cd215f09"
+ "23b7fc9004f0aa185271a1d0061fd0e9777ad1ec0c71591f578bf7b8e5a1",
+ "4514210e541d5bad7dd60ae549b943acc44f21390df5b61318455a17610df5b7"
+ "4d84aed232f17e59d91dd2659922f812dbd49681690384b954e9adfb9b1a968c"
+ "0cbff763eceed62750c59164b5e080a8fef3d55bfe2acfad2752a6a8459fa1fa"
+ "b49ad378c6964b23ee97fd1034610c5cc14c61e0ebfb1711f8ade96fe6557b38"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.18",
+ "311c88800535d1b4e9bc78651831a3e967e74b5828e014115fbe5f609ce865fe"
+ "d241970f872ec8f23dc2bf616b8020e44564f934dcbf72386170074d920ba895"
+ "d33ddf279369f236a19acd4feb2b",
+ "894663e63ec19f56203f4a446b5e2b5174c814a54cbea2c8e298f99b34c4bbc2"
+ "c8b177ba9857d81c854436bd99af58c09dde5acad2d6415043fb40e78475ef74"
+ "012e4d4f75b2e95885c851a23b4a255493f30c172eae01d47910fabd269f5794"
+ "0ba443506c0522bf728a257ac1073bdf99b42956db002a30a54dbdaf284d8f69"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.19",
+ "b265a9777faaf158a808aae7085a83e7079cef80d5fc9d7cdc963ec9",
+ "281e88ce190e9862903436a86ba4372716449cc0ce8d554f702d7252a06760af"
+ "42121dd09bf6ea13f0eb252ecc76421061f5744bd8e32c5a8c4fc1f9521b3f5c"
+ "29146dd0591291acbdc5b63b551d228ae53895b197e6e27a7068aa3103b70cfb"
+ "30f415845c7e5287f1114e4cdfb401ed519864cf61bc469c66699b2960a0aff2"
+ },{
+ "PKCS#1 v1.5 Signature Example 2.20",
+ "7c439e7ab990cdef956c4239479b49da842f8b76765a7ad4897bc16c61ed3d09"
+ "805d76e8a5be8b578b951f4545df92a8a537ba3e2c13dce0a003e7b6249e32be"
+ "941f21cda725b80407be1e28bb9e393738325356ec21741d5c86f3c2b4f7b947"
+ "afd56b2d3aec",
+ "6afad77a056d07290586e913809a0437d39ab307324512b2f5bc2baf580bf455"
+ "43eb04ff83e963a6d7f33e9dffc1fcf42448c5fcfa472719c651f81f3c622298"
+ "3d38917e29b48485879cebb0a61d389e238c9c71c368ede4083a946297f7190b"
+ "4cef867e9ccda8f9ffc61984fcf05d4fbafe107dacf5b1dc8e2b1495b244f8e7"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "b5d707b792e056f72fd76d8da889a53ce4d8ebaa082aeeb23032e3c5d8ebc4c1"
+ "5561319be8dfe188991a8951d4b23a51e8a9382c805e4cfd490ebbceaa20802a"
+ "d683b05a100f29985f011c3c8a44262552d83d9a1b7c27315e144ad8df5cbe8b"
+ "c6400fd9cbe76b7421d708aa64f040bae07b7bd6f92218f9a729284cc598cdd1",
+ "010001",
+ "451792b59447cc9378a8a4d645fb22ff4bbf067061511ac836db2743a624136b"
+ "186b6943a1cceb6f91290d933bbb8ac053a4749528236ca272cf77d9d337ad2a"
+ "b36a87a9153c5e16716e09ba0beaa64b312526d4a8c2dc68fe09e37e5074a090"
+ "9d3f04ab73908a980dec1da7eb4505a48bcad3b60d0160845864a6511ff559a7",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 3.1",
+ "986e7c43dbb671bd41b9a7f4b6afc80e805f2423488fb431f5ee792b6c2ac7db"
+ "53cc428655aeb32d03f4e889c5c25de683c461b53acf89f9f8d3aabdf6b9f0c2"
+ "a1de12e15b49edb3919a652fe9491c25a7fc",
+ "6275e87397e3092aab3698bb1b5cf24b8cd7712becac35e32203d54314e5470e"
+ "a9aabc8657f56434e5af9fae778ff6045c20e2e1ef7cbdf88f0075f33ea99277"
+ "7cb7e92f7da18a0ffd00aa4671ed63911fe9e92fb4a76e77dc6e0a916576716c"
+ "15eaef089a71a0aea35bed9447a6c17f2aadb727fd42f0acc82462381d9fa2ef"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.2",
+ "4c7b98120c87509087c478",
+ "59e5cbe7331b92e0cb8f689eaebb30f2b334a746a657055912ff1c92760b0b85"
+ "bc4282f3184b9a814f4437f825ae07d356bac69e540c90942c7f7e6ff44fe574"
+ "f121250ad230f4b50c78311e4fd3c9e265f517ce3297c3e1dddb5c869c698f44"
+ "af525e736401a81b459f198ad1808ccd929d490474caf7005f910dacde21b077"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.3",
+ "66f7075422c8ec4216a9c4ff49427d483cae10c8534a41b2fd15fee06960ec6f"
+ "b3f7a7e94a2f8a2e3e43dc4a40576c3097ac953b1de86f0b4ed36d644f23ae14"
+ "425529622464ca0cbf0b1741347238157fab59e4de5524096d62baec63ac6450"
+ "327efec6292f98019fc67a2a6638563e9b6e2d15efd237bb098a443aeeb2bf6c"
+ "3f8c81b8c01b7fcb3febb0de3fc25b65f5af96b1d5cc3b27d0c6053087b39680"
+ "e492a4ab2367471169e52838945dba9dd7723f4e624a05f7375b927a87abe6a8"
+ "93a1658fd49f47f6c7b0fa596c65fa68a23f0ab432962d18d4343bd6fd67d00b"
+ "25b81b09b562038564",
+ "599e69c154e4fe66b36a690492faebb2bbe734e0415d9f3cf7e37828f53e6113"
+ "0449173a33460c6b4c8dc7d681ca6f4daf1cb816d40aa9082ee1937be4bc6a09"
+ "c6de798c8286fcd2a2b2196c59994c937f37130752612c6bff6dbb53e0647f88"
+ "58bc383864021e6d56681920249297822246a0f528aab3ed185eebce919cf83e"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.4",
+ "d9344428fa8a58f8fa7b443e51fc9b51e37a70210db8bd1de7f8675d8479ff65"
+ "7ca72955b23c6f4a0916379a4edee1f26c85e05290211eeb25832b09cbe5eaed"
+ "3e3965b05a52fb5b16491182c5913cb1825748e81ad014f13d296dc16957082b"
+ "1b83b4be50a0f959c9e7f3aa8077972e2b93c2effd9f308625b8ca7f54d7b696"
+ "48790447ac91f7985e510df70d6ebc3572c205e6",
+ "2c060165fcc5655c0657c8fe08e05bdc8cd77c1fecb6d18b893811c99dd091e0"
+ "d8506dccb49e33daaff6da967b99e344cb17fa3c9631299b3589818b37ed9d5d"
+ "7894e4a69ddb24832e1a8860014ee5e5eb953e8b35484ba4fec9c3033ae2e118"
+ "9af794a72e4267215bfe458f0fce6b37a5549ef80543d0d41a87b2c6e4d84cb5"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.5",
+ "8c6702daaf58f6a475fad2c7a4bb156a5706425577d5e30c6a6bd3669fd030af"
+ "d789faa3d01018d45db2a047f52cb4f63dea360942afe476264206d983ad3836"
+ "e155c56b2ecc08763afb9fd51d19990efc3363f657e285e03521e8cad01d2c93"
+ "5a183ae23f0ee8710086a85b9fad4e7f2b09452ebc403ce0c0e5755a7b2f33f4"
+ "def0db71c97931ff904a81319984bdc5166f6b920c97ee74fb7e890f490c90de"
+ "30cac976b71723e2f86e9de1d503a41bc81d53ccbef8ac405357d9dfdf306466"
+ "b4269580212e9d7132",
+ "0d89fcf844a9dc223d5f638dcc3a5978716f2628b8a83ab33e6e255ff8aa0157"
+ "8c14e3897da45aefd63fa87cf35e244bf4828ecd21950f3085a36621c9da1bbe"
+ "7ea62731c68d4de0a376e22dac2f548cd4ba4a542e710f55ce85a9c19593c08c"
+ "87d296d63587b3fe2c5d1165ee27744c75d8f4f14371637c0c0a446276289583"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.6",
+ "56f4ffd1279dcfe562a9ddd41ecdf60a3ff58246bfaf9565cf674b0b9075f40e"
+ "eac08f0b8966618a196b1228ebce93fc9dd79bd463ea7d2c974d2c2f539eafb1"
+ "b2bc1ea34d74f720e119342ff7131225aa9ada894b76b2ecb12f2f402844b442"
+ "5cf8f1a39b0a9c83b45b03cfc0d15fd314d6abf532b8edfcf236514b2e458697"
+ "86fefe27f54d666ee524e4b9c053be397501582991fa2d802c7d1b178b23e9b6"
+ "ece6fd2ef0132c0601a86f0768badc59c5cc33f24ded554ae51ae3ec23f9dd08"
+ "9e324a6821f6157f128442ac5807658ad34026b8fcfda6dc7f02a93c166ec945"
+ "ee",
+ "0deb397bf2cff979d4719c648b0a3525351f5e08405ca2614a83e56ace86f552"
+ "e41bb928de50f0bc0fe31a2ef2ad799fd3cf4742b1131a37bd08f2a13cacda67"
+ "f495c9f1a9ef64857072329f00cc4c012235599a83fc4594fed923034901edc2"
+ "7d5f05799834935cabe264ffc19663714d8c3de8e9619fd2842d2298f7a72c99"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.7",
+ "0e79ac9c9c0396d969fb3f7cc9947b078bac493b0352c8e0cde5463ea5c1184f"
+ "d52a1fb748193c147a74800d24f751ba935e19c9115edf072288330bf383f495"
+ "296be1aa4a5095b9573bcbdb228a43131237865d26dfbfcfef078f359f9a9562"
+ "e25b696385e12813fffbc8d529819a91451d33a50726392e4fef29418cca2c73"
+ "a068e60eae318470331a0f1db4bbb637173be80fea03c82c15d00193362d3a18"
+ "ad9e2f680500d7265b1557033a520977d810fc",
+ "733b7fea120ca5f0359a8905750c49c363d884f56c2b7a729fad7bff445a1e54"
+ "798941745393e1767712ac4b9dd2683888d9e68b905dbab87921851848727386"
+ "02eaf4a80f4595f78fd4a4610bf8220b86a2885fda24e1996428ccd15f2008e0"
+ "6851b2eeadc3dc8e03012f9bdb3ce0575ddc3adc7c5908498b69a797ba5829c7"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.8",
+ "22eb7dba73307c7c52a07ced89db8bc5394aed2272f7e81a74f4c02d14",
+ "9ea4600a1a6549fd3975f6498a04d69f96fad0e8e6febcfbe01c2f83170bc74e"
+ "b91f2e335338d583e885aac61424c9b266c3d2d98e7977ffe495f9c1a6ee5ef4"
+ "1a4cc7478c24b316c7d9f6dbaa65a4cadef181ca946f9b92184faeca8a1316ae"
+ "ab5cd3878c6df074f9060b9db66dece9a9367d7549035ac6bf1962365e1fd3fc"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.9",
+ "f680",
+ "51639061fa7b7cd5df64b30a394ccf7e2426972aa1dcf5d45eb8ec2cd90b9b19"
+ "6892be5fa03c43f3c3723ae3130d6151b33a637cfc50ba3526a7396cf8479c50"
+ "8c1811810d68b3880af6e64b16bd7079be9c003929512261898fa57c06ff7e1d"
+ "8039fa993fd2056ac7019b8dbcf2530d5380e601a4a1871b86c20bc1c489c5f3"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.10",
+ "650e64ed1da88bcf8ae27522be1d5c9919f2099dd632455f66d9afe8baf46cc8"
+ "a198409b0928dd87226284d669bf01bcec44376cb0e9bdc686acaa8b46348608"
+ "5994cafb5a8cfc33d49ceef479fc6e04f8eef637eb68cb57818d5f9770ac523e"
+ "d5b01638367ff47f",
+ "503e05661d681eca574e0230af2daa877b90516e5e19728c91768d6eefee001b"
+ "35419c5fcb5611d60e7ecbe3c95e5c88ba93460704f1694ae80444eb9718a08b"
+ "6686fad86e525990c3c1a66c8c53aa31aed8cbc40fd54f5ff8a134749d79d38f"
+ "bb0d58442678ff2f70c6c50f25472a72d63205e782423df40b6c43de03a18f8b"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.11",
+ "57f8ac6a9e468b7f1f745dffe39e9cbf9024a0ff36e0228392be6b2994291776"
+ "b89c0a4b1fa86b2ec8bb7c3e64f5585afa77",
+ "90be16b408b385739539b3b9a29b94c729385f79dd4a79811e6f67c80ed359e5"
+ "f4b2a19c222a82b3d6d62a903fb180c1f43cb3fe06a250bcb0e7c688665c8368"
+ "a11ab1160adb740291352b3838b6923a4a37ad06040a535920dc0f10579ecf48"
+ "1cd4413717d7d4d960aa751a743e2f7c616e542ee65fbbfe24660e101daa2bdd"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.12",
+ "80ef01aacc5bfb0db48c6de3d81495b9c2311a389389f23b70c024da4478bfab"
+ "2bfe4e546f13fffdb963894ec6dadb3d2b0ee337f11631058eac8609e5a1554a"
+ "f797a9f9ab478c2d5b9188c825",
+ "44c3f51dcc6fb2b4e70f537f5464c6320ad42e2128fadfd9a7e937cd65dcbf35"
+ "ac66cffafd39283966f2f15de527723550715a31042945e200cc5c86faba5ec8"
+ "abaf509c0ccd64d99dedc76e3ceaa8c447179337f4a0777b11526e472acd413b"
+ "4ac7c303cdcd84cafc025243ef006f79ddaf55c15cc4a8f15ea2c87f05773814"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.13",
+ "ac17959155283b0c7cff515c3315d89bdfe9587cc00120d3ab31bb7607bdb301"
+ "caeaf5e15f5a6f58c9c568ffb3d23402516ffe230c6981a81c178a8a18ca330b"
+ "b8ecafb481b249b466a8cf78b70d9e78a139a88f484cce7c2035b2e89d493bde"
+ "885e1cde42cb1a9449ff570dcf9e33c5cc77b259bee28305396802edc16fc5a8"
+ "e10b56da2da786b5fb6c812b2e175b696b1a9a96fc722a432146450f07a648ef"
+ "3ccf996ef3081fa5bb4221c913ba2228970c9b0ea5266bff",
+ "48458c72f067dd9ab720ef160cf3184bb9801e26d614a889a835844107ac0165"
+ "0b1184a00bcaa7af1ff7de3a2ef2e7ceb5b25c3b5d5bcb29865934324748c68f"
+ "07de174e1780a70fa24d6a3a9f7a41b81937c4984b2cbe06b3d7b44cdae9cbd4"
+ "1632d00943c3b573b1aa2912750a9aeb07f110130ba361dcf8f536790d607847"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.14",
+ "99098f77f6ed35c08fab3fa9788693671a5800dc303c9cce424616fa0c7ee888"
+ "8687674ca88ab22a5ff2d12e2b388b094ffd7dbf9a0927a9621717151e08ecb8"
+ "ade1559f4b48e23d31cf57cd3884dfe2b3e4b260e896029407969496026c74a2"
+ "1890d9a9afd2cbb8f2830a566aed24f016197401a8cd22c82fb8b22891845824"
+ "0a23d10185ebe772dc19bcfe3e44922fe73209c1ee0040079fb03b827c8217d9"
+ "ed7c98c95f30974fbe4fbddcf0f28d6021c0e91da60ca2ad77797ece86de5bf7"
+ "68750ddb5ed6a3116ad99bbd17edf7f782f0db1cd05b0f677468c5ea420dc116"
+ "b10e80d110de2b04",
+ "b46ae866139189b6b171a76205fb9ce041b40298e5ba92c2e9cc0bbfbb4a7642"
+ "5de6ce13021ae1a4a942299f98ff89f552f43a9073de64f49c2ca3620d09d7e6"
+ "e3fe28221e9368987e110cd6067106c4db31a03890236796c84252f56c95034a"
+ "01c5fe981e81b654855aaf2747501155720c2193f3a1d10f49fee90c52fee9e4"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.15",
+ "ff790642305bf302003892e54df9f667509dc53920df583f50a3dd61abb6fab7"
+ "5d",
+ "07563247734f3c3d7a3102bcb45bb5681568ed10f2ec459e469e1a9e3409a139"
+ "fb151b98d3f3b62daaac8b8f8916df85d6dfa9ab760df1e15ac89044e579cf47"
+ "a1af6cd6ec704ced9b034c6aaa90d0e70e0852140e7541f2efbe2cf190b95894"
+ "1ec8b5974f9c444d26c34316c9216b6595e656bc6c7844fac16c515260928e78"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.16",
+ "e99fcbf8592dbe2d7e27453cb44de07100ebb1a2a19811a478adbeab270f94e8"
+ "fe369d90b3ca612f9f22d71d54363a4217aa55113f059b3384e3e57e44522880"
+ "62afc08fcdb7c5f8650b29837300461dd5676c17a20a3c8fb51489",
+ "22746436164e63937871c1d47d8e3e70c9e52d1117316bb154cd552e836f2a3f"
+ "be6d89d6074b51b0159c26c28df75e3d7cfb7cf002f65d1ee521edc2c3a65c52"
+ "6c98c7c025fa8bb631470916d301b8f7809ddd919ded31a0d46683ec5bb44170"
+ "616eabcd970205ed760202d0d87a65795908b28d326f936213f29feb59773491"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.17",
+ "6a6a0c9b5b15bcda196a9d0c76b119d534d85abd123962d583b76ce9d180bce1"
+ "ca4af870fbc6516012ca916c70ba862ac7e8243617306f4f9ab9501199cef55c"
+ "6cf408fe7b36c557c49d420a4763d2463c8ad44b3cfc5be2742c0e7d9b0f6608"
+ "f08c7f47b693ee40d2e180fae1eac439c190b56c2c0e14ddf9a226bae17d2038"
+ "5d501955823c3f666254c1d3dd36ad5168b8f18d286fdcf67a7dad94097085fa"
+ "b7ed86fe2142a28771717997ef1a7a08884efc39356d76077aaf82459a7fad45"
+ "848875f2819b098937fe923bcc9dc442d72d754d812025090c9bc03db3080c13",
+ "419322facace76f2d5e2fbc19aab86c718a28064f1d7b4c662f0474a8777a959"
+ "bd6569538c16081c0f52698b2f001730c03b9a3d26947374c961fdeda115b6b7"
+ "daf66518f1fe820f67c3ff12f0bc3f1101e3911c43906b0a127e50be0140c5ef"
+ "c435e2957b442e60ad525ad70ac9ef61c3d64f0e566cbc1f9d51bae1d47271da"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.18",
+ "3b93ef4a555096691915dc23c00e954cdeb20a47cd55d16c3d8681d46ed7f2ed"
+ "5ea42795be17baed25f0f4d113b3636addd585f16a8b5aec",
+ "ae211f4f77da1be6af9c9ea704dbac4b3f3e270d2facf3651d787d0ebf59a79a"
+ "39612da12d57c4ac8abc728e1da3f01a1520fc9b32cb0ffe008c8069928f83e1"
+ "3590a78b817e819fbf2fd05893ece5b14186d901c768e342dc54722345ae8aa8"
+ "738d4d5970c5085472bd9899fa0042cf14bcedffdbc0ef50819075842fc36bb8"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.19",
+ "49ffd56bf7efc11304a5afbc19d479249018fdf4e09f618726440495de11ddee"
+ "e38872d775fcea74a23896b5343c9c38d46af0dba224d047580cc60a65e9",
+ "68fb0bd519bf6f96e076af29012f3c3a1137c0988de7b6fcedf4f51bdfee645b"
+ "897f17709e05caa0b113500d904dc0600d17a9ff8eb02e1efc9c467a24003ef8"
+ "1e727467c47dd656356d70372a15ea884121634b015d29511f2895557799079d"
+ "03c6d4de259b3b362b80492d81bc9fe8544463ec030bb5c9c73c3274e3ed1222"
+ },{
+ "PKCS#1 v1.5 Signature Example 3.20",
+ "bc255af89a6a199bca4a391eadbc3a24903c0bd667368f6be78e3feabfb4ffd4"
+ "63122763740ffbbefeab9a25564bc5d1c24c93e422f75073e2ad72bf45b10df0"
+ "0b52a147128e73fee33fa3f0577d77f80fbc2df1bed313290c12777f50a334db"
+ "6faebf11081a04f87c2d621cdec7930b9b183a990475dcbb9cc7f345a3b55803"
+ "030cf0361a5d8081",
+ "41f652df79fdd26de95c7a98fa858713fb566d8b39928e71764b2beb198403e0"
+ "3b7e06dc960c505157bdf40592c4d77503fb72a4e0055f974fe939448da368f5"
+ "3bd2efe26e6f9a254b3e8732aad81687b361e21a40cf3e5e92389a2b489c05c5"
+ "97f0e164e267709372004327163562dd8a0adbbdfe3bc616bd08429684c20c69"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "d131e09243370dd2cd5425c8d030f99adb105b147b8a3d0067c616443b7d4b96"
+ "8238e06dbb5f2028e853574b7c14be1083c1e57e132c1df4a3a2713263fade12"
+ "f7114f4369bbf05620554841331ed811005052192572ceb48d662407fd3081cf"
+ "ab8b48c7e92d3c4a26a9645a38e6dee88bb0075975a4dad9646b21603840af5f",
+ "010001",
+ "56b531bbee1837a6946cb86c8fbe7cf6eeadccd2a4921bcebb34a3ae0c6a5696"
+ "3fcb8b5a703b717d032ee813e58e43695cf35547f87264c82dbafae844008b62"
+ "d9122e9de8958560c8dbb007727e7139e0a982e0758814113de54ba0a4551751"
+ "fca0fcb12d8de30d78b8b11298a7f78f0b088f1687053c84a5762f62a4bd05c1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 4.1",
+ "2c936bf6133a9693f146ee5a1a91c2f169b2e644a518e85a75f6e43b560d4a72"
+ "f38c64f84c05240e8b4e55786163e7276265ba213ba93dee1b2e102135a989b6"
+ "248e88327e300361a74f2e9bc41f2a37683f1a1a15f9dd472e118e1c4b3ede58"
+ "dd70f3bacc252e0c654b0f7a6e41a9287510efa03bc92e805e5b2c913f51e25c"
+ "7f858640cafac9d3c917686507fa94f8866f869a4e5a6a3d4f9d97ed8137f414"
+ "d1447a86eef9e1496994ad2da597",
+ "9e93f7acc50fb3a0b1243dc338c8ccb12bcab4aa450440b6306c81b50b8f95a9"
+ "36dd166330c699b28580da1be275616402da85bfd8eefcd6993587e6092865d8"
+ "253b04081d572f262759f556dfb911e8d94e92e55af6d5898018ff33e5f6b1f9"
+ "901996e92faf336e2dcce3ab0a93db932e942cc6478d6cc2fb660811910ccd17"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.2",
+ "94323f7c38b995cc6bd85d479f8de2dec1ef2e84b1feefecf39150b5d9f2cb15"
+ "85ac0d719ab348bdc9750ddb8e3276db89818735bd6231413cbca2de941b55e8"
+ "cfa1ab132cc78aa4f2b51fd6578ee2e032e90e34080f0f8e3db14d1b56f3d077"
+ "f29dbc0216a41344998c0fe1ab412247df21e74ec22f5db0148ecaf473eeeccc"
+ "14ff9e45d58c2e62b5fe6a501ab96fd7c5eddef14aa89266692e",
+ "09402a4356be73449b469e3631e1b02307c5cac2ce1528d784fab926dff51f86"
+ "241b9d66f79d6d8eeeeb249d76fa9f166ff9a8c6a39e832d5d14b9d7ec5a3dc2"
+ "8f01ebb06e39d59e8461b955b2a7f5b1f204b04cc6cc62646161ac1c2bf5bab5"
+ "0f068c908d28de5eaef7e8ebfcabb09b7d75d83540dd4b354d131d86f0770717"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.3",
+ "0e233b2549bdd21ba51480da8e3dcef4db20e0dcc05ee237351edbc9a53c52f6"
+ "74d105fec0939d3699647efc1e25cb4e9b1ab752ab6fe28869ff73f23e01eef8"
+ "674c535c4c9335f798f1deecd489d06dc88fd6bc1d4996eff72b439e3c014dd1"
+ "4cbf17715c158943de2e6f971c349987a1b395d682c3b0c17b66cd3ca41060b5"
+ "7111e228314b2d34b5e44e55f1c11c31a6eb80b5f82d96bd4a17",
+ "d075be06cbd6223e871b0f3362a797de282da5c40323f37c2cc37465a1a86368"
+ "ddcfa6daa135866c3203d0472260b29c3c9b1b8894085d547c5eb931424f2414"
+ "0a5cba153bded4b9ce7daedc645d3980c5f583f76711c67b193a5212f2a9354a"
+ "6796af090820913134ecf305befb6532cd48d4113a0ec4869a0a5655dbdc7259"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.4",
+ "d47c0f5c922e4f809e9ceed207f124a5acde37fa14638e8fbd0a72fe45262195"
+ "8e37682c6ff283f3d51da152aa1f6374cd27d2a4a533053916dff1c07ba93631"
+ "7481696360690458d8d1e5d66c35f9c99a5055d9f7cfe7605cca57eac335ade2"
+ "eff6b5aa627d5b",
+ "11860bf4d74519ff8cfcce3d33e3aabdf77140a15636b2678df9673144c241b0"
+ "a99a0a37f292cad51df0b63b14f8ab17e3fa15587790fb062b5f266c166b2ca7"
+ "5157a0f9e1a5c8ec26b9199d07187799806a1de98715fbe52757a703773c918a"
+ "000c211a78228525cb52eb441b269b3f33050ed1935ac0e8596319ae80c75b84"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.5",
+ "bebd9ddea3abf9f8eb58559766f8b3ab83535238c43dcd81a2949303a95f055a"
+ "8340ceee1615e58df1e014c7552d769f8841ba09975cefe7e48dfc6a2649e820"
+ "03e7bf420e70101b327d9170f73e8d887cd298f53dc1bfc882cf0efcfad6e86a"
+ "0e7f9094c4f26c46921e09",
+ "84a26fbe67010aa1ef2d6c79263239b978f4e893dd1ec6f07d2317f151a2a1b3"
+ "23e505f9450c37df6b1bf3e24f38b636bf774e96741ffaa769cfd7a8a6b3a5ef"
+ "aba23aab3a437a225bd94186e91d392bed2ead8a78f381f40949cf1f3d272458"
+ "1f25704bdf6608dd119e36d87d0355e6706c8a5259fd60c8df13bc62aa9fd57a"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.6",
+ "9d198e2c6e12f74a9a081bcf70fc04168a49e09c5faaa011e9a09e2c43ee2cd3"
+ "9bb2f7e5682deab1fa111e41a3194a20a86da55101824d3d78a7e32db2b60aa7"
+ "73770b573907b409a2592c83f347febb2d5c85e9255d6dc12aaa335adfbb5dc8"
+ "62d7861953e2687d5303b686fff9634ee4d15cbcc29f7a3505a73deb6f9e388e"
+ "9685fff4d5450f1e3275359a2b99440c6739f5b91ebd14ef78ae73c1a61911f5"
+ "ae3a2b914967491727818065ee010df49d5a16ed8dcee848ae0948a2524eac7c"
+ "4ff9096ced61357642c5e0f80680afffce0ba7eb59589949526ff51235cdc72d"
+ "47a27b39b8d4ac849c3bc04fa836cf184bae0c83415956",
+ "38ef245b940d93970a503bf43e28e17b8aff083ccbe1e9c48e4d80f516c27d08"
+ "5ca2a4e573236a2494d9b997f812484812f66525d06c0a0bb2130c15d6ce18b2"
+ "2f3cee57097fc0d558afd9af27f151f8436fbc87d6be6142647a17e04df6dec7"
+ "0a95c7daa84ede94ccb43e1d2c37b945817310d14a22b5b9ae611448ee41bc70"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.7",
+ "8e8ba8436fe3104b7ce2a4efc36c857d49e849c0085fc657baa0331793b3f36c"
+ "7ce738b6130bfac75e5011f32aa3d1",
+ "7844699f1c4f296e50261f1526e0dd84f01c82cb85fa24609eb03358752c6cf5"
+ "9994d84e12f46a7200cf5ad97c08dd4ffc44657db57214cd1f4eed6b77d239fb"
+ "58216988c5e5bc735a4fdff408eb9f1279d65bbaf6a681924418349e62ff5e58"
+ "15eaea592d90d1eef556fcd4d5b4b89c6c70739d6f0d3d0bd16a50f1e0024e98"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.8",
+ "585fa6a7f77a4b6eba5690e73e7128b72e677cdb3aaa8629ed61f2ee63af1a71"
+ "ba87136a52db1a3321fcfeb248bf2e5cf5c639571d5895adf1fb0617ed140a2a"
+ "0d9837c3c1d8450c289d33bc962379d73e3087f2b7ee6eadd6650148c042b6ff"
+ "04482196c718fdc0ce579ceb62a81e584373eb937540c426b5566a9f407cfccf"
+ "bc4b753694af0df4cd6aa9f16546a63394a0f6577371343ffddb651a62a3a58e"
+ "ddec67a29ccae896563c63e3c90d54d91358adf194e6aab1f9",
+ "6893351c73915fac47c962cc6017ca74a5b5ee4cb1bb5a10ada2a43158a2261e"
+ "b27b866db39d3590b4f8d20ee67cb1a5789463150d839343232543c826505101"
+ "e1d2570426ab9fefd65ba84faaec731f27374ab10191c960831693f29a854c38"
+ "128599f7287749b0b48bf7e9dfdaedc84eece071404584730cecce0d5cf005cc"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.9",
+ "783c18b11f",
+ "132fdfb84193dfb79fdfe6babc2efd39b26aa20968a07c0e41560ee4dfcd4fca"
+ "7917490f24e8df84f4e0115a3e63273e7a3b128abbbd17b8aa5a06ba155ecb23"
+ "0fe797260479957010e44ba575292ec3f151abf48e9103e55142ec67a4134dd8"
+ "f38ec659f9a789fd0341cef2bbcf9f529b93218fc3e43a766969d1bf87884807"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.10",
+ "96dc98b0eb84f55948307addeccbe76439ca3658bc36359624c8fe2fa09c52e4"
+ "7acdc32a156d907682410a8567abcafdc6d8bb5325359ec75ffdb73ee0a9515a"
+ "4ddf9a31e5d519460374280ada30de7dd534deaa57",
+ "8fb43dc8f06f2ba48f19be5b1a0931213a990aed9c9fed1de5d6f35a2a782f0a"
+ "198ff6388d96e9d59b88e97822f349ff4164eea50a62935c61cbc76e3df75f68"
+ "4d962475e563596496c9880a48ed978a6315a345571791cb2ddc88dabe418798"
+ "a6a441c47afbb1cd15213eca3b1115ec8f58f877be8fbd38f4fdaef939f52640"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.11",
+ "372001599d9930c7d557458b436decfdc14d06cb7b96b06718c48d7de57482a8"
+ "68ae7f065870a6216506d11b779323dfdf046cf5775129134b4d5689e4d9c0ce"
+ "1e12d7d4b06cb5fc5820decfa41baf59bf257b32f025b7679b445b9499c92555"
+ "145885992f1b76f84891ee4d3be0f5150fd590",
+ "a897c7f972e11749e1e7c155ce9462aa7e1cc0a979c12729795126cb8c0ea502"
+ "21c426f1bb06c1caf7c51ac2fbd94d688da67ddf3ef66606e989a16de1f92b17"
+ "706f88e87d9f1469a005c9fd76788ee8c4a7f01209e28b86f674881af57db6c3"
+ "429b6fb45698bf5d3007f61c7d441178ad1243a49b2aa6029bfe902d26e42375"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.12",
+ "bfbfd07321f0f1d5fa9fdf0014c2fcb0358aad0e354b0d29081b233b43567750"
+ "bd6e78",
+ "c24d31049409aa16d3f972ef8b7595eaa007833e2bcdc7504852f2505fba1fc1"
+ "5f19a0eadde8335c7306fc3f51661da520ecc8db7f473885cabde93f0cebf1df"
+ "9e8a82370b00a043ad632cdcc78f3fac1d8a3757fc8e5241bfed55c49604ac19"
+ "abdac0c9c40da373c15f3c1bcc973ffb4f8b7b5b553ae075e1b1bdddd23d7d2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.13",
+ "c69739d22ac8966bf11c116f614b166740e96b90653e5750945fcf772186c037"
+ "90a07fda323e1a61916b06ee2157db3dff80d67d5e39a53ae268c8f09ed99a73"
+ "2005b0bc6a04af4e08d57a00e7201b3060efaadb73113bfc087fd837093aa252"
+ "35b8c149f56215f031c24a",
+ "d06d32260da2db48104fbdc24e16a65b48737d43ce243704042aad6c03fde5a3"
+ "dc0f2cc6e3ad68c3c62eabfa1f7b1cab009d1175aff77be58fb12a4e58127fed"
+ "63ea3df44181bda38c773c83b9e804bb3db7963263df30e92c4c271956e7e810"
+ "452c15e06e939666df0c8334033096c07dea05b44ebb142492e7669131ebcf2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.14",
+ "733047f336f9154738674547db02a9f4",
+ "c113c0465c84cbfb0fa1bdbc54c3e1068ca23e69b8391909c3900fe5b4e7e3f0"
+ "34c9a988a3ddc3c381756a1e1a27c1ecfb3a70e1ee0e920418ac4ab6d9532b8d"
+ "0959a653b4c508670663462b2e135816b694a6b9b468a29f38de53bfcddf97e0"
+ "3d8dd24f972633a49cf3eaae1d6962943860dd254340086b10357b80c1cfbf31"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.15",
+ "a9740b9aa0d34058fd3b906e4f7859dfb07d7173e5e6f6350adac21f27b23074"
+ "69bd0ce19549d0700120cbe51077dbbbb00a8d8b09de8d8396e36507fe1ef6a1"
+ "9017548e0c716674c2fec233adb2f775665ec41f2bd0ba396b061a9daa7e866f"
+ "7c23fd3531954300a342f924535ea1498c48f6c8799328",
+ "4fbd4fb23704f4149ada327fa53388526a07dd43d915fcbda9a13bb2a3738f4a"
+ "db1c3db26ab69048805a80c81605c96d68f841802f5abb02057b611fe2f39471"
+ "6265e545252c230ce474aff0bbd4ff1f3808496036a4948ca7a110ff26c638c5"
+ "0f3215b28a09f23af6f84cdc897898d0fd223b13481fe892b1a58ba2e4b3685b"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.16",
+ "af8f0887c219004d2abd894ea92559ee3198af3a734fe9b9638c263a728ad95a"
+ "5ae8ce3eb15839f3aa7852bb390706e7760e43",
+ "327ec9d0be7aab7bc959d40227e1d00481fc04011fe08fd5449b90c0f054e0d6"
+ "59b926cc812921c20a563c4abe4f825d6b5eef57b3e2d65d20a8013a50dd5c93"
+ "238cf049f2ff0c7ebeb8e8caf72e46e7cf8a0c3f4925616b1bc1826ffcb0bda6"
+ "0bbebedfd4c60f2788d1666fb84511853646c2dd466851fac85be0ed5ace5fe2"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.17",
+ "38df86557f375d09ccd8bd15d8ccf61f5d78ca5c7f5cde782e6bf5d0057056d4"
+ "bad98b3d2f9575e824ab7a33ff57b0ac100ab0d6ead7aa0b50f6e4d3e5ec0b96"
+ "6b815779a91b3a8bd049bf2aeb920142772222c9ca0c328c659e0a6437433cce"
+ "b73c149aec4a7480d5bbc42920d7ca235db674",
+ "3046055c2b8ef7fa92c8a9e395985bd460fb6b47986553944d21045119f7e761"
+ "7e03fe80870ac6aabf63b096cad5cce7f506953a7f693fe137adfb97cd458128"
+ "ae95c47ca948dacf24036adeaa48f29a469fb513191e05acf79e67a793a3af5e"
+ "4f9c6d0d01fdd0e0cd4296ad3da2ca89a50eedcd9f7b877d2ae1d58d98dcd78f"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.18",
+ "cb34edd5ab654041b6143056",
+ "1ddf48ba5351bed0795f55b306aa1c6ed836f592ba93cf0c46b7c273709d36b8"
+ "dff02abdb1a768d1c7114a86a457496da579e4d819f72a192e298be2152f7cf3"
+ "9d1e30827d0282ccf34dc8889f1c2f5970930d9735042f8a5a712263165d6e6c"
+ "5035e2e4a50e863c06799e3c89ccb5cb0e70b3c99c084030677a7c97907a1724"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.19",
+ "5b09ec88b1527178fa043263f3067d9ffe973032a99f4cb08ad2c7e0a2456cdd"
+ "57a7df56fe6053527a5aeb67d7e552063c1ca97b1beffa7b39e997caf27878ea"
+ "0f62cbebc8c21df4c889a202851e949088490c249b6e9acf1d8063f5be234398"
+ "9bf95c4da01a2be78b4ab6b378015bc37957f76948b5e58e440c28453d40d7cf"
+ "d57e7d690600474ab5e75973b1ea0c5f1e45d14190afe2f4eb6d3bdf71f1d2f8"
+ "bb156a1c295d04aaeb9d689dce79ed62bc443ee20c",
+ "af56fc329739e2f7754b6ca25164a6fa58f685ddb742b4841d73a5e2c4c45343"
+ "b74dfd2f0d370edddd36a017564a8d3ad402e2a341c972062c23814a00131e17"
+ "b1dec7b4c57c5bf1d4fa79222937a4dc5c00235f853dd23dc9757f335c85c207"
+ "eb074d4bcc243edaa7831b83135655e2277ef29e7aebf34a0f7b234a28650a30"
+ },{
+ "PKCS#1 v1.5 Signature Example 4.20",
+ "3c330c1ef718c141e47b8fa859be4d5b96",
+ "0b1022dc38e217fd3b0e7ef19dfcb4b456366240983095f6db965831a70f0f8e"
+ "20e2dd2ac231cc379045c27365e73a53719bb6f011c3f8636b64994ca480602f"
+ "b3b4f0e2274b58b363e0d308b528e15859a91dcf99bffefbc8052241b974192e"
+ "636218f398332dafe8259ca5f5ccfa54c9b32b2735af0724f40b5a5d6121a40d"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "c55ffbdd6a2753bc02af20ae18ea0daf230bb6f8795d05efecc815baece22b38"
+ "79995f6d9764c1df8f97851381686266b8092fb6011898a76707a4d1d5bda08d"
+ "246c687a8bbafa6398ac9ea2726823714a0c3934ca6e5f8ce33987b534857ea9"
+ "f85cc4e19a1d2183e0e4c8aa55cb227b0e56ceb2b62b30efc78864b2f9fb9249",
+ "010001",
+ "07e3fa71b398b6e44147370b3ebbbca84fc25c223ad7d930ea4a6573ff9c5b15"
+ "fae682c622d3485ce3a4af11448f23bfef838e80bc327b87d5ba9c80370749af"
+ "c8c1c017546fc6b65931b759ca4341fa5e5e10b24087e6e2c0f4dbb790695299"
+ "9cbd90d2435fcacc9c82e48fdf24e495cff30ad419e7123e3ac942272e1abab1",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 5.1",
+ "eae9a40bff183f4114732e7b3ba556f4ce288daa83e3ff23611244a7a0901f11"
+ "7d86c09c33a5232bd320fa37a238a8aa62dd21abbfacdb93fa1c44cc55ac61be"
+ "a24a6a34cc6476753837e16facd82eb49e1c57c958fbbff568887cf82eebe961"
+ "e580e064db9cbec3b53df1f27199e49a04cbe59c69a265cfac8ce4f91ca95d52"
+ "b1145c8b9f4440b39c185094be184874da5971d7d763fe07ce16e57f1e50d228"
+ "6504b481e2c685bc9d9c01493fd3a6d8bb9b2e96bfdeb6c92914ca",
+ "44ceb442242bae085994ead07b709543ea2395a6e8d46473d70df34a9555aa56"
+ "7f4da138e963fe9286a84fb7c5cf8200035904b50c32403cae517bfa7fca8a66"
+ "fcfd632af747c49cdfb0b9aee35228b7dc4c21003969b0a013ede1292b65d10a"
+ "50c90263fb0bf4f4b8376641b03e1fafb883f038f4323dfe5beac468deea99c3"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.2",
+ "9de5ca46748561a0b928b260a95a3ed920adc8d5eeb9271dc71bc14f69ccd631"
+ "1d186a779f5eb8db17c690d6867cf3369bbff15fabb3cd2cfdd6f7d75286ff2d"
+ "2499c5abb48ed54fd4d849a9180e110e0a53a721398292110fe8be26",
+ "445ff5b6879f8ce75395016f0495f13135b179e73a3caeb330e3cda7f31f1dcb"
+ "a7aa82e268c935e9d7014e0b0dcea69c7b968adb17424a64dfd1e2bc5707f920"
+ "fc0c83cc63dfc74b963e682b46a22ac256ac6be5709c07cfcc3d4eba3a1d61ab"
+ "15f1badb0a49fb5cf09a1f7481a3aaeaf7c257540377aea7b54417a609c76f4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.3",
+ "183ba1a3811d625ca9da1bbaaedc76192012fcb674bb9e77d8f37708d240d349"
+ "e05797416feb24e3018c7a205d059de8e0ae05a8d7e09eafeeb9f06de5d4287a"
+ "bbef059bc586b21c82d64aece8d7428afcd7b22fc5d168bc076b615f02733cb6"
+ "3125c8f36d5cb809ce8065082398b3885a8919570c478a072f596615d78f0136"
+ "d11be32b3fe0f4fbe3c7da5d81341910177e48b1bbac276c12ee815465dc67d4"
+ "5324f905aaca4838d81f7431463e89eb8b9536586936afb42cb47bd8c31829d3"
+ "1ec1ee29f91ccc6df9cd1b0b9b8646b60267fd7eceae92c0ae9e0ce5ff6f7e0b"
+ "f756a9b8ffc9c616",
+ "ab4b78964c2a35d32855e0efced34bf80219b58c488ea375b1f327166a5135e5"
+ "da9945c287297a3d932e572746f022748b85585a0abd9186f4ac35edc850d2fd"
+ "8805b9e9f51a5adcb95e1ac1729e57b85331c1ed15c3d0cfae33f61c119b55c9"
+ "5e344b72f2b4f8e7e8fac7a33e5b8b276a6088a7fabf4fa172357fb6e3f44a94"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.4",
+ "8707dcdb49d283a23a9bd6ff87aff834f06ff7f47b0e5f57ff1a0d995bba9cdd"
+ "5ea01b42b25d6ff17a0dc10605cf452aca73be54ed5e0ce21566afcc17912abe"
+ "18dfacd1bc03e3e2882a4bb3a4f39eeaf963d7c35e6ba858b1376a075160c6cf"
+ "aed5e8c52e451132347219bd88893eebe35659a0ee4d94f94d035b7a8686ffb4"
+ "16eb99fb2aaa81236b05ac4645925f2c2bc19ebe89a63f2f451d0b13b2fef061"
+ "e530a349baf3b2356422b095fd9f192993ab99c9f9226ef9a7b3cfb365820859"
+ "29c876b5e9d7c6acac7bb0275234e41ed351c838b7a31a",
+ "1753988b39dc745df9691af9ee69cada73a9877cca12f6d40627dced7622147e"
+ "c901a5b463e7ef9b37fbd692785aa22a465df403af92a29f795d40a83fa964b8"
+ "5a7ec05a3cdae3f8bc8a61a79dc842e1d377bc5e1d46adaaa866be282c6e2388"
+ "173644f40627bcf8a0974a4be8fcc48aee7e8259f868a2bd789a908992056e55"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.5",
+ "ac9fa3f63df068e90d692eccfa7d8796491aca795b9858a45518623229af28b1"
+ "3a502d8cb3b95092505882eb994de74659625698a0050417940d8bfa28a3f93d"
+ "149ff8b0bb3926f618ef91966f4d39bdba5a0517ddebb16d2bc4b4e33a7d619c"
+ "95a33cf5f572dbe07fab4aa67fb3f39aa2981a3dc0caee64758ea898ebce10bf"
+ "3aa4fc8449e8e0cf7e88b188238c2068efacebfeef4073a654a58a3099d036ae"
+ "ee2d818298d4ab39238edc459a9fd3577e9f5bfc0368aa657aeeda1eeb8ae7f5"
+ "ac1eaf3b1c95817dde2ec1a59fcb5ef27cc34fb75331da7a4996925ac3ad17bb"
+ "c3dafe6a9c644e3098effef8fea5cc0d5f0c048e1088",
+ "11e1a828f00a987e03d62e2a536c297ddac022e063ee0de4e4695ded1fdb2209"
+ "00a3ac3f87d1be75f959c28b578a43b256643cdfff921595fdfbeaf410c2aed9"
+ "e5e47e1d151ae28c7699aee225a645bc42b3beb52f08387ec554d0204d283c3b"
+ "ccbcca216edad94ec64f9c20b3406ab78a6c4a4dae3fa617a00c6ab2f8e24762"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.6",
+ "1574697344e98685cd6e65e46783f0b5",
+ "3b7d67d13cd3c0fd305ad404d8a3dcde4a45179c2d0b87115d6d060c249b87f3"
+ "9e463b764b4207c48a74cfce2531e8183d3d012585ce5739d162c4ea22324402"
+ "ea2e6eafb8a573fcff4015c95c45e4ca7ac51ae3a06f421e606d683f5e122b55"
+ "79148a9c466adeb02428f4896a86df63be587ddd7a6a8de7176be4e7ff4aaa99"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.7",
+ "be46be8bdd8543d370bbb7ac839f5e6453f30cd8752a4b926732c59e6109044b"
+ "e3a0756c7025a23280df2ed766ba39abb20b944c065fe1487dea31b4708a689a"
+ "50b28d542994cbbb3a5bb9460ee7a9c1538bda751a528b7670f91578d6673e08"
+ "abccdf5f4d8c1ebecfcac75cc42dbbb8cde3c1b474b556b32bb848fc327ba6e3"
+ "cf5f77b1ebc04a19f3c8c39b6b847784eaa325a2b6f3",
+ "91de2f903247b2d13abe93ddd96dfaef1b4d172b090958f0cc34fa92835ad60c"
+ "44b427fe031cadbf92ff1cd0384144c9b5f28f645c63e8d716bcec2e043bc396"
+ "56641785c26ba36ba2a109e3644ebfd962d7a316916b3f13662013cc0f37ad8f"
+ "9e0d9ec8b4c8ad5c7532cfa044aedc73787794c298797c8a7e1449ead6150ded"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.8",
+ "0b7e0663e715ea38bc930ec9d8e2a029aa1a4c95e7b20047ae1544d5b2d8476f"
+ "c805539fb0efab7d5ff12c36d76a797b75c0b53fa9265473dab680c255d57e99"
+ "b6d9fe08cf1a573491e21978fae9539cc05884633a1dd5cb21536fd42ddd731c"
+ "a76c3457813ce1bb59c21dd31bf2ae3bfd7d20c6c712a9dd43951f1b198deaf7"
+ "4108ead22926d2b0191e59d5f679ad97c71edc69de97987e543e87a96a9fee77"
+ "e3f0ea957bd46a",
+ "4851098a85e70da33392a9e90b3476a48ba0e32cd6ad3dc1dd91da57e88dfbc7"
+ "b6574b08e8716080e15df40579c5705d5bef584b08b263dbc4f0d15956ff1125"
+ "c48f89591ebc941d9fe8f9a780c82ea32bf3efa16cabbee580fd6b9574080f69"
+ "07feaff81d48c49a6de2248480f1d85239e9a418dd5310def776e08f509a1478"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.9",
+ "134233bacfa16dc84d8fa4bdbb4793d1dac07d6054bd083961da68679ca37533"
+ "4f0920b9dfb8a68ed77f27fd9219281361e09fa6084f96e69885b47ea775af06"
+ "772d6612d4d16f4a5cc4cd0d1eb23b7a1f09564b842ea07cbdde60453a2aa4ab"
+ "69ddfeb5b13e9f08cd072e5b71ced334ea704c749ff4727ebe12c0290e00a841"
+ "d74b0655cfd8065d2820fdf8fdc1bd455881808bff0ec727607475bf0b2bc893"
+ "5958329b778efce560fc26c3bb6e2dc9aef18f969fba64745ed4d85b14757bb8"
+ "33eadb9c5cb0eaed08d30b9515005a3e88091fc5cd2f36ad955b7c6f2b19bba3"
+ "74fd",
+ "3e37b42dbec129db81c5e2a222f31e81b937ff02249518183730378b4c092aa7"
+ "f3b23459611a824fc52754421a27cce918b62aa7b44638a0c082798052a58846"
+ "6882510690ac773023280246c890ff1f6227049e668bc9d6e489b6944a34e8f9"
+ "3002bbb00d752b577ce352530082becd309b0daccd1d68d06e1df71221c62269"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.10",
+ "35da3d0234bd74fcd76e8e69528f651b88271cbf16286938c2c4a37d411de8f6"
+ "7578eb8b3d20a8fd7dcde7b656fe96a680873228ed0f9a620f1505442372f9b2"
+ "b4168498723490f811f3111f5f77386347b4822ed9d6b5538392215cb6c4865b"
+ "b7b5b7e2842eea0e9001ca0cdf5d6b",
+ "12ff2ab5fc83d649597c47bff329b7f461dbbbda01fb6bad26543e4dbcd60c5e"
+ "2cdebfb112784a964e27f2a2e7fd07ec390aab1494370358a75b5e1fa4f1ad52"
+ "02e6d546c0f315e86faff1d25b947282da32eab56c22f06c8a9d32aef281d6f0"
+ "aa55d7ad3bcdfdb209a16ef45cc6f9682eae963cbb213adb7fad1bef49c0704f"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.11",
+ "75fdb07273f754d1116f997af2d11a512b94e9e04801b3fc739130b747b4be87"
+ "44d7e7f8a297a089d9050c5f54f8a39aa3f2",
+ "07ffc1b7a10ddaba9605f0a3d93c8a5e4c0b77586139050731d9cc9b3c83d2b7"
+ "3faf9a4e24d1c8bb0d623df10fc8407d151448fa43ee6581e7b0ac80d14adfa4"
+ "f6d27a766750b231cbc1c5cfd62df1b9727d8b8741469f68e50a9b3bc7ade137"
+ "db06747603742856d5e7ddb4e16a5b49d7365db2763bf5fdea083d81fac92d87"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.12",
+ "96c9facefba2ed33ed8b7b3d8b6df28f2fab0dcdd7a3cd7a7deda2545ed4470e"
+ "d25b46d2166eebb7e147101783b645bac62664b8727009f35d1ea5fda5e7c28d"
+ "6af6fe92046ca724cab8425a52a085f9ac9083d4d690bbdddfd0a82d948f70d6"
+ "85e26bb9f527408abc847bff1202dedf6d2fac6cf3682a516ba72f4fe97b9046"
+ "6af6e543123165b8a683caba2fa23a86ac06213065e1ed9b4f49af4fff6d46b3"
+ "6d133d8da2dd29d55f9f322c40785ddc21c426c5e0a67d414f5ab971c4460ff9"
+ "b114305a8ae7e7b95c73034e8e93c03529dd50c94f076279775a5a3a80c5d248"
+ "6a2d510848bdc9b852ac1d32ceb7c041a08f2f8e62",
+ "46d03faec4a72318621ef4d0c1bca71a2aeea7a81df8febb8ba3fb3540d72d15"
+ "34b9826916e89f27d325676ccf5a0aa16112db2d9303e0ebce4b85587c55aca0"
+ "6850de84dec213d1137404a5dee6ca88d91ae28b7b536c90202bc7726da5042a"
+ "8508d3b13cfbaadcee1278d35d303acfee6e0741904911a5f18810add3e7b8f6"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.13",
+ "c4b4c9966e56f40aff4708131cd3714421343ede70c4d46db6efbe1b19a9e3c2"
+ "e58106008a983859cf942a319774695a0c98a963e2fe9d9379bc",
+ "b16b10f2bd7ea0f76a9ed2ffcf3ec10edcb82460fe5582a7764c0c5056ecfb09"
+ "720648d5f19b3deaf2acc986460e7114261583a5f4a990e922feb5b4789734fd"
+ "cce15ddc87cac3f6c7c9e9e2192315f0841f43ea86dea9a9380508b06c9ca5e9"
+ "d4a651d01216627c466bf0d6ae744bf30fd791a8210339f5057ff85ceb84f196"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.14",
+ "b838a5d888950f1b8e4d947bba51aff9bb60b83d09ed9d97967a76955ed1ddf0"
+ "481520bcf4f08bebbf899cc7c3ef0c04d5001b1e2e845fafc583300c98aca7a0"
+ "3e90a434de77fef720da3663f21998208a94f894767d3ed81396b7efb286e0ff"
+ "7db6ea8fdb4e72834600fe5f7f150a01b1d4a08b5ec9ee1fbc1001d12d5236db"
+ "f0727e7ea36078f3ebac5046b765b4e23cdcefd115d62a50344dbbd7428d48ff"
+ "c94b11e21c",
+ "b15681eef296a66b9fcd6630f89c55826a389e0c2d3d476a0f8a1e08cbcacc66"
+ "02c714438f32f34e02c36e5c0f168ab028917e9050fbc850f0cf65d5eedb3b54"
+ "be5495bbf0faeeb32bbe5a8f87bbacdd2585fb907b13185b02615663d2011ef2"
+ "3d0ab04dad1ffa679b53152c9c42b84639684eaeaf644e4fc6ff2ec7d47ba5ac"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.15",
+ "9fd539c8ad864924eec1d655c07d1f28270cdb326b572c4667eca6488c033657"
+ "ff29254b91f3216e1cac979753f223b179ea5f9efc236d401d1b9a3c20eb2afc"
+ "9bfcfd0792acc5b00c9828a645",
+ "38bfdfd3272e48cfee68ceb91304eb91ee25e483401f30fe12d5e43518e4b771"
+ "14a12c8c7992aee7d2e774fff91d8fd1cb7c6a2adf79b7c8ab93e8374db74c26"
+ "909c659a97c76a222df4fc8c7ef5199080eaae2d031ca751c5013289db4ead77"
+ "b28b76a4c496ad0eb422fca88fc684e42aea88fd33c256751ba066834e77a1e2"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.16",
+ "1de807409d0a61b0322dfed499e8c33241ec89cd7d9fc5",
+ "8b6664f869d755c5d3e6df9922e227c110918a6fbd88c1a2e1289523adbbd8aa"
+ "431d0786853ab596dd5b001243b54a2cb10c3166bf002338fca20345aede1b22"
+ "ea1fa3d241c86c76bfc02f4fceae12c8a9d7e44ad6171665e88f128522dd535a"
+ "9d65008f6a732d40af204e220f1facd942e09d15099fdc51b3a1426cb2dd3293"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.17",
+ "4b2bcb2679a14c3c4c069ed089a65aba29f22b6178c0",
+ "1c47828ea53fb6436e9596b0ce47d9f38b5deb0b197c1bc474e2e8226570cc1b"
+ "72f239312ae7c3c6382e1d8cda7d4f12febad70afae5acbf2428abc04421bb4e"
+ "1e5990111b9ac83c62435c21aa25fd9b4907585411d253ba9b8778f624053d46"
+ "fe95d7e22ca39381c7792eff46438fbc165ed7629c2fc1cef1b34d77768a2055"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.18",
+ "ef46ae51e0158cd0ef9c78d71e001567d66ae3c5e9a64f245715c7c2ad8eea0f"
+ "9d320023072fdb0fb86a45217fd712cc80e5b94147c45fe00b692ccda1102598"
+ "41b2c7e5c3dcff5956f2a596cda68eb77f4c8590d736b8fd6066773ef6f95a38"
+ "cd384e9483a89dc2b6c2e8745c95c12fa672a1becfb63eac9b553eda8d293754"
+ "ec3947eac0228de26314b59b66994cc60e8360e75d3876298f8f8a7d141da064"
+ "e5ca026a973e28f254738cee669c721b034cb5f8e244dadd7cd1e159d451d4bf"
+ "6580f3e69cdc0271382e8dc14bc733af38992c1cd882c7b150d23a067b9bcf3c"
+ "cdab6b0fba132b4c1447c87c393f",
+ "8c1de15ab86cbf5bd9317ce2b8fc82f5722db6961c9f555140f78ebda24e3f51"
+ "fd7301c1e4fe12b6957c30144fa1e127274603dc02051130b25385fc8646ee96"
+ "a74550d2d63f858185bb984652a3431d533da6014622a64e0691662a4f7c9d58"
+ "319ba3f85f19182475e1509bbf213af01010b4b9f82e647511fc97c6b7c97e8d"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.19",
+ "f87bb12daaad62c864ac3d444d514eec6e59b67cd0820dfcbdf851ea73891f58"
+ "a8be6e843ee8773e4dc1c7d742da82ff16c1011b99566b9f3fd17d68d5ac99ce"
+ "f5a3a0f75318769dc013bb055be13056df49a839b8395251399b27a0bb31c554"
+ "aedf3d9c7482b6620c5d7c6914a564db04a000045699ee1e5088a5b68d814efe"
+ "9d130dc34e2bd97851139c73460765b1f2654686fede9c9b3e92409db2d42a32"
+ "ba9e20bcaeb2c4f9ff9b0e834b7492a2b1d8c65c8ba498342ae7d1d9fe7405c2",
+ "207a348cdf684aa8e1a4af7b7c252707ce6f1f9db2291f2a95a0715d9c7fc51a"
+ "a230110b5b518a9c8f958dd20c7524d5b65106d7421ba9fcfb789178412c3640"
+ "f540b81bb31897d2645ec79d8e5975048e452261a1c2009cfeee0715a01beefd"
+ "75e704b2a6f0f0ae7ea36c53cfe36f57f034e385448fcaab08dcff477d36ff15"
+ },{
+ "PKCS#1 v1.5 Signature Example 5.20",
+ "4c4b",
+ "1cb6881283dcd1863ba79dfb22351bc9a8e0358b2f8a1de3f9065d8ca859314a"
+ "e11213a2cc87b2f632efa67d2103f38200b9193eb8d49982099afc74428f4b41"
+ "316f4878b3f600bc2fb30458cc9c2a034a068e98d57ae79ce3e2fc84b6a745f0"
+ "37a5dea2b9da4e8db4ada69fb82d20a41bb8430793eef92a4fd6186d179663cb"
+ }
+ }
+ },
+ {
+ "A 1024-bit RSA key pair",
+ "d6311457e1caf1224436697983c86dd338205862d2a105baf7103428fd8353a1"
+ "9b7ba4228f78b47f7907357034c52d8597da2b5d13dc535b836c74130a364891"
+ "8d4a7a83990c2e28816aec0fca01d105c6c652ec5733d01f0058b2df5ae67333"
+ "405a3a5b1220a26ac3d142f2b4d837eb7386a40a74cc3d1e4fbc64fd7da63c41",
+ "010001",
+ "5ea61177442f899ebac5d09601c5efc2066b44a366b000f83d74cb97d16ed6e5"
+ "f2ef0ff8b5ad81155345fc37391a68a340170852791443418d31bf992a4a1286"
+ "6fe9ffccdebbbba637ee887b716caa92e249ced657eed71f5ccdd9163f326952"
+ "5d789f4b33c48a95764436ec325e8689691c272d90bd88889851372fb8dcb9",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 6.1",
+ "8f750e65951b5de75814b0b76630dc9f1c6253a0590eacb5512a8a4e1a8be852"
+ "5d36941fa9d092f6bb4422aa8c0ad6423ea28c10caa6e954b79569d44c860f1c"
+ "6581eb17a7543e7bf7fe",
+ "b18b5ec88d4e24c914b665ff9a2c75f4e91937df8c19955943e451addf3484e4"
+ "97978d26da231af14d9c2927ed210afbf9dee33267aa45684649e86fb225a053"
+ "b5455290c320e3f640623c75ca423721f280b887442497f32a90d78f64440477"
+ "ad0927c7ba01c44da9d5c283a438be0dc580a00528fc65e204d42a2d4e2913c1"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.2",
+ "bdbf3b364073fe048fbae55e3cde668e84f753abfc710b8cdb7b6c0cf82dd5b6"
+ "74d21e2b3e36b1b0360df8bf7e6227c92e15f3d784",
+ "66acf043bc6aae81a4d52b4e8c40128b25c6d10a8c698c83aed71e8f3583898b"
+ "e8f4c9bea4b63190e21526caf83ab14a4f8bebe813a5abeb959567bb2f06c5f1"
+ "1e464b5cdf7b2a132d426ddbecf585900a0d8092ca52b6dc0abc35f140946989"
+ "46e1cd0ecd6bd41e2c6f963ee89c82193ecc5fd47630d34ad16ca2479eaf062d"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.3",
+ "3c5c74bc8fae807ae58bd213e6272aa3857931575c2aa2be4bcae4d79ae087b6"
+ "b86f915df8c096c122edfbdc797f9d70b9761397fce3d3e0b8a6f256dbc6605b"
+ "a948d5fbe6f5245c0295ce5dd73bf7436517f7c4222d2cfd8542e7a100cf0513"
+ "04a1ab6fe005da077b62878fd0b741e6271e0d346b20723b7e00b3b8194e1a46"
+ "0c6bf25600768290c1dcaa2f41b941a64fd90214d5166d78aabbaf7e41d24ff6"
+ "36c9762fd892199d2cfd9deda50051e001b9fd3e5e2227aecb15c1b31371b35a"
+ "78b3b8b7636376f134562b4e52f451b741a19ac932569ff3041faf12279f90",
+ "5e897f879ba46f67112cd7c7c6fb2737ad793a872879052a88457af5e9d59959"
+ "a848134a6824de3a674f72a906879e95be0ed87ea9f974a7a07ba9adbec2fbfa"
+ "0294378b14e735f55f403ca053084f51d3d342d8af9c64b4d154ad9aa3c6bcaa"
+ "ce1f1bbe62eeb5d0e6c4c03093c2af0f07888b8bbefa79400323133f776a3213"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.4",
+ "425646650d6b379e16e15bf3853ddc9d444f44535c493a3703b00163af3476df"
+ "372a5b28f334c0860313e8136de608291b3378381b9e21ebef24825d12",
+ "a6a0cb02481af248abae89cdf4161f6776d47108f18ec6e8437c224a14f452ad"
+ "a136520f0fe010a7345af1971a02e4bcf8c98b26c5b8c6003de4d2b4072d8def"
+ "1e1923d9cce0a675141d37873e5948ea6c8a780ed2a5ecc2ba9a81206c7eccc8"
+ "0eac026db7d760223aa2387a182e98d66f1e23dfeaf3515cee4fa1abd464b768"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.5",
+ "f47d87bfd488af5b24db34ad0c131efca10cdd1aaeffbe6e36484722ed6809b1"
+ "d57a183ba03d5e405d1256b2505ecb84db35dfa94de85dc2a1588b6e83124cf8"
+ "6c5e9166860d4dd47170432b08ae6a6e30871086fa",
+ "6c008ff0e128fcec265f379eb083db50624a2798f93367c6d16e5d95a989f4f1"
+ "eed0cc4cd861c6a524f2b9fa30e886f1477741d7ea8a60df140aecf3a6ccf004"
+ "3dab92cbe72953cb1c1841e05918eced5b0f694af9a98ec7f4e2286d233dfd35"
+ "132a0b584bf0e0dcbf05119ce2e3a4d813cf028fec48c34a1881ebb531ca489b"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.6",
+ "031878d588ee",
+ "cc154e1af713f2f95e16f411175d9836ad6d8bbdc8f98cf05cfa0058235d1fdd"
+ "e04082764c29dcdcc59ebe26578bf9e8ad6a5aa86b9d62914b4cf696a8ec2da8"
+ "79f8fa4231463132ead7bb3be750ae0c5628a396b70adfa27b403423b10018f9"
+ "d24fea337030147fbfaa15d47532c9257c2c7f541b5b974d15dd1e3fd2e20a69"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.7",
+ "27263852eaa960bf7671876fc7900f898ea82eb2b0fc418565fdae62f7d9ec4c"
+ "e2217b97990dd272db157f99f63c0dcbb9fbacdbd4c4dadb6df67756358ca440"
+ "115d3e5b3deb1ba1bd90ca1286fd100caf9be485a44a3845005718104bbdfc5e"
+ "781a9e37d67affe556dca10f8efa39f9cb6392a72e3f2825811a2c05af84af9b"
+ "e7f371dbd4106d9f",
+ "94798d179478bfe06d96a34ac99bc9d5de35dc4697ac3f70e9b34c95e22b1c30"
+ "d1426be3508e622c1a18ab3c4672fe3de340eb510fb987b53ae93a59af6b00bb"
+ "aee0e82708e6c6ae82c8455324017836db17660d069d80271e1ea9981163b14b"
+ "66876dfd128f09cd2e3d6a36b73c3b40ad8e1324849029c8b8e3c8894ebfa194"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.8",
+ "a4fb2103d0be290e996016a439462e6bbdb0724d86cd51859133ca3d39dab77d"
+ "a2069d82835896387ccf3df5cdd7a5793f223f3d923ea463513531ada667abfe"
+ "f75398c7a4bc6efadd4edeef35ab8f5401e0daf7c2fca1cdbbeed3bcdd0933ff"
+ "3ee4c5e288abdf219e36a3ee6f210841a03c9e3e4dac18122482ef85f49fdacd"
+ "c502d279f1577be77a4e00b7c7f17ba5da6b28c01a07a863dfb21c156da32001"
+ "f53d7ea3fcb8c9554f075459a67cc3c4e69a6a37178787463cebcaeda6490a8f"
+ "80b392def9f22a4f",
+ "726670c9510b58354c8af32b41db8f692107c0c876e55273a820a0c30d392446"
+ "0fa5bc33dfe19d72e56349282a80fb12a8fa9ea4a5da69c582d7c64122a8a791"
+ "b3212c39e028265b8454df715ba30b003d129169cf12511c0d3e7aaecef3792c"
+ "f185644cf80e448147b1a7961af384417d182c6f855246dad5b893d9a7680ebc"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.9",
+ "e5506e04b191841076858725a9fdd8f9745f242e99494a423f80367474271dce"
+ "95a99a2f71134f39fb3f2e47c6a0b2fb6f615b0dee6df33b28f8b0d41e92d142"
+ "b146e8cde9b11d6ec1d37d71fd82b719ce1addb821ca4cafbd2aa4f1e611a259"
+ "e5f05b531fa11e3b671b7a5b10b4c8156c25b0a59ec6e158f6d346d84804fcf9"
+ "2a72768f4ebc935eee5cfec7f6e6e83cbe158a13275e84183a94d724b0e96696",
+ "34220edafd4ac884b9d00fbbfb71a4a6c4d4b71c198422050799d0c0fd54e909"
+ "a4cad2298faab3347a0af0d27d5301a886009cf5c6f125dfc1131ace388bb214"
+ "c2844420c023dbc8b4a96611b3b393acc3839490fc4ee2d369b8c3c876572283"
+ "ef34d70c6403ef9e2e87a276b23572ed82e2402267c2737f75bb4a27d3cf16d2"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.10",
+ "8fc9cfa721dfa09ba0729ef9189e5427b3e738c5ae38a2657f7c7e314a49caeb"
+ "a0fc9d4540f5f8d6c04753600ef6b9c3396540f86c1175b60bf40e3d8c845135"
+ "5e1374f43043c0c6aa41d3796bd8279b3c3062b374996b7eaedd4db0aee8c94b"
+ "93b171fc411d4dfc3728d0231558cfc8fa45f951b35c9d461218a650c702cea9"
+ "3bb3fa1436ed445c95249dc220547101b9a93eb014cd843ff39ce4c96f82a39f"
+ "863a4c2e1fa9",
+ "a26e7dbd5dfe08c72bd80d5e2668d5d72abb1a0c0420ff0ea86a9c7608c470e1"
+ "c3f72ebf445d12187181415558dd03ebe407aa06b51647bafe0c85f3d3b8dce9"
+ "0cebf0a0eecbac1228e785820c4f909d2ef392f03117561ec38eb0d88b023272"
+ "a4286351620f21043ccaf7503684002957ef79bcff9d1c201c42e0960bd96979"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.11",
+ "961fe34a212cb0e6f6dcdecf1a4cb7b214390a77f44d3a3b3ee2b12f1f0ee314"
+ "2e9eaf708955ec837ea1d0d2954e6ce950f34c8730548f2e095d5dbb938b190b"
+ "738bff81719302b6798b768b0bbdd2e2b9672d891405c771a77902fd5427425a"
+ "f04e21b91c5f39372041e494d9be62dece31bd8a262f6ddb849f068aa99f7d62"
+ "62e184ab9cb1622447d62ff6710920307071c272be0bb37f0eef645f99eab51b"
+ "0bcbbb6487d8d2b49f3f23e0aa918c89ac855653e1ccc00591580e0ce1e38779"
+ "c04be7df1c6663acd9937e472b3eb6d4b70a080de8e03548f51245be7ce0b86d"
+ "eec176e00e54bd63bd5bb02fc954",
+ "98ac477359159e93e1b336ee05606d42b7e1250d129560c0d095f8f8ea3c0474"
+ "32a99c1ec4bc887d7f07f61df16f0c09f715b705388bb8a61187346e8d7b07ea"
+ "b2fc05db89e0300944ae3773e44cb92c5cf0f4fbe01a05ad79bfaa247f83ed1e"
+ "da48baafd1e180078ca8d321d50b425787f01243a493374e84f5cd56b753d7ac"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.12",
+ "96ff0a5ecac95116bd7343795af83c87ed9f8345d03f6f322f295493f40b19ba"
+ "8ffe2c898c7b206621f72e02c7f0f00f9f1c523d73d335a26ceddc7398b7ca20"
+ "09cacbb18283b76b2815d1e90100096e95b88530f1c48c3961c435bce0289ff6"
+ "2e21bf4d3ec899c87e14c8ead7922e795e3e6f4180c0899ea0",
+ "7c7b0157f6a50909510963282f00111eea70193754e427a02b346feb682f4c71"
+ "87bb381d31d23b94768843245aad5361fca42d8b284c8d92e6fb992fa7712fa5"
+ "a93155df020d300a3bf89886668cf37bd13b550adb2d2a86c69daaacdc5030dc"
+ "84343c8b4934f03cdc0eef0f6c1ea7ec0962007903b448217de93b7507549b2e"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.13",
+ "32a12e0c670ed215ae5449a0917ae95e23db803ad28a1842edfa90bc405dd89a"
+ "1b468acebd08fe9c693d8fb105e8222eb57f79e4b22700e07f276d4aecc7a15f"
+ "b74733065627b879b016eed4ab4a1c",
+ "85b90eb826514a0ec0fc1bdc3486a8dc8b0f263efe57cf1750a42a6b5b997264"
+ "fa617864837e639f45d9205841cdc134abeacf6ee0ecda09b98d769f51f3947a"
+ "33587ff0c8dd01b7f6b24a2fbf29c9fff737eee56ada2ceb746b025d956522d9"
+ "20d12ddd13dba08b20e1eee13a8b2580e592c34e39333766115a23b9d00e2a42"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.14",
+ "bbda73cbe2bff7ff5362ebe932c0a0dd68ac84ee998fbf59a2a9265520323163"
+ "b30d9e7008b94b0c0ebc5f6c4c973c13ff153d31690c3c95ab231f0c9ec998fb"
+ "fcadc28b2d7f06507e17d21e82da",
+ "26f952b657fdb9a11dc843790c9d2a6a51c976101efb82d053606762aba33af6"
+ "280bde3815e0874d6078753842e5b1c90cf7991220fcfa62284943690c301e9f"
+ "c6e479af68b9694785be40d46986a62a121aa9ad0de969521f1cb8e7c4bd70c7"
+ "c8cd7a9d1354e7d0aa0d85d6d7aa00e4649026d6f070f8b3c27c98556beaa4c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.15",
+ "2c325ddaf6526a1ea3518ee5e5407f0390e0ebaaa5f472a1e9ab46f746d71ba2"
+ "e217faa81799bf358f95e98308270b18a0019929a288d0c956e0bf17c5198ceb"
+ "2cd9fe40d702a44e5645eca5b439abca7b2c6f95acc3c2c365195c795e91d63b"
+ "3c0933244ff12563af6622a40c7415db60a78dca0260251439538d38aa38289d"
+ "928886ab128736a6a8739c1455c4849f2d5456453793",
+ "6d1f203dc3ffa7a334d31b9a75e012581b8d62b2bf73800be51d026533998318"
+ "c0cac92a02d46d759bf80a41daa0a6a29f4fa0bb60664cacade24a65cb476511"
+ "09beec8231919525d1473268745578db9e3064108ae46a4870f18066789b0366"
+ "a7d0ce37e030b58946ec8c1a141154db0e261bef8baf2e9f65fcd16b7d5797b6"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.16",
+ "2985e8b550812fb66c18f80e6f092a945d091583861b625d1e",
+ "2e843013cd5e795e2166c8e91b06c3131dc3a5e12136d7160ffd11bbefcf6ab6"
+ "40e05d76e0c61ed306f6086bbb567ca87e40c6924d5c84a6ce28a83950bd4b84"
+ "e27fc5069fd0624d50eac24a9411b5f76785d9db5da30f425695b019b84cdbb8"
+ "25bd46e7352e08f114c87b066fe43d1056a2c610cea7e3d3dc98bf4497eb4f13"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.17",
+ "77788e838b834e8f4d045aa894b90abb85940cfc58d7725e7f373da5547137c6"
+ "0bea751e0142bf9a6f4649aeb546ed560cc4ea1562d4a5fa3eb1b11477a3051e"
+ "24c606b8a71c1a774bdcf1a5310fed555923730fa8af4c15800d362b37adf14f"
+ "7afce78efa6bd893563efe0b3b828ebd499f12a2fe332bfe46dcbb314bbdbf69"
+ "087e2a665df110835de55d61e5c2025fd8db",
+ "8e5f3353c49cbbb2ea696abb5740bae015effd950d5607137605a100c4a53f1b"
+ "95176caf349f4fd588aedddcf5060ccb72478cfb098562f34d8f8eba446a3847"
+ "565a7b8955ad9e0c6eb67099e1a46c3eb2d49d9090ae5f63e8a08b6e8f21f003"
+ "e451d250ffc5a790d66a0e2e3e28a6339fe91d112921f55d1230306fad5c0190"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.18",
+ "1d599d762cd54df70f1a0983bc3ea2bbca6fcbbd162603ba81561077fd928492"
+ "5cf1f1b08bea1e70bc595df0b343b83b9cf3d634f95e37e8d1c585fab199",
+ "717497a4e60dbffa196eff758e901ce1fe6e2bc7e1d53a3dcf6225671af146c5"
+ "dee200a814f4898d16a9b5f508dc9fde4d64070e55ae3b1fdf7919f42b7cffb7"
+ "e928c4caeb552dc6fd081834b2dc2fed07e7e627d34b3910ca713bf4154eff99"
+ "9657361518fce5a8f642dc9a18a66ede22190f60aaf958d6246b00a032c39841"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.19",
+ "da51008660b63b8767e65f12c6308ec18ed9575a426bc5fbe66010ec3f01175f"
+ "fa5741eaccddb02fce7b2ef7784440d72d3752203f534e52fcf626a8c596513f"
+ "419064bbbafde7f8d65f30d7ca68718970de71fc8c0eed4da00a4e1ab54102d9"
+ "d165bd7c54af5c31c15c05bca55b6fdd191086a53e5296f484c347d8fb945a10"
+ "c49449752732f62f34c32515588651137919285a2c8ef7b4aa0e690b0b65437f"
+ "f8d56fc95dcbc3e78d",
+ "32677228ff08c66fd03bb31f0dfe890153b3446b57eb84ef3956208f72a07c87"
+ "67e6bf09f038bcf7f735ee24a1f640a1898d409eb53abdb693942734569af71a"
+ "4cd99a6520baca5d4286b199cc67628e2fcad296a30eca499eb880507f6a3744"
+ "0b61c1284c403c41321b99053f5d69728d5b973576cf04748333d808d5e68a8f"
+ },{
+ "PKCS#1 v1.5 Signature Example 6.20",
+ "8cd2dad2a5d5f9faa07e24a96e86f9b0ac8b40222ac9fb8a8a15727cf2f53e68"
+ "4af4abdc9868a7253b25b096bd701f46a943",
+ "8f0322eb2c54052485a64549adff2a3631db6576fc0cafb551697dc5356f02e0"
+ "93cb69173a7e8355a0dadebfa53cb2907f002db3a3e387da057b7c7355164384"
+ "3ef574481f807415177e4b34c25bd55f4c02fa0adea3a9580465f358c00596b5"
+ "cc062d5892303e1acc113c3b4bc74d42e858029078482a1b234a625b04284406"
+ }
+ }
+ },
+ {
+ "A 1025-bit RSA key pair",
+ "016934cdff4850b6002cc0f0f4010a32c655e5cf6e7c89937fd755ef6abe379d"
+ "adde70cc217751f14cba6d90fe52dc0af58b252f26bf72da579fdaf57ddd6cd6"
+ "021879949a0276b4433ff01efcccf35a11e7c77b38c18cca94ae012d0f370421"
+ "491c52ad15ac76b12ecd218f52e757866e089dd8adbb48e9ba894336c575c406"
+ "55",
+ "010001",
+ "0d1719e5bd476d87c7ecc31eb8ab425d4fe4c8f5c7ae230a1047553ffb539fd3"
+ "855af5a43b2ddd4e95a2b30d407aa88159bbad2a873d8093b48a4bce20ad9926"
+ "253ed339ac3b543fc7429695338db0bc1dc3686cfd139bb5b28736bc1660a953"
+ "48fc91c325d03a7fb216d2d9cd9364de4ee7d2119c3b0fbba8a71f0d3f5ab9b9",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 7.1",
+ "3539997ae709fe32c1036a132757f2a1667a91cc83be733aada1bdd217924c9a"
+ "2c9fed1fecf61d1cf79dae9a83f8ae3f4d051b34fbb559cbfda492f1d83b8beb"
+ "a045d4ae1c8fea15b7577a1b8a3f55bac1727edca7f8f52cb4ba61caf1fa8f8f"
+ "d9aac779095ca84c7991529fb80699d0d4688dfdb142ed61a95b89ce3306bf97"
+ "80e1b91b848c8d2003970e52702a1f612e2f4017cfe0a91db9e46db9dc",
+ "00080f770a2d1f6abf5f221f62e166abd79d06c7b9a878d61b80fc4d5ba290b2"
+ "3abaab518f09447e45aee6f3bd0610244436a4730160e6a672110c01aeb5624b"
+ "718dc7c0861e586ba8b60a29d6a5755cd2cc508599c6e28d7355b27e40b740c6"
+ "fbbbb1a91823b1c1242ba693d452695147dbb23ea89cbf11eb8b07ec3a027b0f"
+ "17"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.2",
+ "318008873c4cfea7125ea6fd5215dfd98d5c5e73323f03f215c69c8f2bb1983b"
+ "59dfa6e99add306966f3110c161ca22624b88070265b8f3f9d5df72991e79e5b"
+ "189aa3d9cd9b2047cfa61d01234b233d36ac4b96ed081648877490fa4a80ec4c"
+ "bbd9d2e0062c39e1853a0c38344ba858bd1d995f6caa28bf904026268a997211"
+ "43c86a4343baf89b6d550764251fb07d167b4c4b1b70f99ef5fe50e62e5413fc"
+ "ce0f9959c2a378c41d6f4236178b14b8919db1d0",
+ "006d547da4edcb103315cb8e4b669bee96aa2156235ca5c3e31b24a15a1392e4"
+ "94047fedcb7081907c5617a8aa18d101b0532a3632451923c48a75b0ec2176cb"
+ "98e5ce51588bcf868e29d5d9694f00ae2c924e73d2e6dd144d24fa45d01206a3"
+ "f5d936413ccbb74b0e2d047d82b600b89d51594fce7de6bbd95b97fcfec598c4"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.3",
+ "7f83b3e054c024825078dd9f040e1d09058200c9757b76fb372b8b5266b9dc26"
+ "9ec7569d00",
+ "0134ee215151e53250f5a0016acce3701e2a58ddaad6cc369df0dcd9346a2b53"
+ "0fe3715afeff1e9bcb720831c12558970a9e03896004f287adb821f317cf6393"
+ "00cae6e909e91ed2a3eacb9952a7cc5494765264247951d28c16af03e24b80ee"
+ "32b0b62edf10d70091927135f05a889f2f6056b95cddace47c69f97308c0df2e"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.4",
+ "17ebc15007bb5e4af917201c3ba384926589c3159a89d1abd4c2c986fba0379e"
+ "8af12975c5d031d1bfc15ca91736f07b1766d8b8a72db10c268c98fd7aa11e29"
+ "99f06d86127cc889cf150dcc738f6ab8baae943cc606dd4d9ece701a4a7b101e"
+ "351dee20b15ebc55256db3ce46a6bd5061125b62b995e970d16f7c9a8fc157ff"
+ "68cec7e60f608f6626dd39528b2409aa2ff932fc119b2a7a81772a576b3d50a0"
+ "d287a7fa2db87d2b92e1c961a70caa44d88137b950e100711a9854adfafb494d"
+ "34e28606a27c",
+ "0105dadc99c59b5e3ac554b1b5e7480e5c0a62c7abaefdacf4426eccfe686b8a"
+ "aa1ca4f51ebabffa77d99803e7ee8d20d1204aad8c67385d0744c854de2f997a"
+ "56aaae04cecc656535c16bb2145d1801812594a8013b0eb54e7bf65d38420054"
+ "ec46dac71a125208b302214a7c9b3a92ca9bf73739c766309af803edde7c54d2"
+ "46"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.5",
+ "6a52ba190e44ca0f1070021048762f3e79ed51c94f6dc1a9f1ed78352ef379aa"
+ "49b3a9387e3ca7a196f105dcab18506f294a69",
+ "000b70e601c5ec58684e0918ba7a539e9d2dd29b01a3f453cad4a9a40e50f5db"
+ "df72c11052f20be44a5d3851b01fd09d9c9208470f0a4a95035e989eed7d6b06"
+ "2e13f4995bf0930b4a3d9b8a9ed75e33886e4b194ab5ccd6b412959cb4f5498b"
+ "d32f668546be2c007ae8de5d98977b94b17e1263884b54e784b38fc112b8cbdd"
+ "56"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.6",
+ "bbe0b9de2b5e9dcd316742943f9219b24f66a38f9de709464fa5495d794a637b"
+ "9ebc067762da7a6eeff098fa44f3cc36f2ccef67fd46c59e24738c810c69eddc"
+ "d90cc7d71a4c3e693bcaa28a533d904b41ced3399b4c7647e5ec4b3ad903870f"
+ "5b5f8d6a8d8128ae2381cec86c4d85b78a451e1ea97e3393ffe997e546b09c8c"
+ "f82252b33f745feed4133206518e2b880319dcdf9106718afb016c514b380532"
+ "65bc9879100e47b03eba0368f09e2923ac6f40a04b75054cd505bbc8965d649a"
+ "1bae7bb6643cb74195e91c51f4183db2d738ce603550d634e6dd4f27f4daac61"
+ "56cfa7e2468b5d6aeb782909",
+ "00c2e074dfbcd0e73ac0021aeb9933106b201b93c17a7bf93356d291fb4aaeb3"
+ "d1316300a8de7b07e3d779bcc299e52b6cb03088016daeb841382eb3435f2e03"
+ "ebf22dc086fb20ebe53ac54590249763a2655aa7eb0e7d3864936b34006a6c4f"
+ "a02d9ca104adada6aa01b977b6def2750608a78f3ed83ad712a7a1b0fbde7c7c"
+ "8d"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.7",
+ "83a48bff886d1d68f2920a0ecff298321a96f5cadcdfd8be16b50d34d67d94cd"
+ "b1a1bfa0eae24699b663c7ba3a08a390f7225884856794d180c546cac06e4118",
+ "012e81bd38635065bf6554336b00d10618330553e0e80878aad355f00d5940d8"
+ "ba4501c5c49f1016d5f0e6a73a4d9f8740d2cfc25ea248df3f7b1ae8fcd26bd5"
+ "62e0f6eb777f46d7573069db8907c021b645d3b24058475199a91b5572d8ac87"
+ "f83ee6af5cf9e171a858f60d2b8140f52daed68442228b4fffd8de40078d3de8"
+ "cb"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.8",
+ "18",
+ "00f2c299024ab7bd252c6946bea10dc053973898bd5f0e3c9460e6fe09d7d191"
+ "e71bf79d436caa84e986be3fc09819c080e56a085cf424414af3fc7007cf1ac3"
+ "6f1cf8635780b5568d734ad6d81a2ba8eb188b294669d871ca40e608f0ed33d5"
+ "690cc61570c5b847ebdbdcdc4fa78f429efce13c6747e54d6f261b0455d6dd65"
+ "c2"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.9",
+ "04a6e24b93c2e5f6b4bbe05f5fb0afa042d204fe3378d365c2f288b6a8dad7ef"
+ "e45d153eef40cacc",
+ "00ecc895fbd947e2dfc47c03ba2e993d1a143a7a6ad63a916ed54483ce26389f"
+ "89d580f4edbdd0b37e08caaa5a0c1e526e1e9a1a8c0dc9cf50ed77de2676460d"
+ "288dce565f128a266ea29b4ecc329a94cc252396dc50d5c0a13d809381fad88a"
+ "0789ad4f56aa77e544ec2570af9918b7f741b486ca50b3384ad1124060591685"
+ "a1"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.10",
+ "9965bda55cbf0efed8d6553b4027f2d86208a6e6b489c176128092d629e49d16"
+ "9f16fe51c4c08a6494b50073622091a3822ea57c328bd9b69d2465a2122af178"
+ "bf6b1be307ee4c31479ffd9f4d11f33ea20b7aece812cab4eedd46993151d568"
+ "ff64a16704a55d950ab7791aa23b26a0a8af880f6f8056bdd206838b44c607b6"
+ "61b4f1dc3621065fded3db6f9e3f2dc8f400efe3c2afa6c0279940576bb05e39"
+ "804bd3505f4bd28252918b28e74e058f24f27ef0db3d0dcf9eb29d41ffc11007"
+ "ce86b982e89c0375bd9976a5af131a614d2808ba25079d977f0b239796ba6b1b"
+ "cd5e855d96",
+ "015662e30e790e37868381b4f677a2aed6b2acc564491731824910ed80adc477"
+ "159c88618cc7d0beb049b1aae74b1721e90ba7f7b0ea26bf33ad04f86ff31438"
+ "97bf0d4eb45eb7deb54411ba9680aab13adbfcf18af46b87fcb1461c26206a95"
+ "3bc3cdbb31e296ea09024bc5c7b62de6c69c14bfcfeb56391a9ef58cd805eb63"
+ "1f"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.11",
+ "71c7b18b4aa8ea5389ad7849232865be2a93e347a168d25c6c6ea2439c1cc80b"
+ "b0b7223be9c8937122845bb0a39c025c43759defe6e4e8eb3baab4f1ebdca2c8"
+ "ad12a465a30f8a6525b120ef6aaec9bddb45cd42c0150c407b048edf65199492"
+ "f207ca01aaa5543af38ee98d53bd10d8eebc3b64977e75751d7450ddb1c0e1fc"
+ "24da1718811fbe9b0abfc3ca31e6995fc7349073e217b37e23c5f17a8b7a3f00"
+ "486a3702b9510d6f051b2761716e32c62bb5939b2fb11acb1c83",
+ "013ab63ab183353a235fb893ab4c35d6409c21849dcfcda3bfda1429fee742a7"
+ "d8160fd3c83b3853a333f951539bb5771f4d0fe13adeb64e4030b92e8b0813eb"
+ "52b1aa33bd94c5b8bc1bbccdf6c1df0ba670717c0cf6fd485be2fe9e16813be8"
+ "cdd580e61086675e31831c924a41d4671a95d835e3fca495e88658d1e570e628"
+ "c7"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.12",
+ "0beb19b562928c271bb706189e43cfa57be76b2f7a83e02aa2ccb037c0f4f7f7"
+ "3162d6c26f70de971821e7b9665cb931bb0eac820bf859984db4beefef4ab88e"
+ "91631c0cd31db7f9358a5aa1dff2406b45f9bdcbef20d55c282bae5cfb610602"
+ "3b5633c051af17e729bb07c9af6dd2",
+ "00d63da4d5d3e2284a192a6a9da3f1a7d3fcc164b9fc3dfd7452b02fed6ef1be"
+ "5ad2a769ec9c36059b71911ccf7ab71ce30987ec47bbf55e6d4630d62342b315"
+ "5048ee0bf43d24fe69abdac12f794b6798bd1a7cb489a64ce082254c3d92f475"
+ "566b56400d9620cdfd63fc17c193c425d7ede941f76da1e345af0e2a8b8844c7"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.13",
+ "0287abe2670a45f8779048f5",
+ "0042f414782df65d9347bf1cad534853746cc0b853c1c526f9171445fcfaa499"
+ "1a70f5a8445bcf4114f07fc8354c84a93b943733d3937a59883b896ce65fdb16"
+ "5b1e3055374ce242e1268c1641cc443bb9e7da7f71f3e7f6313f239e6200e79a"
+ "1be3ead6c36e941f24460baa57df639e57dab3eff9e77b87af355b83dae77cbe"
+ "06"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.14",
+ "3f49542c0e9f50932c0d453dc95320af21dd2bd1729c29f4f08c70944c2cc75d"
+ "e9166b4fd230aa93702c5f2c3d9c299a359102570033540eb828cad75a5776d2"
+ "e8cb456141a6fa97bc4e6e62d3df082982a4d98c2de441e59e9312",
+ "015c3993ceebd8dba45a368dd405af8a53b93e827019f994e4ed782c3911b9b5"
+ "80d54224269b7997f1749630e52f221fafab9641c781e7044d3256e2e44e1437"
+ "917232694518ba9e7138da47fe534329b8c9689e2785c02b603dd160d37336a2"
+ "b05be04782659ac0e9671fe932ea8091d61318b2b201bda79af6c0c4446938e3"
+ "f6"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.15",
+ "d0dbc96cf9bfb1e3cd6de2eaa08d6d795bed8187ceb0856580e4b142b9ae60a0"
+ "98cd42984e8dbf1d05a0c0ab8351548f0a13646f33390b2bb0c864b397cf1337"
+ "1f8b2f675a82e46bf16c4afc605ee3e5a1469cac51fa734b4465d4c13d5b2dd1"
+ "2eeda54e7d081cd9e3eaaf9e57db422020a0b5a5ec28ca43977a5d676ffab62f"
+ "78107193594159cebfbd86269819a0f341a0f41284dd0a73ca8014d2e0b80179"
+ "c6380b403afbb11b42db349bafd7570fbecbd14bd0c21ad641687a6ac32925f7"
+ "031a24a6568ab9e287eb80754110dfba688a596325bcac4a39ce8b84a4",
+ "008cc82d64559de0040f5541199aeff3999fe2f086f157ff51f2220db345519a"
+ "a114b01762e70bc96583bb38b22b3f87beab32e23a3debdb8a595429ff12fad4"
+ "95d74e220e4f7dca22272843899e8104c69a59642f6fa825890fe8132a0f7994"
+ "0253e5007fb1177a5bf418067eddc8d32c5e5935bf338f1c690efc8011dc8c84"
+ "2e"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.16",
+ "7df0236e871a71c31790eb5f011c911c27c60373b8dc9ebb13ac85accb3bcbd3"
+ "b474f978862dd84202ab20b334739425e1b79e0bb8b4bc47dc7153f57ada0412"
+ "447bf5a5e6673419baad653e5f5c39e2ef7cfe7ef4778ab998caf97ce16c5833"
+ "2772dddf826f1eec1af3db80e31375d6680aa254b4ab6ef9a3ec0e0403e4b583"
+ "d371ddd96dd57b2c61a6e401251a1a630d1ddcdd84d90d82faf5a018d2a88e26"
+ "5855e9d7ca36c68795f0b31b591cd6587c71d060a0b3f7f3eaef43795922028b"
+ "c2b6ad467cfc2d7f659c5385aa70ba3672cdde4cfe4970cc7904601b278872bf"
+ "51321c4a972f",
+ "01455e3bb29cbca8839b9f544d51472ebcfd25c29227c4655d5f7ebbd83c48e7"
+ "643e7b594d6f7cd5f6bf9a40b05c4a05cbee1fd659d3cede3e7cad61e6fdf8f0"
+ "e4fdef0812a853908f0f99ca7e388ebc19e874765b11640f1ee1e98f54953de6"
+ "176f1582037017c838609a57a12acbafa6a56547f57d62dbe87669edc0fe3baa"
+ "da"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.17",
+ "1288c03f95006ea32f562d40d52af9feb32f0fa06db65b588a237b34e592d55c"
+ "f979f903a642ef64d2ed542aa8c77dc1dd762f45a59303ed75e541ca271e2b60"
+ "ca709e44fa0661131e8d5d4163fd8d398566ce26de8730e72f9cca737641c244"
+ "159420637028df0a18079d6208ea8b4711a2c750f5c0a425313df8d7564bd243"
+ "4d311523d5257eed806ac8c9c6af04ac",
+ "006bebb96f0e282f1b4d03e6c56505b93778da9f493650e8aaeb65cfe6285004"
+ "2f75abe6e6eafeb9a70abd21eb5dba73cbb87c12980aacdf16716b1998c9499c"
+ "e439c54aab4d19ce727b7875a41a3d30814e508daa26eb70aabbd0dcaecc4d4b"
+ "51698071511eb31b210e66dcbc7fc0b8c62314daea69d47ae278100deb514092"
+ "00"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.18",
+ "5413993c2658bc1d9885",
+ "00bbeb2ca0bd64cb8960375b08a9480e69c09fd382dea2f94089b1533a0851fa"
+ "0cbd0eadefca8c70b770797ad089e840d2fe1a8fb8549f3290583bbb81d3ee2b"
+ "1c48f1ea751bf32f9590be3afdb7745e166e0b322c083124e645839482d08126"
+ "22d31ab1877a9bb41b8daad868f30e7507832ac3410112133aa17b2d476d476d"
+ "89"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.19",
+ "9c84c1486bc12b3fa6c59871b6827c8ce253ca5fefa8a8c690bf326e8e37cdb9"
+ "6d90a82ebab69f86350e1822e8bd536a2eb307c43b4850a8dac2f15f32e37839"
+ "ef8c5c0e91dd0afad42ccd4fc60654a55002d228f52a4a5fe03b8bbb08ca82da"
+ "ca558b44dbe1266e50c0e745a36d9d2904e3408abcd1fd569994063f4a75cc72"
+ "f2fee2a0cd893a43af1c5b8b487df0a71610024e4f6ddf9f28ad0813c1aab91b"
+ "cb3c9064d5ff742deffea657094139369e5ea6f4a96319a5cc8224145b545062"
+ "758fefd1fe3409ae169259c6cdfd6b5f2958e314faecbe69d2cace58ee55179a"
+ "b9b3e6d1ecc14a55",
+ "00e6be96e18dcebf8388ba82ec6f27105bc27871595e01705a2b97a1f4d78838"
+ "352b0e7c0a2c627a6ff37db169a9a4648ad27af06533a4f041d4c820abf4fb52"
+ "6464081434df36788503c65af762aa219fb76a91cbb40e1492a9cb77369bb4cc"
+ "a1934e3853de6c86a5dc1148edeeb3b0030414fe3083ad72fe295c29b5ea9b66"
+ "60"
+ },{
+ "PKCS#1 v1.5 Signature Example 7.20",
+ "940cdab4a3e92009ccd42e1e947b1314e32238a2dece7d23a89b5b30c751fd0a"
+ "4a430d2c5485949a2b007e80978bbb192c354eb7da9aedfc74dbf5f71dfd43b4"
+ "6c93db82629bdae2bd0a12b882ea04c3b465f5cf93023f01059626dbbe99f26b"
+ "b1be949dddd16dc7f3debb19a194627f0b224434df7d8700e9e98b06e360c12f"
+ "dbe3d19f51c9684eb9089ecbb0a2f0450399d3f59eac7294085d044f5393c6ce"
+ "737423d8b8",
+ "0080e2c34fd4ab4d1d701ea3f085763acaffc9fd3ed918d04bffee1931624898"
+ "c78f8941bd2a59ceb5b840f0114516ce411fae752b1b8a221ffca7a68766c697"
+ "c50a3d88d8d02ffc1241d84bb7a7227f3d05149e15111277a136a5b8dd96dd4b"
+ "225c5f49cdf6071dbf71935c7a6f1e2e9af3021c0d58a9b81c9bde61fa472c07"
+ "a6"
+ }
+ }
+ },
+ {
+ "A 1026-bit RSA key pair",
+ "0333126488f7a2915132e30d5e97f6ed7bbb67b61985008eaea2a5dafb96a448"
+ "ab75ce3d6e68a6265e7c245684999324c81e0ba6389863feb488b3f255d0d619"
+ "c19040b74c189f0c9af4b0d5a55a544c090cd6152c90a6f2550d7d2a6b6d347d"
+ "5b1b9dfb1de4403c796623d703bf9db443bf6702683b8d2a9c61e9368ac425a5"
+ "81",
+ "010001",
+ "014a2b15dfa8831db4efa05b195084b742734ee136f4483f3be2509d2f619023"
+ "c30a1ff2df78cbd117b14f2c9913171f7293b9fa6d41f0bd11a5317474675486"
+ "d7f0aec0a778ba920e81f564d15930cddee7e2b06ad8adb612751f4e384d6f3f"
+ "a0a6639fd62edf86f52c9fe0776291832183d359b7343260c94e125f4ab8bf43"
+ "69",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 8.1",
+ "9a2820f3b9029abc1865eb06fe61b8d397b65572d60061caa74e6356931e256b"
+ "89712d186684b4de1e14c9ebfef16e40d99d1094396c561c883177e5126b9be2"
+ "d9a9680327d5370c6f26861f5820c43da67a3ad60904e215ee6ff934b9da70d7"
+ "730c8734abfcecde897fdd670a01465868adc93f26131957a50c52fb777cdbaa"
+ "30892c9e12361164ec13979d43048118e4445db87bee58dd987b3425d02071d8"
+ "dbae80708b039dbb64dbd1de5657d9fed0c118a541",
+ "0322d00fc1d96694f36eaed2309056f3ea1c1cc22b13b65e79118d202c42d161"
+ "3099380509da7435bb579216fd5765066842e356a6416fc842a24a9ea1bc6a90"
+ "980523b428e399bbd6fcdc2cb771daf0037a2de8c7649bd53317de0e37c314ba"
+ "b0c437bbd798dfb965506c348b742f138ef1d1a203e051e34bdd3a30e0fce1ac"
+ "43"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.2",
+ "ea9a1a04b7cf478a897a708fd988f48e801edb0b7039df8c23bb3c56f4e821ac"
+ "8b2bdd4b40faf545c778ddf9bc1a49cb57f9b71b6d48b2b6a57a63c84cea859d"
+ "65c668284b08d96bdcaabe252db0e4a96cb1bac6019341db6fbefb8d106b0e90"
+ "eda6bcc6c6262f37e7ea9c7e5d226bd7df85ec5e71ef",
+ "0268440939996ae5cbdafdbca86a7c428a04b578fe2dbe5126a82faf2becff09"
+ "9ac60cb81b117f1ebf4204fe4370548d5d2c468063682da87dc80179bb3bba85"
+ "a148ae2de7dcb494f476221df8219d4aae1e45af65de334a1a6dc1455286ae09"
+ "cf26725885e774809972d7819805fff5a8c89d37376450739249f57eb151b71d"
+ "c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.3",
+ "07df586b905b23b91af13da12304bf83eca8a73e871ff9",
+ "01bfd915ff7780f14ccc55bd0306b3aeda5b5b5955a826d4526b0bc766154fa8"
+ "da59560578ccd4882fe97092fbc736fda73ceefd103894063e93e22a7b5c44f7"
+ "a85e3bdb96719a09374303c91ed7e22749fe3c4d6b96699d507c50adcfbdfc13"
+ "1d6b5f2cf1830e31eabe39aeb517969c94a81cfefe6731aa2cdffe28c8af7140"
+ "f4"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.4",
+ "500b8777c7f839baf0a64bbbdbc5ce79755c57a205b845c174e2d2e90546a089"
+ "c4e6ec8adffa23a7ea97bae6b65d782b82db5d2b5a56d22a29a05e7c4433e2b8"
+ "2a621abba90add05ce393fc48a840542451ac7cd698d84b65128d8835e3a8b1e"
+ "b0e01cb541ec50f1036e008e71e964dadc9219ed",
+ "007ae0cfd7f4c6ad1ff84b4a606ba1c4798c2e499b045b567d32634fd955f268"
+ "260ab659bf5be99e0826eb3870e8f62f5a3ce758e6d156c3299b431cd9dfc658"
+ "37ee94220d952351148799be9fcaf9be264daebeba2be86605201ef9a0d98f58"
+ "ec638abfc4f27848f5d479d334acc2a97fdd2d327ec4c7ddc5a8abd566de35d1"
+ "4f"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.5",
+ "6b3f6a63d4e77859243c9cccdc98016523abb02483b35591c33aad81213bb7c7"
+ "bb1a470aabc10d44256c4d4559d916efa8bff96212b2f4a3f371a10d57415265"
+ "5f5dfba225f10895a87716c137450bb9519dfaa1f207faa942ea88abf71e9c17"
+ "980085b555aebab76264ae2a3ab93c2d12981191ddac6fb5949eb36aee3c5da9"
+ "40f00752c916d94608fa7d97ba6a2915b688f20323d4e9d96801d89a72ab5892"
+ "dc2117c07434fcf972e058cf8c41ca4b4ff554f7d5068ad3155fced0f3125bc0"
+ "4f9193378a8f5c4c3b8cb4dd6d1cc69d30ecca6eaa51e36a05730e9e342e855b"
+ "af099defb8afd7ad8b1523703646",
+ "01921f22f471a08af819a952e18368ce15f9b064eb1d00b12899780244fe8c44"
+ "24b21f64350b9226fe95ff54f11439839bfb54f939c91495e4f027901897273c"
+ "fa295a57151f4e911dc102a77d958b622724c0fd3a34b3b7befb8b8cd0666e81"
+ "5d0c07f2ecb7c4dd2f42b7f4091312e3d7b2df267887e0aca70b541c4c1eea16"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.6",
+ "9329a58090de8be57c42",
+ "015ce24a6f2b373a19997bb20c18ac659f1edc0f25c9e5bf76d569996520c280"
+ "efdcf15e2d63caaff6c77ae03897037a0615f9838c52104e972518e290fac38f"
+ "63247530b4cf61c6ece3429b530781cf34964f32ae50f10934638386d3b4df76"
+ "1c597d4aa7feca266c27f8ce66ade1be2659ce142ba5f935883c7e8c9b8957ab"
+ "f2"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.7",
+ "6ace0f1e1dc63e394a061f522a542fbe7120254e36e9f65d1957c95628782cb0"
+ "368f3c13dad6567179c1ea24fe835a266385e4688317b82b0c3fe63cf2d52f04"
+ "ae8a38a57559bb95d9ebd5fe8a9afe1479909eb99e0d3ef3f312e0a4abb766c7"
+ "e2131a5ffb483183fbb42234d32e581f595065c4898261ecd0ae572c221c258d"
+ "e950a40801ef796d4dd0040645fc534d8e7858234838ed12c68740c14e371613"
+ "f0046176bbb0f43d997519c40c671496ff350a3fdf429cc22f464f435f6b29e7"
+ "e1c30ebd505927d4a096587fc38d3d6494391e",
+ "0273ba2c502b3f2984c548d9f7d6c9b3d7fd460878c84d6be33b28106e15fc22"
+ "17eff741cdc266834beaa86da405f3cae606cc61f2547bb922920345fe8fbb5e"
+ "7b6abf91eae8c42660645025cc7fc07a534b76d37875e3f40d5270c10ef46c7f"
+ "e45afabcffae2a9c9411bd04d61d4c0e5ffc022cb36a64b7c3a8c89bfde436ba"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.8",
+ "fdcc0f1e5dcbe5016a6b0f8c28f5b331ff582837138dbf62ef7ff61bc1a35396"
+ "c92e3d548d399e350a3c6bc2fdb5da94b986a4ce6dee104e9f274b152558bfa7"
+ "22ccfdda3b26b9f8e51525f381034c51fdc9f7912ac927d1a708cc2dbbcd7ba6"
+ "c031b011cba8e2df8fc9b88364ee965f24270e4348623253cb9e59d6f7940909"
+ "94a7a4c9300270b57f2439ebbba4658467afdb7fe86b4f1aad1d3d3b2f",
+ "00a7c450b30b2ecb19bb709a9231cbfa9f0d61697a26b90a96d91c24c4da70d7"
+ "b00b5923c8e12d41094b705d50c778bbdacec660d5c15dffd3a2478fd9337080"
+ "dca16b9c13e6233b8292b2fdcc29e9bf3b21a71878f34ef5eb7cd50ad4120372"
+ "5a0f1c663f7342ec7c3df3d5aa51d058dfccce5fe69d363b4284320879e86d58"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.9",
+ "2d1fcd1766f7d45f29594f9d4f743941ae912a97911ffc3d65dcd9656010773b"
+ "b0224ba6df111b1c1368384f2492fc4fa7280c066514ae84f7614563d9052ca9"
+ "4ef446a31b463bd6c25056805088c1d31abaff5215f7a8f89e7b64f2",
+ "02c0e071e83690dc14d9a37d61e0afc27df978039da601ca2cec1dec8f0d17d2"
+ "ffc450e678380a025a41c746118f58364252a122539eccbbb4ab3d8d377bdbb9"
+ "11c58a4cb9462f36dc389248501bd08f48e3533b82591a2a20cf62df5f5a1f84"
+ "ea300cb39457137141ad8cd1d185abb17ba5d03be348c06797b09558f0331c24"
+ "b9"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.10",
+ "4f469ab79cb893a53c0ee3815a8bc087eb74ea36615bddc333dee05fc72665aa"
+ "6d0bd59e47229829834b1f91c9cd81ce28d68f14825a345f3a4f38a01b2dae59"
+ "100764aab990a850b11c13d5dfe419f1d920d00cf13bf430e4ca8287989beebe"
+ "da3e5d4036028c8ef9546e350150d196f00560bae1472299e7f4291d544629c4"
+ "f652e35cde4f803e1b3ca33809515ef23d254b8e65202a14a411b1bc315c5ffa"
+ "ecb8211197809dcb5ced682c09f67e41d1602c",
+ "01712964ea9ab970295b81b0fbd8357e54b936ee8772d8ae9c9612716fcc2fcb"
+ "784ca9abeeebb8fcb68982161cc74e40c7c02247c0d00e03bc8e1a7051b87c90"
+ "dd7d3dfc95e0b3c88e7a0f37f30e1bd5fe8b6eee465a0b34cb59c64ebdb57d6f"
+ "5fdff2e70bb19c60d988ea956cdcdd1be562f26fb37c34da52a9f911b9974381"
+ "2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.11",
+ "52bb76c9ea265d6fad108372ffab2503bb20d38d37df199254a2f6de0c4fca7a"
+ "730336",
+ "010c553423602260158a17133b5d30efe98e9aeb353bab3371e491cdbebd350a"
+ "0a470b9dbfd18933511f0d0e3694a8ac4bf3f5b6eb9bf71c23d94c2e64beb7b7"
+ "c72252ca827bd0c0567ba8a10a6d3b7e187b0fd8e9e95d4fe480f250dc7f0342"
+ "290e9a7d32703a7213c65213aded455754781f3db73e79e3d1ba6af7f690fe81"
+ "73"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.12",
+ "5f597a19cbf51430d3c6a247a5235407386caed0a294f3f41f3f378250d4c5a2"
+ "c99275f95544ccc1d77e5c151af13ed60be522eb8cabed89a9b45b09654600f9"
+ "fc751e8b12e67e52",
+ "003bd4aa9081fe7e9f69a269fec8c8a73670c037e85a1f36fcad74e5b52d710a"
+ "5a18ba095b9810cc6937bc76340951e7fed75b326d0a3b0f26c29cd5eb6415bb"
+ "f7e2dd60adf6a0e61302dcc660cce910408b4f99a440ae2ad6c30772c29a9e7b"
+ "3280e2e2939aba0b54ab022aa3295022718cd3b787b1137990fbebefacec8cb7"
+ "49"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.13",
+ "840cc900cb4b2cb67a304a9b02826db0d66736922e787013d6bf214df579ff0c"
+ "f4821f9b",
+ "013b6c080f68939505e187a49482c791278da3ad4a747c4f01791b924805b682"
+ "f649bbd80dba12fbbe5940f17f27e75d42677c4cccdffd0048772e36934c6912"
+ "128ff903afea5e1ca8fe9424fc979b2187987698a5c5a75e7d7070a2a674852b"
+ "d805bf13bbd1296bff1310a6d6ed45fdf8672d5241e74cd4c41986e43625500c"
+ "23"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.14",
+ "c6417194133b5f8ea63d95581c896f5b9ef3d87cf66c0291640f350a325b4911"
+ "52e9d1430d6870346e468e719945d4e365d001075fa970f2a9870a1c65434ba1"
+ "7002412acc4cc74d28b2dee29b36e397b68c5d59cf677c29aee793a9300b7bf4"
+ "c673b3e0b603a3611ca90244ff087875c5168857cb92a95aaa61dff3c212dc62"
+ "06f17147c44b9507d5c890758bb35bb72a2a5e9d4db265e5373a5b3402904f0f"
+ "1a1205d5bcc59025d3220a5de1b182a84d30412b8426d46932321b57ef72640a"
+ "dd2ceebf5be968436bcd1216907884823293b010ec28f0d9",
+ "016047caad6c47bf27d0ccfa0341017e565e028cf26c8e660f79e091f350ceb2"
+ "aacf92f7d01d373f7155119c072917f24f01bf747be2dcdc41d1be588535c2d6"
+ "ac1704c5fb16f6e5dc4bbc8453f521db731eba7898e6e5212b80ce9da0f15628"
+ "189998313503dfd44e3d69de9ba9cb5eb32ac41cb8e3621ba1d291d0c5da249f"
+ "15"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.15",
+ "a642f0f70b4bd3b54be220119a7f79",
+ "00a0336e6367527bbf13b0a933b631c72cb33eabbc292a0f8f75550c2230fe82"
+ "57f2af76d543ccd107dd2c8778d3ac8a7b5bb4acfa57f2af6a231495235a51da"
+ "ddb083e373b777a95cf9c4a9b6be7751b65feb623ab334433654b1210f7f782b"
+ "1725c6ba4ffd20d17ed4b6ec4a3af64bd2734755b7739eebf418f09d3aff289d"
+ "13"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.16",
+ "ca16e43d9c82d9d30c8fcb4022933cffc7d74caa0df4863509318edaba4e0d51"
+ "99779c03504affa27d87191b6bf686a84d979a2fdd5b8a4c49321445c6f75d25"
+ "235917adbee2a5cff8a97aef78c009221011d83c0f9d37160875af7367718b10"
+ "eec3b42990e643f63707cfbb30a7fa74ab16a7ebf1c838c3b22637b63ccdcb6e"
+ "b34c62eba9e948c7ac9030f0637729d3e2780ae6be4d2faf346c1163d3f98248"
+ "193a76399fb784cacf68fb33c74babc9ddb627520c0c6112346468cf20a8e02c"
+ "c9a9bd27910e83297b85e857324a0100f5cdd5931b6a6de05f94833aa8610a3a"
+ "4b08a5a39353",
+ "024859233fb9db7cd141f4b8776a1d83e103db3ac94289d36ef40f5e6e63c312"
+ "12afdddd1688c2c1c8d4db04719e1c6e8dbf7d60be25f1d68887fdadda3d112e"
+ "3d0d24c0cdd7988a55c7102940082d1ac31fb3efabe7c288cb4ee72a992ac96d"
+ "1edd78ec728273970a796995c3e2a38581e22803258eb4cd9da2040faf741c54"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.17",
+ "3baa7e9ada2143f848825d22936704d1c997b2da76769c986fa152b898aeb11c"
+ "10b94579764f9dc933652a8103670476958d59867ab24a971284056e99c648b7"
+ "7e7a653644870fe4c7cef37f9001604872adede16aaced8aa5df42053304e4d1"
+ "71120d7ab3ce81a4d1a27498d138018f6621bdfc1d53e7f3c1a5aa5d62b09a55"
+ "4a56f1ed4f385a0768eaa2da0c9f5637034c2eef58cc35178bc2a6272cf529b6"
+ "5adf",
+ "01e63b86d0c15999093d4428af7c6de6480745d819e429623f472b45de61aa56"
+ "7b60d994792a0d1165805598f4e21fe613999a96225d0bba98f9cfbee83af585"
+ "fa078439a742515ae218ec31f8d508f29b0e5875fca8f04f11a1c82f2bb0ae52"
+ "8fdad3ca5075bb3f41bb5783348133fba8a0b3ad951a1a649ca0f9758b20c870"
+ "fd"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.18",
+ "7eb3c98e46fd1b5c9ff1b11be1619b566057f26c55e288f4844ccd50baa91b03"
+ "8d6095836f771fc1c425fb533ef2b1dc4a3e949bb99525c28fe8a3e93178f3a0"
+ "ac97fd5daa81b59286188e17b44b3771bca855d85f3c4d286f106810f4e522ea"
+ "05834f11a31e89c35990c51b080c03a661e3d4a1b97a2c27940f5b2e412b699e"
+ "a610e8996ae6715ab6e20969b6aa54cc72319dfee63bd2cacfd0608d40e2b403"
+ "95fe55dda5bea3b0f9b94b5aadc098dd568da395db2d44e4",
+ "015cfad96e4b57d9cbb578c79074a2ba869c06028868c5a3fcf4a5e361831bd8"
+ "c02c25b12b90234c8ea4822fb65e82d091a90f89b6c1156e4b44d78d32a64737"
+ "d61587c0ce3f4b343e71f8f7a84c6f8fc8aef8f464c8b359e4fb18adc699c5a0"
+ "76453755930c5f6fa7071f8fecb8631aa414f50835038be7ab05a4b050f3f56e"
+ "86"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.19",
+ "6a45ee0b7ea80368b2c429af288153f456cc663217a8ffcd2aa05c5d322db757"
+ "56cdbc0f684141fe6bcae189bf24de1c8edd5b113644a4500d0d4ff580083640"
+ "e12a2c95de69e9596bfb1d44365786e167d025d89ea2f8d13a0e6477f13b85bb"
+ "dcf160774b18258ca0bec0bd7bf13911b3896b4889fa3de04ab26bd682b4ab43"
+ "7c0c17f353a23a43e92e20e7f820694e403aabdd5d196e93895b479255df4030"
+ "ad8ce3a53d1573be226d81aa18e4858957a2d0a3359c2e7a",
+ "0164f0dbcdd9521186a28084a3f3ae6aacb6596b856e8aab2e72a7f233d62d2d"
+ "3ef196d3787e4b045731da9c6150ad9d5f918c6b06c92a11a0bfd5efccb7b03a"
+ "0107241439d34d313d35b36a0d8ca0813c3623b2bd78f2e3a97199648da35806"
+ "ffc58eed33ac9fcf79538fa88915b1a5758578b9a2db013804bf32e7a56dc724"
+ "37"
+ },{
+ "PKCS#1 v1.5 Signature Example 8.20",
+ "92a4b4bce3daa0a7a64b72ad871f3aa8eab5ac4011aaaea2ceeba89277c64329"
+ "572626c956884f4854f8613d22518b14f038fcaf9e68e13002fb0a00a78cc2ea"
+ "5144fc131176d5e5d67e106a99879c",
+ "0124fd8b2acf2237fc71a2ee97e26a4dab7dea829e15beb2f8a73791a0ba152d"
+ "a5b06adf341d7409e8d3d3175b510134325a353297a8d6d66c09700322eec5e3"
+ "3f62486a211130d74c70dd925df8602ae3c4c6ccaf93cc9a970d1e853260eec6"
+ "9481c5f1337e9dd3aeda88d88299be08095b715a5b2166e617c926722cedd6ef"
+ "34"
+ }
+ }
+ },
+ {
+ "A 1027-bit RSA key pair",
+ "05f3743488261c6f0625e432fa6eb87fb12b26218290bfe396ba76ea4261322f"
+ "8143e4b4ebcd5d2ae19b0f9d8dcd2fc7e6823208a751833d3b4e8e387c39f8ed"
+ "6bbc9fdaec32d3ea9abbff574723f3f1229990963ea4fd9fb544f64290aa2ea7"
+ "da631191a20dbc9423b461233b937249f2f4ea10928fae2a6fe664f12c0923ed"
+ "11",
+ "010001",
+ "014cc3263252f8c4fb77cd57a1420c04c043278a0c45e7d42379493e340f9cf1"
+ "a96f96063ab759d1630406ae286a1834b6d1db71ee722c93745fdd4ad33faa72"
+ "d89351da691a7d0a71d2c55c5797d2ccb3b4626208bc5f5c84fe432f664dc30e"
+ "de0963e658452b2ad5efa4935a122f461d1eab841c8ae0e6e82fc1fee85d181c"
+ "bd",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 9.1",
+ "82e5c5aae64e608b27504b91db",
+ "014582dae935e6b2aeff7d725089dab058c678b2ee28bcd444a72bdfac31463e"
+ "18e94d7b5ecc84a431696a1cdd79f9c08c33e1d4b322dd277b503ae6e4f9c315"
+ "305b4372fe45fe4a7ebbfc4ae590fa3c520bf828158f7820299f09b134ede117"
+ "b672a1eac2f050c044b255ca8d4552d4b5f3f57b8734db2474500744a5337500"
+ "5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.2",
+ "77e0fbdcd6e0498fc5684ff13d4c9f5b780e77e2464637ff66eaa2d7d9c3defb"
+ "9b0e3a383773db97a4fb491beb2114fdea2c2a480ffc219b796ad805d54fbec1"
+ "7dcb34b1da1796cb9cd5f2416ab5e766f8e006918ebec1822998a28fffa6230c"
+ "078726fba2e4a7b0",
+ "059327cee726ffb603e8a9fcd574aba9cbdfc36c0aa66fcfe3555cf2ef3582d3"
+ "220df9d6bf8a78e3fff0c129b3abb3dc712112a2056bca08636554c1ac57df87"
+ "f3664152688c6ac72e6b88f5637cd73f166989c82909fb67bc1fa2e2d523e51c"
+ "918f2bbec1d75202af240a61cd2dcc555caeae9a68570d77810cf1df8123ff41"
+ "c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.3",
+ "0dfa5baa1cddb834707a5f8cc6ece571a7a7fca5676362d2b23741a9570ae263"
+ "8f6b1c2389853675ccc6cc1b4c6dae23cda71ab96b5a2f22145750433e2d6ba4"
+ "276ac1ff9a48afc9f312f4133785ca5af3746674319a6757a164e34d1498bd55"
+ "30902e321855e3bed40881f00542256aa21a42fc",
+ "01d1954169af58993e14772a94f19bc47924ccdb2e90ee4336fb6e08498af4da"
+ "2651a2b7836c313a57c861b55184ec3b15fac8145351bec5a7270a3aa8694db4"
+ "e9a92cb9327bb7a4f7b70d244eaf9ebfa9edfd4d54782f3f97262695b97d416e"
+ "527be4ea2deffe6eb5e06cda6f0a7e416677ac0fd6f8195d4ce28970d2ca411a"
+ "2b"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.4",
+ "167e79568c7736690c3bedbbc8d424eb536a12855a60cdb10f94ba112317e917"
+ "a1b7d6fcfaa3438d68ee09fd47",
+ "029a2b908614ed7a5fab72f2a1c8e548b6f8b8b45b7581fd2451fe45a622fa0f"
+ "08dd0ba2e8f3c417201ea0277910184f376da803fa72c50d39be2882526d1e85"
+ "df9ab17975764acfb207366f6cd2c8b136a999daaf48f1c08a9ea1f08425c21b"
+ "654180da4adf109b4bc5b817dd67bf7daab4a384034ab4ade694898cfc272ab6"
+ "53"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.5",
+ "0d03f71284f2e483242d923fd1e153bc160f0cdc2c0b76f1bc2cf7d1be9ccc7f"
+ "afa6afc39034018409ccfd1628a70b358333bd96eed3adf3142b1760bf8a9bb1"
+ "9ea2473a2ed85c91cd5f0a5f2d4632d6176419fa1d8cc88b6708477711ea4958"
+ "a83901fef284f5a6c502798c8bd0a350f2ea83ed181eb970d30b78134c8e1d64"
+ "f0d1495b7017245fa69bd57427f74920ba0eede9cba34eb22276b0f27413ba3f"
+ "0da8ebdedb9b0c800e44481d01e6bbb0dfebf9a15ef6a7020b2c55ee02791179"
+ "6f66f43dd846021f8d6f7e01bb802bac09fde9b904becf9990e684e6569acaeb"
+ "3cc64dcf5d",
+ "0422791fe7b43e1f319ae67d918c5987e6393681a1861c1e71dd6fce1923710d"
+ "bced4301fdcd4aad8f4fc27dfa02a94d91bd96200aed8b3c5a96efee7d11af90"
+ "87fb81905c5df2c24ed7ed63d5fc22babd6b9e3b57cd25419a7817e93616e934"
+ "54b95853fe5204b58c098b46de0b3f01f582763248c290b9e80969652442a4d8"
+ "e5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.6",
+ "4aca963f14acf6a79c51081ef257166671e3b45fee312407ba3cf6d711aba1ae"
+ "25a4a8ba454819a3912a312e990f1fa74cbcb72777f1c7c663a2d1cdb2c5c007"
+ "4d4516f48717de1403e8ff7d0f9de7c7c851f3e351168ba6c414bed5d42bae52"
+ "7b724ceb834d79bacf702c56a623c1688087dc9de9538ea7c7c761cd2fd578f0"
+ "dc3f552ffbd4afc7f4ec7122fdec1a3a2b104d532db81cb9141854d57dcf54b7"
+ "5601a905faeda65c2a7a7bc2b029ad12dd7a6ad1b40be04028b4b5b63730ef98"
+ "4473f0c482148993c36b44e54be9a5f234e743292a12a34bf2ff73b7f798",
+ "042643c03ada724e2dbb19cc07ad0e752228b9d36f653c6a9c0c29356cf4c3f1"
+ "ca193776d5fef43fc55417716669de9ab2addd3ea88a90ae939a5eb11013e228"
+ "ae0816eefa4dd42c6c08c878bd58b49040296a863bfd11285f8bbd315be16d2d"
+ "65d7f5e5f26aa97147f95f5ee36f989aa896d7f9f1b3051f824244f90596723d"
+ "11"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.7",
+ "a75a4580",
+ "004fe4c5d9143c851e46167cc181575c075e69b981f9c103f9d9b011ff8b29ba"
+ "55a43187ce8777996317a03c9d90afc1890a9adeec8eac087f99b815e6eb2b87"
+ "1dcddc8092249d8f513c6c5609fdae2cfc6bf01fcb8025a4f79bf12aa8e10982"
+ "9a0bb38a09d1a39365e0405652dae451e5c3298f47040598ecd70e4b403389bc"
+ "d5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.8",
+ "7cfc00a643ae99796801ee3cebe2cbb1a6be1cac15c648d4ba3301293871a99f"
+ "7cb143c128c77f96311fe43a3901df2c2a5c404be8314697e09b2e80aac6ac39"
+ "971bbe0dbc26673f31959f238eafd15012e4967d33551892a3d3651fe4469b2d"
+ "ba4557df893ab6b94f1325c3a1",
+ "05985a4cced0e8fdc58924edba9e400e6748214f8d0b83aafa20350bbf0e6876"
+ "ca5a9af3970dd63be684f9936db282ff8b53cf5f1bb1cbf4473301f372d9948a"
+ "f9391b2002b2be3e45ff24a2d899ae8b52b671b04bab460106bedcfac013959a"
+ "48189598427fb957159a6d329c19f36ca75381b9350d34389c16e180a851e457"
+ "cd"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.9",
+ "3d90de7235515949245f490368c1f49383e44c1db51dd5385bdff5bd34450e63"
+ "ce42150b441ef9ebc729a9033453f0a9399ff6861f5065b6666dc20b28720342"
+ "8e72bdf4cb748ac8d4a55f43d2235e0ab2ec2cf2b06a015f41e35168ac7e3c56"
+ "8f2f16ef5728b2be9524919d3676d68f537efef29a05af97cfed7ce9ec45c12f"
+ "165e4d7a4fe72b99eabf83316cdf2bd1644b82fa13e4ffc449e76d44c3876963"
+ "51478b1a0f859615da905f20e68b24565c873f834e593458518ade41c1428174"
+ "da0c47663a7600c65025015e09c1",
+ "009813b2fdc51bff88dedbeca3b14ae58bc7e714c1d92d7426e4944ef93ef9ce"
+ "6d10dc989eafe7348d0a95f99f56948f72602ac5e8614f6b38e68da79f48e276"
+ "8eda5864cff2545137f3cf4d81a5aeb89b21072674caeba0007100c07ef4dcbb"
+ "d05afbad9e8b30d746ea360d6cf875d10a67a57f4b5df4121d7297a4bdce128c"
+ "b5"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.10",
+ "20e6a3fe16b521b3c1e6ae993ec6e849a9c11f2042a2d4ce89cf0f99e1b4b947"
+ "1da9a1730da8851fc5ab3c0922055f003758b235c28de40880663fcd80140718"
+ "15dd06494a547ccec3348e12d538d5dfb48f807b59e9b7cd81f391c02c016cd9"
+ "c1a84f9c595179d8f200242a5668182cf2cba3b9fb6ead451d6d27d9c7361525"
+ "d688b55233ff45291cc07402d292de0be83d1646c43c28881fd45549b14d1261"
+ "b12f120438276c6b3f98f55bcf1780bc1a91eb11d0229e1d7868d7fee49d6b91"
+ "68e24de1cb4f0f22e67cbb1569204113027294b37ec7fae58bc64e825eaa4d56"
+ "94d0058f2cd4c7d21418da3c0307fa2f0492e8b37758d3ea40a4e30f60",
+ "01f02b3f839123aff2a3f43da5aaa0b6bbb60c043782f4962a7b9f025c948e34"
+ "322e98de3703e3bb45a706a2bb0509bed9f410528c881ab9a1dc0197068c3728"
+ "c3716d8381d9f86780fe78a6434b72f51e69cd32a7213ccea743b33c3c96eb00"
+ "42fb98a70c2e52fc178ab2cb9ff8bdddc1046b08e047baddd65a45a4e65339d7"
+ "25"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.11",
+ "6eb49f8abc5b4948720a7f42f74084780022e0e9f9f68886d9f34e7f7f8ac154"
+ "dbe19c91b8ed38ec036b614212ca35f79ed874579e2485dac8205d0e56b4b4c0"
+ "000a8a75a6d497fc5119111a40db513df6619655b58a116fabee082bfa79373d"
+ "917656871011241887f442608bd1eb1d95d1768065fa63324fab2736f922705c"
+ "f289fde9267433859207a8bcf12d17861cfd062b88df78870d5a5e91131b63",
+ "02a2fa32717796710b52b051906cdb9815b2d0366c070a78ff72d45942d7adde"
+ "ae7edc73ca9301f1f9fae68a0bd4b1df05a9a671f8a5b7d45cd11fdc0f0ba09d"
+ "25cec3b6303d9a666c76326496ea31ae3886a0c3b7d22762eea278934b96a4f9"
+ "0a501ad3088f702e14763ce33846e2fdbe6d661cb82e6d989df3c5ac8fe40a85"
+ "62"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.12",
+ "45cfec132ee593f0c3f3813d3cb449e6e5e61d13de529ae3e71c998ea456359c"
+ "e66b82045b7ac797fe96985deabc5122530b2e29efc975ee9603b4f96f3ff4e5"
+ "9b0e35a9ad92f2b867794d8e",
+ "039be48f133ae7f0b19eddb213560973a3e2a1146c7942f8264bba5ad008692d"
+ "113801fc2778a7e33a9e115ea632e50188c87b69e8d4d8cca48abf9f251efc00"
+ "17b99edee566dcdc0bc58dbf6d67bf863db8a89abdf12a77f1b70de439d176f2"
+ "eaada5464c79a584270ca514f48f1dae8678ecf1ac296d07c46898bad41acb19"
+ "9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.13",
+ "22512987157cf9b9ab4e5337b09891d63cec3743c0f7bc9d182e",
+ "02c7757f9993ef8c6d60a3f5abedcea535dff55ab9f4f62d1254bf261dd6a2ee"
+ "52da6349f47b9b289f1d0ea3e0ff08f455fa5485658e4217f440c08b90ae4c6c"
+ "c25697cb833531dbb474032543100b5f92b678195ddbfb1b59c59be7c83dd817"
+ "45cd4e709a0e3f798ead5bf8662da65c1057cc082d905050c465958b555d77b8"
+ "b1"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.14",
+ "ae48cd83f4a1f94e1719219690c8c6f6737abd15e0d08e7fc2ea0d315b45bec2"
+ "46e845bf1760c86c3f82d84b1e9d68dccc01d9a7d07ecc6bfbeed83d7ad03a6d"
+ "566a89bc64421e7eb47e52c0238658d5e4c5597f125afc6c833c63cd6f97f9dd"
+ "5cce8a2638807ce8a583da032bec81a38cd299a9c78e8254f288516413525fd9"
+ "4a9e0a95c656d73cd52a4dcc7dd0947f4a005eaedccfd03bb1715c351cf059cd"
+ "522c7f538c1628e72a05644e8fff50926fa8682a6753786f2aa2610abfaa95bf"
+ "99af15617151d0bd0fc46fc3b29cbee1e663b923136b5e1992839f0ba52e44fc"
+ "cbd9f320ede20f55a423770e573a9fb2b36dc8f184",
+ "00fba9f6f959b170b0946dcbdb98dc8e8479c669adba6c54636a2dc7d7f7033d"
+ "350405d717f2d63dae65c24b37db1dc3e9f61743af1ce6de2467d185aef08d2b"
+ "f865f075baa6a29c580661dcd4a48f21ff4e7b039eef1e1e20ba80cf20eab6ec"
+ "de60fa5d3767a30e6ad4144713ca49fc038099af536c0d5f55c4cb15335381be"
+ "a0"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.15",
+ "2c8a007b603056d33187bf52cef6161aa5f5f5337fc359d46344721d945fbc4d"
+ "240d30620b296c3977cf45c247eb2c36394079983f03ad82399c4b286c481659"
+ "10b348b95ef39c43bfbeb3566d1d1eea5a427f4cb1681f2a7c401f3f0d6d9ee7"
+ "993be5ec5d34a75541e9f8dc7c6069a8977c9f936edbe41a4ef785a3ef7ba051"
+ "899009ed612a228f903167a934eee69b4f8736c29511c6bdc61eee9608a9911b"
+ "ba52839be99f91d2ef85b8cf10c1d635080829ba7991fe2ef82e2bae27081406"
+ "e89bab75c3ed19e87a4adb72ec2621f3f2585b38cbb36b3c0d405ffca7a6fb02"
+ "24420794cbd8d7831801c881e165",
+ "041047e242b6448741f28a4c8b2dfecacc0ff6619e956a6a6b10cdd01eedd201"
+ "c80e0fbf7c5bef52a7aa9900a859394b47e83d08b5e1da03a33554000cce17c1"
+ "d86229a3a20350d11643a758c116b8fbf72660df4c86ef8c1fc4544c3ae1d1fc"
+ "3ce9f263f62e8007cd7ff7ea8d50a0828389ff431fc5c562816d3d24b607211d"
+ "29"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.16",
+ "7b15d1a79c7ad2d12f75da57d14a8eb71fdd4c4eff5243741acde23ce6dad308"
+ "c81d5d580ff9c3f893ff124fe458b31884daf7fc4466d700dc493f1c7a7dbf62"
+ "241b17e73623fa17814ab4d2c9245be83bb3cc5f9444b15217b2441f459c00b8"
+ "2e58689a11dd5c59fa395d1a6f9b2c25cc8499927ab9a49828533652cee23232"
+ "972d6569ee56447866f10ebad54ea3f061320c6d3fefce34552b6266967b0578"
+ "d6c455b9ac2466361712e7d05bd3332ec130d45c6a4976162c797ad1363f4969"
+ "e4ae3ded6e36ea2cd7fb356609be031a79b294",
+ "03025290b4462f9ab79fdfaa7b1d53a4d12796c85aac28deac2127c8252c2a62"
+ "395a8b819dfceebf68dd4dbfc87c1cf3d017a53a264092506bb6fc9528e6f876"
+ "78736ca56a14a1aa2677a8b84f5e03fa2c0ce4785b26ba92e75fbdc16d8d4c7f"
+ "b0bc39a88e132e1e05ad00f12f072706343f5eb3dab5112e3bbe76ed0bbc7bdf"
+ "cf"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.17",
+ "7a7644001f8013c50fd717b24465477abc34ba9c1e53ad7632645a6ef7c8e64e"
+ "8ecb7bca5b4f09b52f4dd48f8bb3dd338c78182ce86e8bfb1c68a876f7321663"
+ "06a8ea8c0d7c21ff26faaf4ab45510361950c76f95c2730b9d3e4d6d85ea2558"
+ "4ac967a02b1e0a26",
+ "03b2accfeff063bd175ef8ae0cb85bdb800ddc27776f8d3dc7e21d199bb8d65f"
+ "5b242e79d45ecdcff02e803f5681ff044a43b55a9aacb1eaf16784838b1d5a2b"
+ "7c1a364dc405311a6555057ec73f0a8f4e0ffca423022ca6ad74469bbd5557bf"
+ "a1cf4b95636f534537eff2fb16af5e6471824afe2167918c89ade01d52aea739"
+ "9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.18",
+ "12d224fc10a0fc40953ab6d701c416c3a823772beafa",
+ "032cb5c8d61290b766e6498aa601494d9f066f27a47a2870f3678943291ab22d"
+ "3c45c076e560819d33f889f8cfab2df6c63c0ce1ed5ceb51547077c08278187a"
+ "8272fec7de9554cdc916ca72f2c45143f2cf3243c4bd200c6e993f0db5b71d4f"
+ "63771e249b19b997a6e5a919ca100c90fea6a2d4dc6881c3a0e1c1355383cfbb"
+ "4b"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.19",
+ "e0d4e2a5e98a51237da5085dcf098ae2c05b4e169254ee6dda16210e4a3fe81c"
+ "7256eaeff28c0c63d854b7841a136c4360b215dca058748a4bfa825868042821"
+ "992a4ed5a7d58f8012207549be8cc9cecc8501b9f802830f865845ce2e339bec"
+ "28059611a1a00b5535c3c615e9d2a13959f1015c8bad2d753a59a6143b3a3058"
+ "ef722560ffe1c18487c741dad61f07a15642e726ad18a984875e68c62eebedcf"
+ "946f13b893b2808f78f9294807d774685494e6b89040eee6de1ba718ba2e082c"
+ "3d5ef17c1028cd66",
+ "03e783bb53dbb67cf2195fc1a57f4b74c98203b1f3d615feb920e4abe8375834"
+ "672f4b8f55fef2aca8b5d40aefe4efbdaac3e82108d07f2f1cf8c0d4dff81b39"
+ "66ec69be5117ac1aa6118e460b92d88fcdd94d08ebaa5362e59d52004b433695"
+ "1437da0f51d63e505615b4b75554080b94897fef293a34c40400c4f99aa1defe"
+ "35"
+ },{
+ "PKCS#1 v1.5 Signature Example 9.20",
+ "64b3ba409803c9b960c1c4962f51271bc89a40bd405ce5bcdc8851d97c9be5e5"
+ "b7464e50d99b6cf8adf8ff832b737de8b6ff1abeb89dbae93a90639487806b05"
+ "96cd316860f68f0027a3503e158967afdff469076817fc7da3223cca1e6c4897"
+ "3b570e0bf74bb8b39654372b7a1d6f",
+ "00d200eba0b6522afb420ebf16488c530352c42dde81e764c0cadb43828cb998"
+ "d0a60b23b5b6958a00fc2553e235e8574e4d4fec9e668dba40de6661abe13fcb"
+ "84c1ad15c4b0cc0c6f4f0f837787c4325f045d61ee2c9972b01f3212654ec426"
+ "62567faac40e9c0a28158a2a6c31f01a849126df9e96cb8209beb581d6846bb5"
+ "ab"
+ }
+ }
+ },
+ {
+ "A 1028-bit RSA key pair",
+ "0d5fb99fdedf4256e28d4b41d707fc27633e899515f4dabf6b462710ac112581"
+ "fa73fa8369582c9fd4525a70161899df6325849e5c43493e13354e270955a43e"
+ "3835b5998ed42a575bbf688d69ec366d2ba6f0504c1ee17dc59b7ea0b4640cbe"
+ "cd8bd7962be8566f0ebd655743656a291285e037bbfa8655801bd0314f464c56"
+ "91",
+ "010001",
+ "e76f42b47402d5e0f96464925ab4b3bc6894300ee486fb70ced491f2d1b36780"
+ "84c1c2cb969568a5f77dabcd40933937a867f934fb2aeaae6d786798e0d04a10"
+ "6f545e41a9c93833d81fd4d75353179cb0bca45e79aac9413464b0367f31ac5a"
+ "ca566f2214bf5146a9484b87e42bdac2b01a996703506be07749aa0fbeb3b229",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 10.1",
+ "b2d588509c2eacda281e7671cba2fca914ef73a3aea9202043ead6b72125c1b0"
+ "d5cc15414620d573d7ab0b3a8ab66a92df870b75b1c4d68ea7056be0419ea253"
+ "e6b08b129e0f64f10abf82e167f8e3e9282e7bf71b043baa2ba2d8756d46b6d3"
+ "6e973415f4f8c0eb43fc604ced493dc046a25a119bd1581dbb597c3e67c2fddc"
+ "396df5d23b7ba80bd2e31290bfc26225e00955a98d911911a399676fbb",
+ "079a7b916f674117f1d877f4934325684148d5d0b0d5c2c6156a11159bc0bd30"
+ "d0a73534dc9445ebe206d6075eb4ea7a7c0432bd44b83cfae4685a9eb9a97cbb"
+ "fa4e82f71db51afa0d27cf27f0609bb3f8806413247d5d4954f789a101bf3921"
+ "728b487e85fa3fd4dcd72d04448e42d3ec05cc475d74cbf765c34e3ec14cca50"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.2",
+ "ca2518a5a224b23d4205d8dd7eb04cbdcd0ccb82bc87961d859d6600b1ac3e25"
+ "a9407b6c065027c04081f445a230ab9308e755f33a759773be6b969e0ea774aa"
+ "6e334fb604184275f36a031daea6518697795bd6a7d6697b406da2cece15dc11"
+ "3d8544988561131d4fc6f6e3c580d806807df2c6856509542e4ed39d346eba15"
+ "976a8fd01d7941b0165606c76176649a161005a0",
+ "00beb921ce7489819d2f85c78839a27d7e19ea0a764ac53101e86f3170a76e31"
+ "8a7ee89b1f5e23e7e2db9666eb4391b2792a5767ee359b5c71e2747910c82c60"
+ "83d6d34829b96fa5a2ec0f62f1bcda5d78f8dc3c650b94e32b3860da5fc5b17f"
+ "bf687ec0075a9c73dc1e98d1f36aaec4493f7891e3ab08e2042d8b1e462e8c4c"
+ "33"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.3",
+ "d433d15b2d61b86ac8ec0daeba65e11ded3c38842525e4b7c8e453b0f553cb4e"
+ "b875a69d7816f54c87793e3abb79fc55113537b4762965cfee586e0a17997851"
+ "e3dc9eaf6f1c9c2e98c9613e3bbea013ff58616b2ab05ab324a9c5ff4c5efdd9"
+ "90dd97d91693c1ebd4c09c732116c8dfc3ec515c20532cba7e4758c68a69cfa0"
+ "ac3186",
+ "03ae3be1c7446ad3efd8bae61b3d32d3ef152482b1bfee312fe9e6beeeab8cbd"
+ "08f4c8f9cf067deab6bac7c0fecd87bbabc7f6798c77ef1c3fd8bca28cf9ece6"
+ "56795f60b37875eabef82153a12bc7fde3fbc9e5e148f4e16cb72a773d9dd023"
+ "17f70b3391400805e85e7a23567b34aa65a35f744170affcb323371ad2ab9f1e"
+ "4d"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.4",
+ "7d0f5bd7900f1e65654e6c7eeb064cb828f355d6de9bf0d34783ffcbe80ab1b8"
+ "ae07b7f1e3f5a320dd9b8b76be0e9772de19a8d3",
+ "09e7a5304171da638be7601fbff6e49536f3366082253abc1db5d1b65493da59"
+ "5ec93c37f5890b5f4715bd5e80c0bbc5c63b74af2e60439132d25213750bc1de"
+ "302e3e8b83dad2de0dffc4faab4056dd7c405e04d5942453659d490f3c3daa7d"
+ "3f117011816b56590104de7f9c052373e2dde414490427a58964493ff45f08a6"
+ "e8"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.5",
+ "d96aa091c160b552b16df0658fa8",
+ "0b69754ed6d7a7d2d85b2c7a306c78d63d0ffa438f43beec3a0286ce57e7e0f8"
+ "5ca430e63908c0fa584ba2505f8c94656ec02494bb032f920c4b6b8c943e6be9"
+ "2f578aa8ccdfaac0a54b8a9c0df548271f8973c9ffa2a20c84762e9017e7452e"
+ "5d74da690f75c099ab91e2a7963bc537f9c24ccc3c418c6e985861d93daab2e6"
+ "13"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.6",
+ "56f048645a49fa0141f4d674aafcf2fffa83f9b452f1feed43057cac27675ea1"
+ "a141d87f92f9cebf6ee4f78f8ed4c3a29deb729747b4f98e4c7590aaa8d56dbc"
+ "61d38cb5622226f68e43f9c4f4c03998aee90934395bc840c86dcc8874776f43"
+ "039f56a89d24bdc4b305df09e5ca0c0512ad6d1571919a3db3a6bd98b7820ada"
+ "0869d225a404027acb6d767fc314db377e8d1db6ef0af29454db2bd4c1cee013"
+ "a59743486d32329583cf80113cdaa10e4f2cea6c4f9fc6e4e2716ede85727c3a"
+ "fd43494609777630ee33637ea35c9b4f688e492c3c640d",
+ "0666ef71e2c8a1eb1c46403fd23e521883ada1b9bc5fbd353bbb3c3dfb570ac1"
+ "c721faf3f59732f213377380397948462fd20a3f0e5e0891a6b07c31b360aaa9"
+ "65e2f0930eb341ee77ec439065c0aad91787ab6d2e6cdeddf55481651aebbf9d"
+ "11d54bc11326183ebff49bd40bdf76d7ef69b67ea3968fa849032fb824b6dd6a"
+ "e3"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.7",
+ "79da89e355d551a0e031f4fb71ab6f4144c4762e07d0641433cb5ec86134963f"
+ "7d2c4dc7beb5c6d46157c6c4e14a4b9c7a2c0d460f1fc062ea1b4f9874d5b1c2"
+ "9ae2f2a5b39062e41212e65c85c28e767589965d1710ad5bc76fa5a6729a06fd"
+ "496e2e0997e57337bd516e6bc79be9e070aa7b86c2ddf14f94985fe1582a292c"
+ "d13934b3c38dfe5977ed1d9f8ad324c0dc07e5853c7e4890bfbdc1a01ecd72c5"
+ "ff68a02f1e",
+ "0a0682f742e743e1c7dabaac618a786f28ed13a6587adfc33c9829d752c13ef2"
+ "7a00c7e6d45e27171a5841771d78698c6cc66778b8c09338e35b9b6f59c064ce"
+ "b3eb20ce909a5c6ceaaebbe93e86c7c5ff4a3917f126819632cf96fab1d39173"
+ "a7ae7fc2ff5c0fb4090535dadb58d87d0da3db32ecec13718b3ac5c30ba802e3"
+ "8b"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.8",
+ "e69ac9433e6c28ac53f8034a868da9883e319e82e6bc2e49455e6e4f098b53f2"
+ "87a858da1d876a9a5a6a9fc14fd24238cd4e4b5731077a4dbdd5038a9bc1f5de"
+ "f43fec77f67eb062faefef7d0429238b25d031857896623a3f1d37bf",
+ "08a020e4209878f1e637ad59daaf835daf4ca664844794c1c648f0e2233dba75"
+ "48bd161f0c0a1824d762031a417572842f8e644aa93f9d91dd7709e16a429cc1"
+ "43903ef4f837a458396bcac24092b01724c6fe3dd1ad243f3f70b5ae6faa09f3"
+ "70caa512104b9176060df2bf121cbce9198ec2fe45a59ebddc467532b5afb9b2"
+ "35"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.9",
+ "45e09056a28e4b2e7c11f65e688a1e3c33f0e52c9a036c09d81de5a6dab58d4d"
+ "55cf411b53ad646e83a34b0c08c221ae0376ab76a79d1fee671a584420564f8e"
+ "852eb6f2d427aee0a096dd72dbe8507c677f8aa00eb7c25dfb0a49dd88a6c784"
+ "76b80011b6828b3aaf4647794422ba6bd63b7ab0e7dafbd36f6c41dea03d7322"
+ "3564969460d928540b739257e70bb68d5c653c3796945895",
+ "08717d5086a6453bdeff77d4c2b856e3ba990babf69701df6ca0a3b3a81b5569"
+ "7d31889d100d6895c97f0a56b47168c98da62e59ec79d7aeab2f9a570746988a"
+ "26f423576c703fd841ae51c9c229a2e9c25fe94c5b6ce2fa645412bee659faf6"
+ "09a32eb2c05beeabaa4f58caac3133e5eaaa27344d30eeca22c6ebd8d9e34441"
+ "0e"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.10",
+ "b81c8bc4ac1fd971b21f027e06f4d87b34d5769d23c8599d1f157b08a7f92e34"
+ "19fec4c8c1b34ca463c768b72e07f9dabc3cbbdd8b5617cc252875002a1a1392"
+ "af0fafc08c7211758f3c042050ad731b636c0e83191a79de5aa2cb94dc8b0bdd"
+ "e75db7d0c8bafb4223d347b024b3d9c6b239619b5d8b6346ea86fb8f24c584dc"
+ "1a47791cb7c8c7ebf1ed438b88",
+ "01b9f43394c7cb885bfdcc3c84962223e8aaa94c6c9b7905401d24f0dc443b2e"
+ "8d840e28a95fa22e1ae36ffe08966f38d38714cf68da8db23764b88c4bb2be4f"
+ "d3da9ccd1b506942aa9d73fc09382dc3308314706e6ce27f00761f3c9bd54fa0"
+ "e31c96719afbf0763e35cad889b72e13bd12b76d6f2020faf61dd3d708228df0"
+ "6d"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.11",
+ "d0322883e598163d722036da3e632aa65597acbcd1f47603109696f9b39fdc",
+ "078d17ab8e6ff0be50b3539eb03ae8f0903b7a077481781fb0b1f09edcf77886"
+ "312ad6c060274f0c389c16314040c8d7d9909cb75df18c82d62dd34eb59c6a87"
+ "d3c46a7ef7474a5e447f7744a6a92f5990eaec7bfb00844d684d307ddb498189"
+ "4149e752bfbe2e77057da7605469af7ffb6727a9981b9439caa5d80e6ae3b3d6"
+ "51"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.12",
+ "e8742f04b5654d9288b231a47a365839bb01be87",
+ "09b75306a7212ea6f47eb0ccf4e2e0d6f8f3abdb9cdcfaadbe51922f92ea6262"
+ "3c58ea74ea1a247c9d731f2c033536b35273c717495f325a60405bd5f5e405b6"
+ "80279e752160478740457216dc929ddd65dea505535546e4770f8211b849c365"
+ "218e566e5bb41bfc361b65cdccb0e604c9edb970ee6a286a1fcec0ae9d92558e"
+ "ab"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.13",
+ "a03c2b85fde46468d1c50637b00a72dcfc32c41631739c060245f53e57c66c51"
+ "766f24eafd93e6c66743480591bf14446e040b67a4f84699576c2e1463caccbc"
+ "b073e4b7ec6da6c8cb41d4a123c748cd7e83d261e54c2fd2bc495bc4c44a78f9"
+ "82003403092ec6960c088e2bcde348a2e0e55a4b4f42eab229b95c383f2113ed"
+ "6cd1f3f3167de3d28d362c8d78b2eb6e31620e34b2f0f941dacdf7b4b8568c6a"
+ "863a551d7bd4a5d7093eda69e1e28056dcb1eb69ae03ad74be72a75ae8fb56a2"
+ "7125ca3d2db3769d13d35db108e2644a7f3b37938fec9762315206d30ccfd576"
+ "ae7de0769869e5044d07646cf78c64a486480b0fd42cc7b246",
+ "058da5494c4e98aa121f67f65a2c865425a9e6002b223f0388809753573b4f33"
+ "4de45d8f0007255d112ddc84db266700e440b5a86900c3d3d35b024c18d8a25a"
+ "5800226d0a56d838d8919e6d5a8730d619499015ec4665c63d778083a042dd4f"
+ "052a1bbb5f4080cbbb41fa945bad6a74779f680725e47a08a0514f350fa5adf9"
+ "0a"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.14",
+ "c40c70f26da569486bace785da32e337a0eb94fb3a0aa409c5770175c8e8cb2b"
+ "aa8d2a1b9846c37df7d671036d5e91",
+ "05256128afba1f55d81f79ea33879147a24ad7779346ee798b211c247153ea38"
+ "d26b217065f61e0110b53d72cb64934d9b1ad1b3dec332092d258f0caf1c4aee"
+ "8b23e09bab0f0c278858b441d08ca3ae9f00aa9a3f018f7d9fa98a18df0d2484"
+ "7e567a47f5779bd1793a4b0252f2bad40c9c4a81301cc28c2609d7bb3337e97f"
+ "14"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.15",
+ "9e6dcb11e0e8477139faf041a74e2bed643a62adedac7cbef365ecc43ae4e582"
+ "60bc724623bd6342dc660d66142ea63680715f522ff3cd4b636f84aa9d75fbfb"
+ "c384107e43004d986fbce1a27f7ecc7d02392c",
+ "0ccf234eb480085d920d37d687965d2fd2e4a4f3bd3bf7ddc16b5d62a6903274"
+ "207c6f90836e29ffc63a57f98130c525232519c708f0dc8a1255ab55db1a2b9a"
+ "bc11061602075ff6f97f9092796b98871a6cd5d2617ddc9d255a7300c910fd21"
+ "0b14a981e5a0e0c6bb2b045fa9756898b93b8a634544d77afdb1cf0e7958f11a"
+ "43"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.16",
+ "20bc463b5e1220a39c84e89fe6716eecab5555f8bfce60cfb83793cc40a4da1d"
+ "22c0ab4eaa931fb747be35f1cf6fb1465bef1df2760fcb3f70d3e296e7b27045"
+ "0dffe2d588c4396a5f6f1e6387aa86971fb0ad24df550443dd122bdb2cf3c9ed"
+ "6125fe55cec991cbae8ee1562a8c0f4f364f8f0a80cb30fd99440bf655f0804f"
+ "92968ca2e01c0d5abb4ee267636dd4f511a8d3294116216bedc1088645e465d8"
+ "e198b8afe1cd5424b42a533ced198ad597",
+ "051b714266066bbb819a2a3805a89cff461875c095f4f38982d1afc2ad2f1424"
+ "50b8a752947f031cce2c9c340c8ac9f9f7a548b7cc17e4cc525696ea0c8753a1"
+ "e15bcb985deaec776fb9e7d9f75862f8983523d9f871c63fb7561ac71c376bf4"
+ "95d4323859bd14188fcdfb4b37abcb5dc1a58eedea7e0fe62ac16e208aab4cee"
+ "26"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.17",
+ "92da260bc213b72b48a05753503d00a1dbfd02ac7b9fd44d2401ea7ad58ad186"
+ "1fda536329ae4173c9168005b9662c05cbea47ad864af7cb16602d3d183471bc"
+ "98bcc62c6d00d334bff5b90cfe7d7e12d07fe7d4cbd9dcd3c4c23490be8cbadc"
+ "08c9177980373c79eb4eea6d81a6bee2270bf420f91979ad3f271fd68dd4283b"
+ "e81410928ca45b9deb58d3ae98b2f4fca62125950b5ee128dba105c35cc398d1"
+ "5e742bba92697b5c62b267ce01141cecef807507de29c485305d0a990943230d"
+ "8d9b7252ee0b1956de845f2fbb2838785b470a7c2053db396b315a30d8a7f91c"
+ "fffd03e8a39ba8bc",
+ "03e23f8652374d48d381c378353eb47d9064cd708e1b9bf688704c04c0090088"
+ "46e6a47e0bd2e30c3340f5d4e19d2dc5d8890c8f0104dd6f5dd6cad9c4d99484"
+ "09c3cc0be670719dd0484180891c935b9979db8eb468a23e4ef46029f3af1457"
+ "4bd10b473edd9b127a306e5124ada402c148f51b52e7e628bfacec3fc2543a0f"
+ "92"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.18",
+ "8603a5622a2dbbbcbbe53330e908d5a25f6e67a51e0768d7c3c3fbe8b92e8b1b"
+ "36dc00743ce33da0f1c8cfb00d63edd6b2252fb6721397d2504b30ed1d293a82"
+ "e244c951bbfc24298a42ffee26e456a7be105cb5e37b3d25de28bfc01042c4a8"
+ "2ce870455487e5b30e26f8d5398c86126e",
+ "0822fc22a9cd877c09b6f92e8017ccc028d5379967c7d04ef32f869c7ef67d59"
+ "3c7745f629d93df260038cd333eaee92359fdbbf84623b7b5514235b8306272f"
+ "4efd13a6700be9289ad54e57d52d1febb46a37afd695942c4cbcfd3768f2821e"
+ "888efa0e2c5fd3c9c42cc35550d7955cdbd35c8ef8581b41f8ddab2618262e3d"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.19",
+ "067d4becb03e1eb275ae22507a77a5396e719b5f00b105950bc7998e0803da57"
+ "a4de08a4078b9a00d2d46f",
+ "09108d44575f614a683ee4d78bce1c58f5243687cbe9c5483460b65df236927d"
+ "bc78c06439ce1c7c519739c8f8950082d956d60fc3645ba7af8e78895470631b"
+ "b4da00c01b982cc11c68d2650c7caea4a26e210ff4b1cae1db505fcea9293487"
+ "b2073178ca245cf0ca2356baf865546b54af9535bab18db679ef5627092979c0"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Signature Example 10.20",
+ "884fc502c8824849478b2eac1e7ebbb7caf28eeb4889458602ec703581d05ef9"
+ "b1a4220bd2f922f25e464c880701c8a45b1d1fabc8662eb249400426c2226238"
+ "eb8ad0f9069c90f0018277448025a64180ed55d1afd27aff4f00702f715d2910"
+ "000df3925c7010ff117f6d8d2a816709489efd29a45c5923177bf92cd0bf6b94"
+ "745d348a144e98740f72226a3e2a9d417b7c1fd8f895f515c5c6d406a72bdccd"
+ "39152c30fdbdda0e62823ee9dfab3432e6642eecb6987b9046e040a478a4df64"
+ "8defb3016aa443d067a1fa4155555374f8ba325a8b55e4d6b5fa090eebaec9c9"
+ "2e261cc04ceaa48b3bed7b3f87d3",
+ "0b41b412197126159e9bda1a2462c8a4fd3dffdc6e98e4dbfc06cfccf16f74fc"
+ "b52338af14ed3936e02c1d7e77236cc6a489f00f089852de5cc425b45094a042"
+ "e385464b64c3b2ffd01f19a01c2c0381f758a67365d1e65a707b134e3f8a9316"
+ "b4aacb7e851a5eab3cd811bd4522dd141a00157dc3fcafc4154caf0593ca6210"
+ "2e"
+ }
+ }
+ },
+ {
+ "A 1029-bit RSA key pair",
+ "1ed7eea9405f507f941623a17bea717b860de44cb77687b8b85a6d7d1ef4f862"
+ "8d257cb94238c625ba25d46aae593960af79f75e28ab63ac3cac4820b82da1cf"
+ "750d6c930d6b827854aaf6cac0c17b80b029f5d319ccca665c5694f54ba5f096"
+ "f4543413ec4c5e97cc1dda89d2afd428578759032adf92895065baafe88d2d8b"
+ "61",
+ "010001",
+ "0d938072b16a02f5d50a15aeebeb5afe431874482c6d18fa7ef316c47f4ed6d2"
+ "124cd0e47eb89cc7587374576cdccb3bbaa195f7b531139369b56f9e2f53aea8"
+ "ac7a97e1d7458f526cf7d710c4902aaedf997c1194b87b62ccd8dab8ff5b67d4"
+ "0fe83de1b82b91609a7c5cf39229eb3a1b2f0ebf0b125cb80091a07ebc779ce7"
+ "fd",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 11.1",
+ "845519dd45d2ddcbc8dbe0b82954c458c3664d88274e502d279146b18f6a8167"
+ "50e94b4ecdee6832cb35dfcbdbdd3e5dc06404d5f0c70e7c7cd0e19f38bc5ae3"
+ "2c7cd91f94d8f56782397bc74e6b069827ec2730173740ce4a10e648c78897af"
+ "1a89e83331d0f461378d06052873f17d9ffce46a32472607fe73e4a561879e61"
+ "9e7c1ae814e45e1d2bdb121946b2aeb8563916c543ebfdc2c090feb5566500a8"
+ "ce74afa45372bde0c6673a7f6accb0ee9d57bde93c36ddc57b8490aa2d68585a"
+ "3db7297ada6d9b3f356dbc74d315c5fa1abf7de6cebca83c9df7",
+ "0863a626dc42baf3e161c35b3de3b1abc1aa5adf5416465d4c7b6b01ae2dad73"
+ "f9f158eb213dbc360be4d47e5707871c39c38dbbc96b46c8f9afebd3ddac8716"
+ "9098e1a76718d354cd091ca35296a77c21d2512ffe65e3b71b9022e9cd1f7c35"
+ "ce1365fd1f2c2cb967ff4c8f90f0c8eaef0db73fed00e98cfc83f80c67b3be1d"
+ "33"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.2",
+ "868e7c4fc6340b6bbeb7b86ea89ee7265f3231f48baa92e4a2e8ce0fa1c1a8c0"
+ "fb0aca944c74bccd",
+ "10cbf8717f76278fcc8fc0aab46e90a3d180c3c92a4a83eb93c8920af88bd650"
+ "6b4073453f0beff3e61edbb4dbc9c947c69deb69a1ac929efc15625b9ed7cf1b"
+ "c423a8875f3780ddda9eb2fccd9fa014626a7fcf998649bcfa5953a3c43efbcc"
+ "38704d024919df2fc4adea39e34cd15cd4f86ad3f501012f6bd28aa5002c3b41"
+ "ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.3",
+ "92cf880da58915e3aa95089353e46184c915945c57679c1e4bd3825ed919a320"
+ "52e9786e23b942539b9315f581daf0b41fa3261b967de40cd5d92a4824f364bd"
+ "1e1f51844b109b1454134adf234e",
+ "08828966ac5836c513da4ffb87618797943c612ede7e12b31003ef171065b4ce"
+ "dc6a80b1456c21b674b3779ad35f70177aa92c6eac0b833a967d7e98990b4824"
+ "4205dbf26f5cd57ef87dc6fe5ed999cf8ca75dc8e626fd6eb281c499aff72989"
+ "edf52ec6f3bcaf81ec5f8e8230b87ededcf7b778143ed6c8cebbac9de54109dc"
+ "f7"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.4",
+ "873c4715902ff19de08bccb0cf263763fab016d0220f0327b4755e354eb247f5"
+ "dbc2d396989bbd36d31f61989390cac16643125e63e1a1ae1f1bc9bbedacce67"
+ "fc1b51a7",
+ "05259c481593ea86d1f002ca58aaee9329fafe218f6750f0e588f33b64e708fb"
+ "27a6fe81ebca8adaec757a14ff55a0c88ada2c3b43e39e8dfbe676894365a221"
+ "0c2aa81f424d8529c2076b00c92dd8c8ae3b780d87dba729ddfdef7d407f854a"
+ "71cb688b9f03c71f3baa24a2a6e1cb410774309e40c13c2b264738e5697cfdde"
+ "f3"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.5",
+ "14b27602ece8f067b58483af1777c4ed10b8b64e64c69f57ef889a1ca5d5b5d6"
+ "51c608db239deea150ff12cf50c8679612f97ecb09f7",
+ "15c4b3f081a2e58af594e42fd6accf1d0d61d93a5e3a84cf904b98d9ad713361"
+ "b784b24d9295e43c23be93ef36514a9bac2c1bdf4ee7323436763a20662f2db3"
+ "41d9e38bed5f12c7dd18bc3bb0fcba5c0050bd1a2a44037197b8c9fc2aa599eb"
+ "43c3d9679242c99bbc49b03b98eaca8346287259e6ea2e89155d0dd2b4778035"
+ "75"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.6",
+ "e566e5fa556c765b62bd6e374521f508fe446668c6474bef046cc6894a87322e"
+ "1931e80d9ed9ea806b167a3af77fc04938b5548efbc068d4f1966a997625af31"
+ "a4007f0698a8469ab681f4d508b4a48c8fe720cb5a94a7f443dd5a58030497da"
+ "a959a3aaf6e34184397a",
+ "07e7c9442624bd266cc1cd1af3b8f06294dda1c07767fe19bced6c9ed7c4b1ed"
+ "7f26e203db7f3a1bfa57daba6f3aa06003bcdc1e00c2d3d76b9cbff96849b1af"
+ "f542d0d7afc6e422492eab0ab7f8e1d1ae0b279b851945b765851b9f8ad880dd"
+ "164c11ac4a57f96a0e484ba16abf1cbe8aac090adb6a71797e1335eefe2ac998"
+ "0d"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.7",
+ "b443c343527b30d5ff",
+ "0b3f13c27224d16101b9c8201f1b4f8537db3c116f3ce130be0de0dc0dd20f77"
+ "3cdf7b7f372387c4b653e5dd442184457411a82f8ed00366ecc077a4267c9d7e"
+ "56549663239b4319fe499aa78954049c743bbf09d77b3029d918bb7b9a6ae80b"
+ "129e41bb56dad2b8a4b6f3193374c8292fe017d063347e91cbf4dd3939c237f8"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.8",
+ "db90047f615ad71972baed0c10626ec8cb18c6d75eaae058219fd6195426d44d"
+ "5c543bef3c4c1498e877d7c853e53121eb31570081d5de4885cbc925a6c22321"
+ "ccc9c3784eb219e42b7edb928877607329798d55739c89d6d6b3f0d430bbbc47"
+ "22eafa67defc86aba6e63483fd6499b03fabdc8465d98bbbe4402b0231135c21"
+ "243d7e02ad5f7e9e8b9460c12dde2a395b456961cc3dfd9a12f5d9359e0b3a6b"
+ "d77f44655b603b0255dbbaff8bc840759a3462fece0d8db6e45e2fe2bbf8b6e9"
+ "7b3feac07986738257ab9f8cfa795a20192b5e2cea118ca762252af6c6eb00ec"
+ "5c6820bcc7c7",
+ "00aab067d3a8633d0bebd591ed34d067f4718cd7f9b1e35aaa405da1222ab940"
+ "3866921fbd057433407a4aae7e26c5cfa0bc9c1157057b1da1cf3628518719a6"
+ "03f6c3c4dea30bf49db9b068afec698121dce5d60d93a6f5633fc6af9df4c5dc"
+ "cc138c294edd429d4afe3b3378868255cc53788cf2b47745d64acd885bb47d2e"
+ "ec"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.9",
+ "2be0067b95185bade118dce95c57029b554b25e1c39519f8f89073b9a04b7e91"
+ "299cdb87b0bd17c9f151925c756eb9b645072561264107882138854ae7d507e1"
+ "5fcfe847094540e71a547f63b590467fadff647f643e1cec11246529062c9e40"
+ "8892f2a20cccc0ae45ca97a47fcadc8fede21a24711167706cc4b5d69477e5a8"
+ "a146b960cd4b1727427b16517b63ebfbcf84d0b1ac8e7e70f044357522b1d0cb",
+ "0976811217714544410133243beba9a21a6f7212c687915c72027bba3112f697"
+ "05425cb994cbb6d359c146b95db1446435d4cf961dfd5c498739bfd4be6ef1ad"
+ "d74b81b2898a4ce43dc37cb0e9ed7744cf409babff71788542ffd286ebe5255d"
+ "63dd7bd55ba43f5184e248d3a66933cdb06991ecc90eb39ee71d65c88ed24d94"
+ "4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.10",
+ "a790e6ac5d556fb7cf44460c7b9be5eb7f24f987ff890dcb7840241d45545b71"
+ "05635a1aaf4457e6410c65aece5011e2775ec8530a64a18839e9c58a7b77424f"
+ "74293dcb9e9ea8736d6ba58b1c6653d57beaab98735f7af732477b9af6a33ff0"
+ "75c7e46639d748550820ba6abd4a9d48cb4903f65b76f814c6cdc95e8d9e870c"
+ "244a029b294a8a5c826ab161f6f978d9f1c03fcddaaefbfadb8caae84bc2dd33"
+ "2eb04997d61efa91e9241e4ccd9764c726e766ed3b0338d086f1032c1533ef59"
+ "3f88fd56033791b1d0625c6ca51eec279cfb6ae3f12700cf5bac271e6567",
+ "0d1b111ce8de1d7c4f7fceac73df70aa6eda58dc32eb98f78e7fb9bc25de3e6b"
+ "09ab8cae3b2026b6187ff63672e57da4ac28962445d1fe951d27be6a6ce7a580"
+ "7e1376139446e8549d48aa59fc223354d121fdcc38f1d0275e4186922700adc6"
+ "1dae1e4be805222a1cf07f110a6158a2a26258f19c657a110c0d9ad291680c75"
+ "96"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.11",
+ "32afd13e607d87b25ff40a885b2509f521f2a0a772a96a39fb3f71c96384b3d7"
+ "578f48fcea9739560a65bfb483d9608d202555f66d612d16b9255387b4e11241"
+ "15ed48bfef8b89d8ddfc219ccce48786c9e6426a9212e7b16d971d278a1118f2"
+ "f86b9c4bbf75c9c2d099e3f66548f1f4a8a821d7274498f7cce6ec5e2bf2bfad"
+ "2c6fc005e80a48cae46992fc8267a6480acb894ccc9b62095cad97db70d882a1"
+ "3fb38588c48ca190f180cb3e61acb4e2cfd9cdbf855c539921f68e1149d0547e"
+ "f59af53792dc660da5ef48a7ab8936d3d36ed6b6469eb6fd95e3af182c8768fa"
+ "60047854f18f3741c1883bb0792688cadb9e4df391d91145b85e2ae24ffdfe51",
+ "01a937b3cc8254d51508709e4a4de7b181ded9a447b3ec8dad492c397952df7c"
+ "550e4b26c95017299d8d455ff7971c338cd014df78e2a8aa5ebee258f49253d5"
+ "1ace9a49319ffc807ad70b2df2c96dcdb73b48acbc4f6c3c2a701e7c154b279b"
+ "0705bdf2548c8b3611b97da1ac09cd12125099540bf7ba99b08c2f3d5f6aea7d"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.12",
+ "5b00b8b794a10d21f1b45ecaa20df7c5b3522c1b1db4b084b959aa4e5658ac54"
+ "68f6e8fb612ff99f3216b5d21cb4acc0bb42eefdb8e82d754b85d09745894a52"
+ "3c0162d08ecce48b99dd6c38e2bd3d531c8562deecfc6152369aacf580eaf9db"
+ "6c68b69df2fbf3053f601f70022c9e381dfbc59099c37bde5ad89a8cc1efe4c7"
+ "b7d78e9097e08121eda64ac45c327e5edaf922d3c35f88b52c93d399f4c23836"
+ "2fe9",
+ "0fc6ac1d42947938cd2586d0e7fc3a0542b9af12d36eebf92b5d049c7965b11b"
+ "a9ccbf4700f34560911177b9d1296f1c68e3af469f4f399dbc189c23ea746598"
+ "2813323305ed6c35ff9cc109d0a2303fe7d329ca317ec4b18edd19c62c60a3c8"
+ "c3106f86dbd072e3e1eb8785288c21abcac22e0c0d41f4e23e7f394d4682f6ce"
+ "87"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.13",
+ "b750ae6d4d2ceb92140534648d36ef25e45155f52bde1bf26ab7",
+ "16aadedca09e062560c661d2a49b0ee4d9ce23907c69d10004f149d103c59c16"
+ "fe7d4373597db9ffd8923a77a6b943b188c47425e2a9e530413efdb6848dd342"
+ "0ba53ef81c25c578f8d9514d93fcc9cb1fb52f58d88a57d1fd3fe22da310ecea"
+ "9ece55e9608d63ae21dbaea6571b78fcfdd271bb659257476b5995687a02bbe7"
+ "89"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.14",
+ "47be01020eb7e7875bd4fcc005a82b36fdf2145ef132e2ed162ff694bc71589c"
+ "7dc6d5a3f89d597f2d2aa343335118f6fdbdeef23e613cbaccde4195e664a009"
+ "4b07fc0a32848d6139031cf572a1e323c5a707b6fa2aeef2dc872dd5a3e76b13"
+ "f8ef94adebd4e205748e485b4001d5d2a090b89b2e6474c479e7b00d2d57f586"
+ "ab76b80f795ba8996288292c3f2ca51a44e4e841c03707e48025af4bfd0ab6ef"
+ "eb8362edd5d23405ba0e231b3324e1ca3c5d639d2c9d82",
+ "063917929bbb209217ff48ed4f55d07a03f76d6d94048b6f71310b2c96e214ab"
+ "220d4e45ac01c93dcc8a5c26a02df61ffdb317549665610c84bdb8945fc6bbd3"
+ "8baed7fee98eb056d9f039a860d452b3acac1800a932a28c88286abda8de3cb6"
+ "c0d794daab7a8ba0110933b4d1ded239cbdd557d3e5a162917853315de680900"
+ "a8"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.15",
+ "4b9c09644810d4b30655ed8338bb276b624c68019822d1fc8f78861e13e22ac1"
+ "71821cfdbd3f8f5b8dc9c0de732b746e1d132e5f3f149a5a867c2ee478e8f14a"
+ "d4b9ddebd3ae7817e84955b3404b094393e61ca0189d055369b4243009a0f540"
+ "3f41c1002308c00ce699671937baf13c7893d663c947fc7f84071a672e5e0737"
+ "8aac08b3faf0fccf5bf283092585ebe240a3004620b6f3aeb6732b7b9d8d3bea"
+ "fc8467d1f1f1c7da66b1bf5ccc145b3224245fae31dfb403f493c0755357add7"
+ "cb2763713226c54f43640f7a670eb7b1f6e9e772f2e51417a705cfc5873ffb88"
+ "a5db07ecc4ee89f330a6690a8812",
+ "1a0b698cf3a058b44919af73c3de328e86ce9a5d4999e0122f414b94f32b2d8a"
+ "b1e6550cc0d48dc04befac2c67a4d069a7208f142dc267b3e38f6338a0b1839a"
+ "93a836807d181e3f0c7e877fb2421602005bca25a9c372266d18e6d500c5c7ab"
+ "13385283d2af919d0bba0dcb88bf7bb9972d67008ff498547d80fca658efe764"
+ "a5"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.16",
+ "ec9ff14b9f197a2b4f24948c29d2f64a64625223ddb85346378c2c25343fcbef"
+ "585a99e1ec0bef0ef9d09ead85bee1c4bfb35e48fb26411bdf180dc5cf317b3a"
+ "348371c7c5f4aa6d5908fcfc1ea39018cf0449e55f4ef994bfda404f1c189fdb"
+ "8a0a5b0906c3d40de1e787c2db4d88dbc210b9f801f4cd9c97227e9b2fbc2811"
+ "e38cedd9e9f03560031d4c958a7681ba9d7ea5e78e9bd8bdeddb4156790ef21f"
+ "b74fbc4158c2939e4efcb82efdc881886a5b6713a24b9b5f2ee25ccf721a64e0"
+ "f640778ecb3d35b4b8eea8ece31232636310ae3cc6b82b8a",
+ "013b42057820c73e3acfc1df4de1440c658e0180436da7185a9fabd26eb32674"
+ "b554de354d1f4f24e87773267fed9dd0fd8293eaca4af3d3a9dc518c8e495a14"
+ "7695111d3dc17763f1f02eec1ee29fb1ab749cf30c7886da8b2f646969598aa7"
+ "0f9a92fa4f935c7cc77bfab6981f0df0d285cfb10d66581539f78d0368ed4f93"
+ "01"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.17",
+ "414cea8eec6da3c66ffc8470f7e14760f74bf6e75b84dc98fc8060dd3c219e76"
+ "777dfabaa6e6b92955379f3ecaaf5fcb8aa5549ec9cdd1f5d577201b8e329f72"
+ "faa2bcadeaee388daf7d408afde6553d2417860f3c8e25305dff76dbbd9516b6"
+ "868ee456fc1f7b58d9ed18a46e4fc1e353e8d076bea30bf247c60e6f685801a6"
+ "d3f630aea6abb412a941ffa6f607f6bfb13d900127bbecee4f98a7aca6920811"
+ "575053ab2d427013801d8cfbc3880f1475431555a086fa5560c6e2206d9ee938"
+ "1344b8241c1dd1d86448753af44b00a0c9",
+ "1697bb23e291525f4a0e79262f3406630d0d6df332496926c4e5aef96e41d955"
+ "148647eaf790696af68c78eb2ab62ff7196296e1ea886df0917366090b630aa3"
+ "1858b51615873fa6bc8ff0885c57b2e77a04908893ccefb1412403991d0d23c5"
+ "57d222291cb8517b43286ee0056758d9c10bcd69bd68b84a2d1f537905b8a465"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.18",
+ "1789b808b10de8d1778aa43f94101cb89f56343061a1a943bb8da55ee6b979e2"
+ "7afeab0ed8ee3714fbe70b3be820603e5ceadec4b22f958773225df3aad487b2"
+ "8057ebfebe2c8793da3846bdb15903ac71e9c93b2016668bd906301a0a7d50dc"
+ "60b2fad8759d18db147f2066865fd90950a188747d9b696853486deaab8e443f"
+ "ad2992fc8a565bdcbadab0b9333ab7fcdb9c3d0bcfde50a58d2aeaf1cefb0c95"
+ "f90773b2fac137cdbc",
+ "02f99751c84438eac7f9963250d9ee22fda7297b6e86e2a8bcc7a9b5ac01f790"
+ "e09911704660858ea5c16272c38133fadadefa23c102908e419de2ebe9ac2719"
+ "4572878e2a971f8831c8f917e852e851df99d4df018fddb2cea31ac3a7b68975"
+ "e80a997cb7dd4d4df757bb8c3ecd910bcb06033552127ac308117739a02c2017"
+ "17"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.19",
+ "ff875cca0efc3d90f56e31f4bb668414894d09de90127f8466324310e11369a3"
+ "f2f6493c1c78a362b2a14fb5488cb56ce022739e43aa763d9c1c97b621cc5368"
+ "c9c00e81606792695f9af9ab633ef239eab3449dda9e6607089c375190354f7a"
+ "59a4b3ef75229d1c47ecdae33b2769ff5542655e781022d0c43b421a99843c3d"
+ "e10422ad2fd89dfe446615f5192e7579d4374379bbffb9",
+ "0268917f8bdaac9ebe32b0dc6cd9d39efd3f88d817d66cb6390d7b55c6921221"
+ "844ab8c08986d3f2ea49bc6e3a1002086c0b6df163f79d16116a93c4a2cc0422"
+ "c94841e1e3b945ab1d253ab8d7d139c9188ba83027c593f83a6f38370e7f0379"
+ "ffddf1427d6fcccf6083313f1815b5ded6737430bb4a70ba81484834d8d1d29a"
+ "5e"
+ },{
+ "PKCS#1 v1.5 Signature Example 11.20",
+ "e07ecf00e2401ac98b2d5ae0c9b83f219ab027a65199fdb634596e2344624138"
+ "729532495328f93fb3a33255278f3ec26065ce54995d424193bcb7581bfe1ab8"
+ "957d0b961c3030b820d09c9e326cc30c0af642666154",
+ "00c46db41b65ddc71fbbfc125a4f9bab880a2f0c1f041c411df7d45d1e19997b"
+ "348eabba19bf79b22177b2a0d73fefa5008362ce5960d7ef58a58993e74603d4"
+ "d9d0b3dad4b20c829d36efcaf57f0c4f0cef89015a48450242bd020d5f52d8b5"
+ "0ea13e56a1aad601915d60ec9abfc307f18af20672384dcc12f9822731369971"
+ "40"
+ }
+ }
+ },
+ {
+ "A 1030-bit RSA key pair",
+ "36981a95ae24181452da257c038f05821412d84eb47a43fcc7ef1217959ba677"
+ "027f7086d3a85cdd349f920f034c0278792dc8a8cf0c0080e5c61f474883c687"
+ "9f4dee0ae952478a5ee2ce4e3918641e813cb374f7b2832bcd6aea809d254fc2"
+ "ca9ac5a332424ab65c2a261275d19a414b616500d5e373706315f063dc885d7f"
+ "b9",
+ "010001",
+ "09ad031730b6327355acd69468700e7e9baeac5a24a7ffc93b292eb871da5492"
+ "46a5ce0c835255651a28c6e2f4c761afb6f06b9e2995fbb7dca174d5362faebd"
+ "c39a72c5795d1f3392ec088b5dc2a785b2c9c4c6e669e723b5dd0ce443255512"
+ "67dd62e0f78d2424adae48e249443aef4a370410db9e709399ac37cc481b5900"
+ "c5",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 12.1",
+ "e4b2d60e3bdd27816f",
+ "13fd4ac1ac6848173780965aff5e61c596892bc147760d43079b5d7177e423d4"
+ "86f5a73e1a16b3ce9b5edac161ea6d4f6c23fcfc3e6219cac556067ffaed4ada"
+ "c0a95005090b89844c54354db22aaff9eeff9da5aaa5490425e135cc0f64584c"
+ "7f05fe336e4440bb869286d44af157880e3a40fb06725d09deb37f1ebb181c8f"
+ "5c"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.2",
+ "788685fc5805d627b13f2fe7fe6f7c9ab2ca4944abf308b86d1a0f583d17b576"
+ "02439e1f2c6e0c5bf78170501338b4c447e9197b6503fb73ebabf776defae33b"
+ "dcdce77de79b82be1485a8aa9b820937dbf428a20550966a86b62a172e6cfbdc"
+ "fe0d6fc67a4db62252fdaf85f1e6bc14f8ab1c53326aa6a7bc5eec88e0b11d48"
+ "d2b561f2260650102ff27b57b70072bcc121e35e70f3780c8333b5bf6b08fa12"
+ "08260f33",
+ "0904cc11ac66a9837b74568be250e53ae4bef78dc67ffee509e5d9b472583eaa"
+ "a56d4c9ee70f6e82dc998b53eff1272bf01f09e5262b155a6e56d1504003e4c8"
+ "a46e6502553278230d6e81b7291843ab9769737f3c693152f17bf2d8bfc782bd"
+ "b3fa0aeadf0d441e1e52dea54b75cf165e35c382d31174f6679d2f21b981f413"
+ "58"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.3",
+ "4ec7393fdc4b90af8fffcaf34e845a09656aef9dda12b0342c46eb049174aa51"
+ "1b43c94d75c0e29070aff5b41423a170d9b3e8b21224aabc531d88886e2646d6"
+ "788f1baad4ef4b0b4bde4b12ce9052082e2ddd0e3e6caabb0a14344b0a583f40"
+ "4c1b6a3c7bca8a5885d5f224af1fcac3fad9370e9b2974e8ca62e22aceb9",
+ "21a66af627ee0dd05fe7563cc1d29ccf6f8731b41e3db39597893ba1cf375f78"
+ "1788fdf073b0b593c76df2816ec6defc224221ac19f5bee44fc0e5d4093d3468"
+ "278fb42d405a0704465322da4d3a7ca9c3da73c3d082aee567b77083323e75bb"
+ "35ed77e8db9c01b496a04cc4a899df359da4a2287cafffe1ed63cddead876c94"
+ "07"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.4",
+ "907760db32969b097dc124ef89751511a5d230596d2fd8a891ff00f05fbad45f"
+ "72a45d465624a3ab67afdbb9e5f9e65b63e30c2e57fe7f32f399011033dc0529"
+ "c0971fbe064fc5edb01f84cd57283fbbbd2aa02944110b6b534f74082f56be34"
+ "6cc343bd4d0b348091c005c6199a7e3d56885247b0c16a36b235b8f5d4f00a6c"
+ "6bb6feede88fcd788d75cacff7d95687996571559c05796a55711d7746bb92d8"
+ "52893ba90675f98b0f5408481bf1543f39de3d0c0c1f53495bd212ddcdc6d0e5"
+ "7d7a3dbe24208cb24ed41de03a5f052a9b5812700a5ce05c0200d4719c55544e"
+ "7fb294d344a4f205ef9a3497b567547cbd1a633e2b79d3349095",
+ "0ec938a0d4b2a4edd278d63de761c102e2592102ee05db1b591e0d857bf66684"
+ "9e74cc19b7e4e9cc392de539f790fc68e3b521db3a1a267e5a4e1219752e0199"
+ "e7019a248554c5bae3112beea40cf3e64f8aaf9bb1e9d1c1d8833c2bfa31b9d5"
+ "450fa249297fe2e46ab03e99b1f9c651d539eb53ce0961ce6023c17dd7383dd1"
+ "2b"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.5",
+ "bda554954732d1d5f3947555c61ffab801dbcdc8121dc6819127c2f22a436d20"
+ "622d1f4a447c3a77b6585731afc03e77baeb709c1bfb906a1aa1949ab6763a15"
+ "c7da5a12a8f395101e646a837173141f2a0cf536024b36918cf9db95b1cc405a"
+ "efe63a3a93bc4ada60a0f4e0729f4db8b76fd64efcbcb66f0e4aaff3",
+ "07262fe1f3d7b77932cdb7cd96ac198b9303eb44460f5298e8e52fe6705299bb"
+ "d618efd0b36331562f20b20e866d99c2d04a0149f564ddf66ba319f3b8482539"
+ "6ea8b893ba5b3ee5e5245cfe6b616e30a900bf83bb763d20b3303701cabe9433"
+ "4148882ae4ef14e6d9e6c752bce253bdda5739e33bdc32eb082828c1c399c22f"
+ "ea"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.6",
+ "5176ad7c99be4cdbbb5d79ba5f496cad9f42dc25d527a5d5e8e3359179225e6b"
+ "0e43666d3d82ab5baf424c85c33121606eb79ada6bafcab5c1e2546cabf6a360"
+ "038405ca18c0083667",
+ "0627238b0b93e4cf985713d291296cede345e88e17824525535939b3f3d5ff4e"
+ "bc40740011490025dfeaaee90638c5391eb44e9ff370457b60d5de80c16538cb"
+ "3860559585caf5e3332c7b1fdd8f45fb6e3557f2c7a60d099e94f8e96baa1e03"
+ "199ac83cec8f9c16bb49151a8872cbfe70f002cf3b53b611d6cbb665897cebf5"
+ "99"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.7",
+ "e174719364f7bdc86e2f0c61265bf8057d649cca",
+ "09771954fc8a1feee90f60c4b8a5bbd462c634379ab3da19ffeba6e031b4243a"
+ "83509ceeed6e012a9163c6145cf70502a9fb0c21db31fad5ad14695de00262e4"
+ "e567095e16110c6e65d6bcb9cc02e919f90d19e7307f4434503f9fe02c12c1d3"
+ "f50cc160086fe460298c881225bff2e9e313da384444bec72a67ac344467e82b"
+ "66"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.8",
+ "98cbc91fd49b507c887e97c3cfa9b59c26001fcac16487f6004f0b6874546320"
+ "02d549b5461ff1530c0f5fc09aacc46adada7dc9d7b3e20fedfeecd8f2f16841"
+ "773268542e86431c7fb4d163f31e8e3172203426bc0d88a23b137634bfc71401"
+ "7220fbfbec888e01e3eff7bbbdf93f083b88fdd6407d989bcc5ecb153c9cee34"
+ "10fd006bcdf07af228790fd5e04f5c0a1b63648d48609bf163c6fd656020757c"
+ "3c0638e1b82d75e2b4b908b7e0a3c8d7266b801f60fc2b4f317ebb8bf22ab9e1"
+ "cb7b7784395bd7b424329e861d478661f6dc1298515f48564a3ff99735bb9003"
+ "3875a25be8b724f3",
+ "0f2d7a5eab83584503d94ebf7dde9eed494110be94ed648af0cf6e891b062d2c"
+ "9def958755b1a308488d1670742951ec0060545d2ec43fe84aec8901adf4fe8d"
+ "67aae57a319f491c85c21cd7f9c599813ceb9df84778adc82a33c4e7674d7fbe"
+ "1348dc207551104f5442acd684869ac22cac516cc9887fd1d021efcc54abdaf2"
+ "b6"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.9",
+ "3eed6bf116cb31e0fdd4c5c93358bab68fbfa8b5c515bcabf9051cdf95a243e5"
+ "ee6815154eeb4ac10f5231d0493813e28149e9682bb1c8b77a6e1360b2b2c0f9"
+ "c3161e417ef6cb3d9abbdc742ce025fafcd538c77c4d0716491da54bcdf167b4"
+ "7a61a03527c96e4b42bfdc985b178781b6920f60f11cd5fa76663f56f319f450"
+ "cc2a7f13bcce59e41cb666",
+ "07673fa683e098bfa2b955b6c34e9ce8eccc5ab0ab4c2cf79b9be1e664425a7c"
+ "177a47d5320cd57086f951891845094b1fbbc9dee5f9b556df3e61e7e66973d6"
+ "3e69c9da17296fe615d633c86218dca399258c04f805bd04d9dc97a29f39d606"
+ "ff8e9c0a1371aaeec003ea274895ff7ba1502b28f8176302c24eece5b528d671"
+ "00"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.10",
+ "084ec287865e8fe6880472372097ad5b964c40a935eed1bea51ab1b5bc75c846"
+ "bbcbd95488e9ecc363cf073a90b20be8b679364622f345e122d0566acd34a4ae"
+ "11244525a38f47dc1f92b17f89ede06d836b4426ecbbea7933ac0e847e551033"
+ "b5f7ea4eaf1f63f3479db7eaf802c996de923386cd15b122de5a2398d3f39702"
+ "c3e9065c327395b9a995fa254de9c7adb451",
+ "13a7f004c0a88d513e2f1aaeab417fa0b2702fb93b828720ccd800cbb0af5a19"
+ "65725b6ee0587117cbcb81a46318521c950dd8469bd85573f5d29d865303ebac"
+ "45c7f6031c6f9378eb12b42f050944316f0b93db899bec937d5d0f58ed407004"
+ "01cd3265a6a44b09bb11a438eea07715efe42de4e8808f88240261148e8de293"
+ "ed"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.11",
+ "610700007c3c6cb096c994d65d95c9b9a147c34614cd722f29ebc5e093786f79"
+ "094802141a3108d2ec8a874c53187eb0d6ee2a859138cfbc29221506d0bd89b0"
+ "f3dbef506bd1ba4036b0f1ec0073327060752b428cfa12db280c53aae5f3e357"
+ "0e918cb09b90e9847f1f5ca4487a6bf3edad425f78407ecbe3f9bc7cab007566"
+ "5879431c6cc39e0c7e67006067418bee8d0db5e7dbe12da716ca",
+ "1ebeaf85d18f37840e8a3eaf07d69f524d883fa42f291e2007db595ad6930e8d"
+ "5a75b40bb95beb72d7ced038179747e9661d083840d587dcdf21c3adc7d47a01"
+ "f6eca9c7bf9e2a9887751b36d1abaf25a313fc29d7f834d2a2482985575e1be2"
+ "4bc4ef43a57ef4b0a6836993e11b67078504e3b79c721775f5b99bfaccc48a8c"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.12",
+ "da31f9be2609",
+ "1d2bbafca41ca06c4b811cb9d8369687166d14d9f92c5b98fc7c772f2d75d35a"
+ "5f9acce59b99efb2dcb97dccbbc86d7fd6b4ae8beab1e981e6c7745a1bfb4c1f"
+ "44a472b2ad07d41cc17515b7b14a49990b243442ff2c8fe505b1849fa991cacf"
+ "6809a20e55f2af7798870d65776f1f9ee48797e313aa66a47e695f3e731b2c7f"
+ "30"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.13",
+ "f98be52d9a5e55ad92",
+ "292ea34d3e6118bf8cd054e21517e863ce7cb7dd7273308f7ecfeacf9b457583"
+ "d9b9b97c54abf74e5a5ca36a87067e47d67aa047a1c2ed7a23d055ab4f094a83"
+ "c439ef8dd2d02035ef0562d967313d81102fc68b74525bb0e1d7962eb2758ec5"
+ "e5aeab65a93d2ec8e655405af88c00fa35f59de9d0cd8045abd37173b9fc6c51"
+ "d8"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.14",
+ "f438eff84c373fc12744a384158243dd97f4365e87d71e8b56b29791df44adf3"
+ "49e7626004a2c53335ec6352cce2edd963947fd2393893c248ba1b840842ca77"
+ "6c31729f707af50411001c287fba8fe72502320c445bb143fb7bf5394ec1fb2c"
+ "d501592432154091de5a2365d678f35782fea8b47f64d60919f0f1d5afa7626c"
+ "40d16cec19bfe025d116f42d22e20adb56375ad77089f9a93381fd78b7b1511c"
+ "b4e4984d2ddc7c9d75b310f295422560d66e3602a871209616131a847143dd07"
+ "8f23587db502dda03e18606482dbbe014ea083b7ec161b",
+ "0eafebf15d84ee4a13f1a82b8405118641e22e51da94d85887fc4a3b11f03249"
+ "cc39a0374501071c7eef4abaa11408d02fae1786dea37588479c90d627698591"
+ "c3bae1fefd6e8c40e3ff4b9f6061e06c12fdd21c7f45ddc5b78d1cbc41c15706"
+ "fa20ba92f99f58b22be27675bee081a06067eed158f8e20bf04a6e968f719a32"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.15",
+ "fa1c0f7b1015a895b1a565f32996b2b8ccfd864b95544dbb9cf4f6e1a841de92"
+ "06d55726fdf7eea2bf336a829fd2bc1209bd215aabb977d23a083f10ae69db43"
+ "7ca32d7bfe4c8825b93488f01afdf784458cef5cdd8dffdd17",
+ "25e22e6df7fc6bd4e0f61ebc8da063fe478a3ed74d68f7763435e0e374f65262"
+ "a5d7612e8678596122c0e5b8fa0c0b12812ba9653a0f273883c6264c6dfb74bb"
+ "34405d2a043043fbb0abf2af7a123d2ddbf16992e09baa37d731d72ef1996265"
+ "8a8fb010a10f7d5562ad5433479001af36d3d326eadb2e9abec7b555709d5d47"
+ "e9"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.16",
+ "828ebe2f51e58829cfa61526dded7e1f1ba311dbf1064c08ac0bb5d6716eab29"
+ "8a23d63b793ffd9d9cea60229598823f282f107b6ee88a53fd93e7ddd48a731a"
+ "2109ffedc89aeba2c0f16bcb140a0a89dc57ee8b5d000a2142175bc707bb409a"
+ "ae3a039c663d019a0bd913c13f7ff6f6b91e905a589d38b150485d89092d18a3"
+ "a762252765525d984566425b05770de9a8bef443ff5fc14833afa4ccece542d4"
+ "f2cef1e796f59fb3a4bf37cb677ae4223666c82b31a16a6cd701a0493cd99686"
+ "6c84bfcddf852b19ffc89e936179fce8b99e72fd4afc28b51173afbb25c4c7",
+ "1617559e43ba182e953486436f15b602831e42eed203c269f653bf639c2b760b"
+ "0d49fb532ca8ad01e7b4af83729255db559bcf55fab3659cebecd537694fef2d"
+ "ef9c9e762d05d2321ed688c3f7e2c05733ab4fa81b08cf79facb75c3200b7a48"
+ "3af08cb183c50927cc6169e432f7fc9b11780dbf4d3b72d2d0b85593d8b5b018"
+ "2a"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.17",
+ "bb4a6eccbdd6de0ac5c3b7f99798104a5869c1cf1a1fac7f859fe95149297eb7"
+ "79110059e269f12756f08a548b66af",
+ "277bae63e6e3253a0e204f4e6c9fe84b040b864f21edd4426d82be8f1b911b0b"
+ "d281cf114953d40209da2e9aae133bcd1855ef0a99693a9443c93f6dd275f058"
+ "fd1bb69532b64a1dd7e1d0e780d75204fa8c61c2eb5de88272cb93aef080f702"
+ "bb78889425a5f166f63b5b1a31ec5c1c26a599fafe58774298b97db314fc81d0"
+ "92"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.18",
+ "f1d111ad08e038ca3ab4e52e5eab7101876ca9be626a135917f45b1f9d1b32ef"
+ "e4ff867ab8a305f949c0048b25f5462261b1a3493b8190210f5cfa6bf7e5c300"
+ "5498deecc1e1c504f3a34998be6ad6ac004051c4e0a3db2c22eb5e14165528df"
+ "7812a20d5c7f05b940ca13e9383ae00d6cd4d0f4ae3dad047ab9c4178db66d3b"
+ "80960caf0a924dc94eb8e07709bcdb349e90fa2e10c5d526d2219ca76f8801fd"
+ "c661bdca6a93da48d045ac375134ccd6ff7c52fd15c7cd3d1f31afe504bce7c0"
+ "333a8979e3cecc53c4eadd7d95d46fa3b2a9f006100d6bfc0ed5ee77694ff1a2"
+ "4e16a544de71465290dddd189f01670359f8c6b5d4c6b6b9f5c57aa5a38f0799",
+ "0de94231c06ab187b00dda2b34e2b4cbac41f608c48c7227a6282a179e58c32e"
+ "f5ddc9764fa2dfc3fbe021ddb48156a6373cd69b85d364d89b5a32fabb2d465d"
+ "0562d4a1dd6fca64780b062a947124a7fc0b82e4fed12b8b4f726a0c8539c6cd"
+ "e21af655acc8de1e7ba9d67b87b8e777d48acd868a80db15314f355560103577"
+ "eb"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.19",
+ "9c4ecc4b2444a401bfb6f4b7244923a5ad3386c3b841678cf5e6447b8a3a0759"
+ "86c33fd001b843724dddc4212ff45ab3fecaa90a16f6b5592c515cc4ee54aea4"
+ "593432167096678f934159856d14c432e7d6d28d71b2687f54ed719e5c201100"
+ "688e85f20e79a9ee8aa4b61431343d1e99c21435c61e8bc104f2bad52960fcee"
+ "e67b85033d3aeefae413ce29701effcb02b484a031e2f319ef7ed0d6e69b2916"
+ "eeb38c4f1942ba23c2a1790ce3fe09d01b9b9fe6dba8dc210eaa8fe73ca76f1b"
+ "5b",
+ "1853c21a4a18547d867b3ced02daf0b22ce8d4d5af2b8ef5f7c8fd385b815364"
+ "8d81831d6acb5da830f67740259ffb339f7b90af4883819c4715e08c2899d4c7"
+ "246e07e5bc6ef3cfd9a04da06c43e95c772be221cfaaf6954ef93331e595ff48"
+ "921f05fce8fa0d429e0c99562a9c2f68ebf32cf1c6c6bb8b274a2e42d6715912"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 12.20",
+ "c381e60399865166d2baa03145268334184039e05335a300c2804e2bfef5a7d1"
+ "4c443d6538e16bdf9da7ad1fea634ebfe113bc821e79a449b2eb2f57c21fba35"
+ "ffcc6a7e525572277e8f5537c7b5b9794defb39aab060785d1994002dcf80701"
+ "2e1d1791da943b2b759c366bb424e42c9c2043ce788a25fbfebb87e74cb020b1"
+ "1e8eaf161884d6672bbe9c09fbb3b8afa061",
+ "199069573753018f33592af15c1d3131bf5d8ac4f64cf614d3a01bf372df002e"
+ "b5b5fc8f82ba137f83dc142ede38c58180e7bda69c4f1bc7bf96ecd3fa79bccb"
+ "ddb7d92e4fd864c5fa933a4dfc600e1083008a386f4d022c2024ff7e0b3722ea"
+ "fea05a1e02c7a63eeb40f4f4c4f660c32472a0a78923e3863a99445e7cfe2700"
+ "60"
+ }
+ }
+ },
+ {
+ "A 1031-bit RSA key pair",
+ "70e923a5a0cd8ecdf99bbe93d7d02882955d91b6efe3cec86c93d21c0ac301b8"
+ "293e51435b878bc6b34bed4111590e764676588b116c2a36a4c77ed9c90a13c1"
+ "4d23e1994787fcdb8f5c97410fcad4045b8585702cce29da11f97e79a97c2e5f"
+ "6a5fc0bb8ce76d1554a8bc47961720d364050bf27419bff168c0a7ecc8734cb5"
+ "a5",
+ "010001",
+ "029e10f6bbb7d02debb1a5d5190d6906ffedeb9d154a0f66db8780b92831b596"
+ "3e94847f3e7db1aa9148fb0ec5576e6ba4fe04d6f27832b1521812d37b22d9ea"
+ "e28008e092c67e72324267e1b1ee454355741d8de1d2a6a05074bb1ce5818b41"
+ "bd19dc6b58c8937d8ad640d7043fa11f468d6ccbec4ade520a9e159d605d0928"
+ "29",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 13.1",
+ "b5e86c8ba3985aa5541df95e513cff67612eaf2e16688576f7d673f6f1891fb7"
+ "5c9dd2cd",
+ "6b42fd516309197f8af3c73e39624d8ebabecda3ec3ce657b1117f43e983877a"
+ "1ba1aaf8e95cc39991d92e35e2db1e413090143d16467198b9b9a990d774c27a"
+ "d3bbb4352d3f075d61732c6b58ec0f66e492a3f7ac4bbcf012ed6b401feb4ff3"
+ "95cb8b218a81d61731eece376f688e66aea698b4a8862f58c91d876085496fd0"
+ "14"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.2",
+ "9546346cf22194c787888170a482f7f49217c3940dc6210ce39e4550a39b4528"
+ "22419aeac24bec198bb359d08be8196df2e757766196c958e2b159c74c1c3023"
+ "c2dbcce9ed5d0ef3fb51450bff6445db265e606e194bee064ca5b321d7e15514"
+ "230c2b3b55d5da4cd040522f7bb86a962b813f9da39e51389bc64f56e447b2a2"
+ "bf819d7a80094e2b8de27f104bb6eb2f2fb43af1d01eadca23a196ba125b6a78"
+ "579974c0eec8a5496771f67dbd5069f336e4ef1f404742dfc69ce325aa649f8a"
+ "6331cf403555e13f0810a76350a7e18d2992fab48f397f3b93c5bd5a6fe1d2c4"
+ "618ba1f59f002dc257ec39ee2f876298da90f7440ad4c6c93fc114df05",
+ "67e414993f987a22643dd039e7f9fe1cae744a7ae41d4c044fa4ed8dc9e340ce"
+ "bb1e2afb198e847aef4bc061fd800d81d4d367b0fc2f730933c19b88d4ddf05e"
+ "d98a5856de5eb45b116b7d24feb45677849dab76e9e0ccb45ba6b6f6141f37bb"
+ "ad7c191c3777113bc7388e4e4644eca94703a72bddcc6f50cf980e3f6de39d73"
+ "12"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.3",
+ "5652b4c57520b255fb96f70a30ab92eec1939956b6a943c83ed0986e2e6ee4ef"
+ "bf8a52287867281203a7a6d1d886b7005952b43b778544eda898e0df2fa06f68"
+ "380318f14a53fe55d72f8cfa6af21d93bbfc20d358c208c562d739be0001ce07"
+ "fd8cd2f46c3b44c836518809b76f3a70cf6926be069c3575d5",
+ "016411a231a738944b3e44f7885cf81acab732d1736de34c56cf40f99a6ce400"
+ "70a20aa94c487844a93cef287a58bc0ea181b2cf27d914f293b929779d39036c"
+ "4e5aaed35eee8a7fd50efd096c91a8f72c3c141c576c8d10b636fc4ddc1e6714"
+ "f17ffcce106d221b4fd7d6fe1e7cbd3f3b08f5546b44d1feb718fbc13370c7fa"
+ "2c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.4",
+ "6d57f079a3e8adcb47cf2e3ca976e03b09c77d1d9d9d8484357e912309e8f4a8"
+ "3cb50cb6a7388c414aec844671ff810651e828103a1f6a199be260f74600028c"
+ "6a7b7bb9416ce7b6350a3a6805620cf5e6b0095dfa22b54601f619afd10da203"
+ "d28190cf9b0db5986d293033691ec5bbba6d73ea32472efa3f160fd2b1b5e43b"
+ "0bfad31677305fef467244114ee10f5cb2d67b478323a711041e294c46b2ed39"
+ "ccde079c877fe75cb875144ac31eb031a738a4cefef91f017ba71523f5124818"
+ "cf48b972bc47c8f2ed356f5bf691fd94670bb2",
+ "315ce417d0bbd73e7c4356797e73ed7abfe9fcfff1a5342899a7d11fb0d0542b"
+ "fcab66de2e4ec07c7dc2be7d797290a30db8c407dd16376588a6dcc1a207bf7f"
+ "f311540faa9dd6f19a73ab25a7496e682fa8a7054081076c1a02157be63e7f64"
+ "5de82df7c615503fa83b4edba20581812e097f65056ed417f6f24803530cf818"
+ "58"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.5",
+ "bb75446f787823dda2422b1adc7d7fefd06a6e9af5c04901ac5b99913ad6298c"
+ "9d1a3322e8b217e4e0994c42204280d404d01eceb5ec53fb86f761a396b23ae1"
+ "9d467905a0fe8050b895d8ba3746685c47439f90c3669c70ffb81994565c4df2"
+ "a31eb2a452bc3cb312b8147cec191032f38f3b3d89d7582bf18e7b7275fb4f16"
+ "ee89567e2a56bc73b3e2e109f9940ebd10b9df2b88accf0ba18e5b349520d2c7"
+ "f5a31bd5226d12ec35bfc9e36203e13506ba12b756c8ba00af91b85b0b4c07c7"
+ "f484adc458c926aaeb4f082fec987d9f276b8949597ec0401bb71a2fea9c7b74"
+ "e0dfe6aa52ac8b80beead336a49db22fb3",
+ "53d0d795bb082f2001036f472c2ece6e7d2db69f292da7213675c7cbba0d33b2"
+ "3212f8f43a4a8e09a6a50e019bbdd59a58898cc46c58a46e42ce7ba093fb4692"
+ "f383de33a9a34f47c7e61938bf8a6adaa88df21296b4c67b526835f757f2c26c"
+ "1d309d7cdd5ad5fd8f61f851ed23c4be2abb627dfd817f8477dc042b6a2e4069"
+ "40"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.6",
+ "883939d149a544e62ef04c610351a2dfa252eb9a9d1e11ae54c9b07ebcf1fdc4"
+ "7ec1d94703411da415f59fb3e5041ed9470e7bcc819b5afeaf860c016ef125bd"
+ "08a6cb8bcdf3b93a51dcadb2f68c8cc3775514282aff7567ec65f270d02beb95"
+ "fb8fac24095e1706e48b524865bc14461d3ece8c501c3d802ade985ae95cfe1a"
+ "b9d6b9ab0d15fcc8866f7f259c5e41c02cd413437e7d6ba7f15b0a70dafbd55c"
+ "0edb6b8075c27cff3b289e6c99e9a884ff7f086da9f75d6a4cbbccaf52ba25c6"
+ "342c38a76b44e101155df755e39c14862e220ca36ffbcc832afecba87f8abd96"
+ "0a577f56ca6cd8e99126658f27ac6e53c442ed4766",
+ "1ec02ae6a0a3f611992961ca27ccbf296e11361832e1ee7520569a9aee06345c"
+ "da22b4fa48fc345e4778bc3ccdfebd2dc5a6c9d48451aa441bea4b951199654a"
+ "e8d2f7522e17edbc2f51ce15cbcd366f4939cb53c3b77081f4a73750054e00b3"
+ "0ba2fe58f6f02e36a862542397dba6a3cd2277708819e78a2d876a23a5a269d7"
+ "75"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.7",
+ "4031e0def4f3d1ad9bc082770a88a1d9b4b7107548cdf8462b0bae3d994d8ebc"
+ "4da044b905dd8ed91a1da676727822360ee2b6d5e12bb70316d79e8abb82a643"
+ "44afb3b225885c",
+ "0be5a6d043be5d27d1d51d9e3aa61d92c9d84323119b48c84a80389718d7a1aa"
+ "f57a9a0d214f6506484864dfae85db7b8474073a8f977b42b53b407e44c7c62b"
+ "168d1e7778f4f27857bfba85dddc8b0e9f0e9a5b6de71a0443720e92bb88b077"
+ "cba15d3f6e2be4d27a7c509c7dc03f1fdd4fe338a4e545c46c034522ccc0d45d"
+ "4c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.8",
+ "7fdc96a4565774029fffa93b39f05dee9f84fa8953fd0f6338c81c9dec6cdd66"
+ "1ffab96f0e08eb0b9ba9ca5be17b57c4b4868fd5341154de50277113c7185341",
+ "1dd21fa495be7c490f982f69eab14e24daa04bd138b7143249cdccd78ccfc910"
+ "6acaa03ec876694232566ec6cab9122840f669c800f2ee092bb9b6cb2a4542a9"
+ "0de604c4f105000a3a0deccd3dd97a3261fa38227eb381a1f8f23b6665d28480"
+ "dfb72117882ed8db25d76de40de2fbe72dc394ec6fbdaa99c64fade72978a51f"
+ "c4"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.9",
+ "631832ab1918cd020828e47ae2b4476b1469f272e30e53e596fba26b402937dc"
+ "44c2ea5745c79d2dc64a10e1225ca0b6929d4954bc5d374096fd878dd101f766"
+ "6313d9a8f826bc671401422c1cfe1a6d01a4d7864a14c60cebc2f070914ceede"
+ "b1782fe540a0a5d2578444f9b36034ec77d6b803a0c9761b327592aa4846635c"
+ "563f1c6a6df68faabce497af4dc9a3642b75a4a294d308568e6d73c11db56724"
+ "042b55c3a24a7bc7a1050e4f448b6a",
+ "45d3a6ae8f48355c012b501079ee92affe3c9e602e4a080cfc94723ae96dac2a"
+ "66e455a40e728b2a1b27e62240554ec7c5c0ad6aa00c0922e53d7b12ed42c087"
+ "322d1536e46b7debda8095f55d1e12bc2442f43b4d128fee231dcd6f8c37aa6b"
+ "cf4fe7b5e0dea9c6709d3d91f9e42a53168a16b6fe997b5dfebafb46ed9aea5c"
+ "66"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.10",
+ "8b043d90dae3416685d53a5b4c3cc254cda0cbd23b4e408de820a4da7ade6dd9"
+ "5d4e1a97e2312c3e84261ee0b6cefe60e6b082fd5965efa1648f4fae61605fe3"
+ "55332700469605265347e6547aea775b856e5a46c341d29952bbea927049963e"
+ "3740208cfb0b652857b6f52e366a170be34f13d35846bde69720462001b09dd2"
+ "68b89b0900318e733db2009efd9b517741e510d3f394f7adb54559b157",
+ "6b278f362c292eea09b90bf353d143f2ca099ff879573479df2aff9b250d1c91"
+ "87c6a3343ea14c076f2a20c1a19db26aad3548ec6fb3b2fafc751b59082d8b23"
+ "c82c8a51f7faf7a4d4a82398bfbed449bde4ee9dc8680160666fd9c774c6aa57"
+ "7b4ec54cf0d5bd9e3d1afa9c3b4b91467678c9d4c4fe400aa857a3b0545bdf84"
+ "a6"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.11",
+ "3b28a6092e470898af070a087c4553188de6c344bb0b5fdc7f66fbc52dc93a8b"
+ "92a374112037d6a43286128acef95a3505c0abb1afa62c48cb2136077f8a0e0e"
+ "0b5a4ee9b2c77d7a0c0b53f38a51cc3db9b583b3aec07f1e224fcb3f1dad195e"
+ "058659a9d11f8edc7444994686ed62c97566e9e00cbf8f0dbc1716e6b7f0f88f"
+ "e89a867a41d643135ad8b18aa143e7375df19529",
+ "3262fe17e44e5ecc843170d3ae2751da1f48d6e961d81e9359b0982c6d61308e"
+ "bacfe2607c538c170ce0e72a07bc01487b295c36b8e22afdf6e7fe39c03a5c0c"
+ "3661061f23fbf5890ead59f872c946cce0f816c9ed3a2c1e11f8f74da1e97a39"
+ "0d534d785578a2455fcd874783f4572a15f4937dca98093fd0e9990af0005256"
+ "bf"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.12",
+ "4fdd6a3631ddd4bc3c76071902a227fd5b3653b1f970f2b767ef554e1c75cade"
+ "819d8d1fca76bc10541cbf8b1d8b0e7255f95740",
+ "29cba5b43fa3565775893491b118578b14b5fa1eebe0c80759a6d191e7c2131e"
+ "e10ac5b9b8ae1aa7d696c98488a35cdfa2aa006d91bf7e05a5c1909efb20dabc"
+ "82133b6264c042180c2cca65459f66cc7eb1ba75d15d4f56c7528aab2838e679"
+ "537a4c8dcd37d4b4ca825ce165fa4a97158244dc87c061fb12001e5533fbd4cc"
+ "62"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.13",
+ "590cd23050e57b28d5c2185ead60b1e9529f2bd52613eb03f6ed1aefa4a67288"
+ "d5a3a34fd95ca63894af3a40cd68873a1f37e354d30414297b19254bc6c1a3f7"
+ "a47520eea56eff77dbfda6bd7779d02fd816fc0e99919fe4395eaee5b2f5f032"
+ "cfc4336f9cf9acef74dbbf4c9a0918da6558b4b4e3209bfcd71ddd597607b6e2"
+ "8c3985dbf52ca7d1d751cb8169c0b1b13ff8b65b731e69dd2effe44c636f2b69"
+ "9535831aeb5e62902f",
+ "67eb8957ce4c06f7391d00c7412453f4b68b3303a1292554e2a5fc7262c52e74"
+ "bed70ec58c8950cdc4315a8fb7c6801554cd35781d44fb5e57d68d59a00f43b8"
+ "6d53b84372d556e5a4153cbe6b397c4c9c6800705d2fc0c548645e11b9d8d512"
+ "b2dd9bf59f3dc5d11c3c773d59ccbed9e6bc14320910cdf83b465901b746b596"
+ "74"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.14",
+ "808cb97613fd878535801c8008791510a5fe866ad5b6843a6e0019a0fcc21776"
+ "0354f60cc699fbbe1adfe8b00ecd6a36a2b5a5a1faa23d343820024e3a3197ae"
+ "673c",
+ "1c539659f872469916fb0007ef9e48574e964e4c0e6a2fa74b1373fd60b664a7"
+ "98ac8129c08c12cdbf3749750be125602a7154326767327e92ba57b5e289b5ac"
+ "9d7771b4520a7a2ce66c5eaf704afc5a190fa60be1376f943d2baf70523e47c3"
+ "defc0a25a6001831a37aab0cf1f6487be37f0e31ca7db5ac41b5630957559369"
+ "ff"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.15",
+ "57edaa0566251686f65205efc62660e2c2e04fa5eaa3302de87a3f6b491f7fa3"
+ "ac7270cc76751a436942ac765ef5f4749162d7e797126bcb8fdac19cf18dcc6e"
+ "ff48593c05c8893b591a51332fa26ab863c5eaa4d751e8d1b19c582690b5415e"
+ "6a89e05f231b33ac38c53f95a2d5f91051c2ec6ddb2b6dba789d553adb9f10c5"
+ "83597036d3486fbb32172a1c11079e5f09aa29eb4674c8d7bf5bbd6d057e6b87"
+ "a8b3aaf48086d721cbbc8efac6244d3239ae18f16623fa528e2e70fa25656a6a"
+ "4a2292950fc928edb81c",
+ "33732fcc23342c585138b25b17c812ee3e9d3da41f6ffbcc1617a2ee75cc5b25"
+ "01254fd1976d258800e905d7e44a0ab6fb4b8a88bb7bf9317395303ab2fca431"
+ "28486a2bab36c75ef6aa5eb3fc5bd555b3ea79124aad7897e3a434dee7926371"
+ "de2d6d237e89b03b8dd7096058e2a4b32cb557c7ada298a7e2edd3a3a3b529b4"
+ "d2"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.16",
+ "083376bb82212bf880be1285653af2cad625c52e94e321436877f725a83bbd43"
+ "f4486d896cf67e31391b8706f8c0f8f4bb1ddba95c332f034f3909113f655692"
+ "60a2e4f10406657c99faff001fe16ebb896e9e18115af1d4986c8579ab5652cc"
+ "ca4774",
+ "2af46c00d1d915941e212a7b8d8105ee0f0ec480fffbb4f13bf28d73e2b319b9"
+ "84a7b7c8367adca7ab12aaf53acb98d0cb54ee34204c908e60c7c79efb42c311"
+ "4a02589e1ae6afb5975354578c1435ecc89c116e9026b6bc889ee288ae4daf03"
+ "47cccefc5dfd1ef83cb86852eeffd84098599b725bf602ee620bdf44afbd84c0"
+ "cd"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.17",
+ "8c874cd0ce335139c08d760b825eb9905d",
+ "669a8ad7cb81ef2187f5a85647684b72484aff279f0af35435867cc2b04333a1"
+ "96eca6cf44a97a1bd39d0f6a0ff9595702835bc80a72d71404ef3f46fa3b0d20"
+ "e86d7a1d5f7efc3f3b8e8a7e37e87e27a99feba96ad81320be8fff78557d07bf"
+ "bae21603a1368cafa5ae1d1b630aa21ff20e4585650a773d7e2f5e7f51729719"
+ "3c"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.18",
+ "cb3e6121d38b7d97e18ba15c493d1ac32e9d2ef4e3bd16df9c67e4a196e9247a"
+ "8d0c24b21c4ab23e77d6db117d591195bbaf4466825f63978f114085281b79ae"
+ "a37e32c6b36c1e9ddd4ad1236e97fd427b4d976e07649dca4f33a89c46fb8c00"
+ "b4267b144704",
+ "568417803a400e9d050a4320ae7b7d8d248e163650869d9fdd100cc1a6b9bc29"
+ "1c3f23f1256003164f619dbc78635ebdf089490afa5aa00b6f97eb0636c3bba8"
+ "9d86360afe260043d861a74f64c71d9cbd31eae2393a1af1561f1ab92caa76dd"
+ "1e76ab2333098c83c2d99fae827398758005c176cbc4a2e22efa0e6c12f4e342"
+ "81"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.19",
+ "219a2f8d0b000aedb5f185455ed3ea094c45426b285bab4a07cf3d0a2906f3e2"
+ "03184c2d3d81a809b89c9fc48bc9af9ab32f84f15d81389c4edb0ac68ad09502"
+ "e3f30c7cf645102954b297c8661466fc10",
+ "03835d9057e2b821dc4c6eaca3f4156a56550b6f9d7400fc5c5195a4aee4717d"
+ "f32929122b43273a079a24f99dd9e7c34056aea4fc4e457d8314ef34427f8e20"
+ "4b81bb4903fb3e779e389e41339068c157d9b09f2c5e99cc54e6ef86eeac0e19"
+ "f44e33e707c4261a0a83ceb422f2e06bccae3b8bba428d7557152f40846ec011"
+ "34"
+ },{
+ "PKCS#1 v1.5 Signature Example 13.20",
+ "e39ca40d2e9d03ae0596f60eb8f609993085a5db156b0d5098fe5faac55f7099"
+ "3fe176d2d0c038b860bbf9a66243f5e78e6cbe526ecf25128dae319656cc321e"
+ "e80a50531490c9a6243fbdb0c5eb4cd642d2611505ae1084975738ad84621d67"
+ "f5",
+ "4fcfa57397f27ee0f8ae75a0a54d54b0c51b957ee63bf7901b6055cc3987c32d"
+ "f7220e166a71606abc78f91107f974dff7d6257c256dc6ed7a69c3c99f9f89ab"
+ "b58fe589b7ee7cad0f48c16010d046a9c4e004bbe1a8297968d40bc70682ebae"
+ "a448525dbee16b03bd0b6526d098d09b6bad9aba039305e2ab796902086580cc"
+ "f0"
+ }
+ }
+ },
+ {
+ "A 1536-bit RSA key pair",
+ "d870a776cd13ed443df39908bee2cad73c485fd9bf06321322887fbe655c08cb"
+ "e4c8f63e254fc91c75f0557d901d435b0e8ded82d49173414d29860324e46c1b"
+ "030dfeaa29d80f9898c2c5e101cbf6daa0628978d415b502dea26de6561c79ab"
+ "065c6dca6abc4d4d4d5e9f5c74cb3e6a5af71d1f90fa5eaa1be0ca947a70a39e"
+ "fd315c4df21a1a821caaff8dcbad13b29c7e82aad53c64f582ec9ec31e6bde82"
+ "ea5a5f4cccf0c457b888f1550c4ff8e1c178a76a46c196f4bef59e61dd944e47",
+ "010001",
+ "05888fc77a43bda7a67bd15847650df185c185edcfb3ed58cee3b57c5d2406b7"
+ "8bc055874e35e57adc4b0a2c7d203a661c0fa5d857ede607efdc9568042bf0d5"
+ "99f4e4235e917f0894333a92df9462d9c10af3dfca7049a1eaa63570139883c5"
+ "befebee4e2218943d30fc645ffe8b914d218dd58960aadc121715bce5ccdde4a"
+ "2c73a8d9d86a4eb6e455dc924fd74a0b1f75691c281bae914d699ee259d85c5f"
+ "b5dd999ebef9b70a4bd94aa4fafae26ca784d32fd4e077dbb6ea693bcd6d27d5",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 14.1",
+ "f7a3c67e92a787f35dcc47aed7d6b6192967bdfd00a6acbf6f7efe46d3acaed9"
+ "788aa4f1db184402249f9acefc1c7dfb1e690d24738de86fa5b5250f979ebd8f"
+ "778eec0d7fcf731fa225086c866564ed3eb154dd458d0500282f86804887d443"
+ "5eda9a4436a8e923a20cb4b4d0e81c91114bdc0682278ec258860799b59c9436"
+ "f43a53cab4c4cd",
+ "09d1435bf5a9c17203d537fe57df987b7a51f34b2a14097e06a0de563be7d64b"
+ "4ea37973b4fe9973a66a3f31ba8e07e9117b6a1ee70961337b4d2b0df59810b6"
+ "24085118bda70ac74ae43e2fbcf89227630323da6830f5b1a2b954f1b15aea07"
+ "54df2c5118579516e877ccb0b1286c5724655ef8d29185666f6e9bd32a6bd9ce"
+ "9e1ef94729fc67d6a30e64560ecf78bf8e1b2b40e50605e25ae80c386764aed1"
+ "1a0e71449049c939b2962f6c2417a358cdc8106b12b1a5587639438af1a68d32"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.2",
+ "2a133003ab67cdd2e83b44e9e9dc777de01f4d233d22e7d2b4467f04812a3aeb"
+ "ffb10a092454e33b9e7028249328747ea14a11c798ac2e146e4e49659ba86067"
+ "db64e9bd80a7021aabcc22856e810140c20fd8c6527badbbd9fa5953fa77e685"
+ "8700beb6c74d5a463c9da861133baa5bd6a599807ae9162e3af3a348d04a4edd"
+ "2ffbab",
+ "35e666cfb87c0488a86fdfed5f9deaedbc4674171c318459acaaaa20e1cad7c5"
+ "8604140a80ff7f565bfbc86e90328d4c729b91bf72a98db701c1be638a6e8f2e"
+ "468f20392470c7c5c34442d51b1b155fb464b8a556f4a170c02301fed0d1aa92"
+ "aafdebc3f18ea8b4d71e245c2526f6fe665de48385f46ce1bf3312fa8928098e"
+ "d3312b61116ca7e423204ef08bd2df3ad7bbc850098cb02683266625bbd95982"
+ "5135a45f03829d096fed18b20baa3f9d44b007aa241f92f8886055d98e0e0704"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.3",
+ "58627ffaaa8e800a8be98e42f51a83611cfab7ee376b34737b3e48e1bc1742da"
+ "a77de47e1a9b293377aa",
+ "3d17cb386c88784d359ad3c38dbe888bfae831bfb8edc9d0e801e7d69e1dd4c2"
+ "441d68fdbb35126c73a4edabbff54e74fa5109dad8b5c313d86a79e4d4127660"
+ "fc2a8e1c93fa8d092accf01cc18a606cf07de2dc3e7b55331152db01b6caea1e"
+ "cec9093199be62c3e123e2873113503b22030f168dafc4e6bd065ad2f6b1ded0"
+ "5be0c2f9b67bdc1a3bb18da9594c957da4e49fac3fe76e0766f74eb0d523e4dd"
+ "1ae759dad6b9b908b7fc8b97ef5f4c8292320ac387c3508b54cfb85d34f6ad39"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.4",
+ "0f0f8d3c0e4d2608afad5a888ea14b3f6b2b2789dd2212b85909e64bfb104d0f"
+ "7de427d14a9ffa855e2d4ca2442336e559568b28415d60cf8063de5592171b26"
+ "9b3d763351c7f7d9d25809e70220ee30fe8a00b95d4c202026897ed2c61d7ad4"
+ "3aeddf36b5c2cbe21e0086dbd0fdfd19e43f0277f3bc95ed55a34af930916602"
+ "193cfe04514bd26a057e562a1190c27eaab6c322fcfaf4bbcc7f20c3779c638d"
+ "7bbc07086cf75bf83996db4463",
+ "50904512361050872eae80102628b63d02168dca52f0abd87720ea48050d2c62"
+ "061aa2153268bef8efb34eed46171a6288e504d420f6fc145138611e75ed3cf7"
+ "9b4d102664d8644ff3e9e5dbfd71cdc27a210efb10be90275604f8d449148b3f"
+ "86099039c33aef90bf191b3518eb459da3ba14fd0c72229dea5fac2f7dade108"
+ "5c8a2370bbfcfa2e3a9e63ca224f6de8c8d297a3b1f06f1fc9497890fd0e0e13"
+ "887facb152d12d96392528ef28d0724331ff414030c7a63855813ccd89fbdb1b"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.5",
+ "2665cb5ee36aa9bb1a5cde7ce8",
+ "4f38c2ba84c50d46df531091b62712149c1f42dbd77e03d185ea96eda802337c"
+ "22c1130bc3becebf1539fd11893851dae3cc1567cb6c73a72fa1c96948682112"
+ "7e7cfea1363eee952b7c6eb59e102c6657c08035272cdf4ab5e583ed737ad028"
+ "ac1cfafeddc9073dfbd7d3ba3da9e8dcd846fa365c9ccd8e9b39483d37073c1a"
+ "7b782ee7121bb1a2ad8bf5f8ed6e653e924debad871b744339e5ae7e96f60dcc"
+ "45ea5d697d3b1cc7c5e8da04e92be06cad2e614eac318aecaf12d5a76234c2c0"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.6",
+ "7b7b6161020fafb488716321340daf2c06ac43ce2132868684aaafab1399653d"
+ "353b2693ad73cb55b71d66acd01a160cbf743767bd96e7fd1c7a13320665bbad"
+ "1c4a0ced26593ce89cd82f546bd4d1b1bcd82c65a466f99da012a41e8c412069"
+ "810958475b4d9c2f80d82d06414c8325eb4f2c5a1166f1f1d2d107d48c",
+ "d5cbb6c7eff4a63ad8250de94cc29f7f31a0d7106d5d771b715df8a675fd1634"
+ "d6e8ab58875cc4c1517b2fadf4e85c1cb8b85360e0687587d148089f3f48b79d"
+ "98d2027c50770b334f1252ac0c3b2f036534c3c29722f6087d06d706cec7c4bd"
+ "ce1cd64f7b4e0799a87aa073ea8320292b8ec82717406d36ef9125e41fb5d53b"
+ "ccdd622d388fccee60a385ec206a715dc54d7877bd7285d0844c25d593779791"
+ "278396ff9a8a91306a54ea76607c813f801f38760c3a814b9396959c29dbff9d"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.7",
+ "2b0ad613822878a572e14280",
+ "89c81084daa8f914b7e24455107417ca621c9102d501eeb43d174c7bad381db1"
+ "8d9533c3411aec6057ca5a4dfdc3f131c888b88f013003d617e06d64479502ae"
+ "7e424a5dd637b03356404d260f5ed6b8cb16d2578528cc3e8500346eb790bdad"
+ "41b2e36ca6f19885e3f6f51086bffb6abb9c66336b49473464c5d7ed8e9ff85e"
+ "11aeff409067bab0a05c41e8151b8be987f3f5958e3e6f26515d96bf234b22ab"
+ "91c0857b6c08a46b0305fe044ca9aaa0d70a2758a1ce431664a8dd79408c16ba"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.8",
+ "36938c8c7c6f7e355234db5a32a64810db502b67c6f592544ffb27eb1f22e06f"
+ "2d638b56d5d2f7d19e9e271f2cc90cc0dd36d6cc2c06178bcc706aef20e56a35"
+ "8e524f6316769c54b6de2dd5",
+ "a03753a5fb54aa51f6dd8dab91f19cb865568485f8558f0d103f0d2b6d78536e"
+ "79c815c4a037bcaf11b69d4cdbab035abe216f7152f630ffc79f849d8dcd463a"
+ "ae6ae97d3df15a9e73d23f1878fac754cbdd571afea5d25357d4b88345f489be"
+ "0d67b9bfadf023f26e67315ed5fbf391910af4969b724bf0ca31c1059f8a3913"
+ "b48a13819c236c9be8e824ca4cb619fb7d784cd5f9526b397c76c5d0c60cf7f4"
+ "8d11196e54f72a08bb42f75aefe38f0b91b42bb806de4b87c9082f721a6880ca"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.9",
+ "60830c01cfa86ff2dcac7af9321ee5fe502e0e7a6facb73e3f6bc902640a6109"
+ "5f646fd03e80d58182465331e75d6611a0977681627086241729de9f44ab4394"
+ "9dac193673bd6cf87f5d65771ef87281633fdd07bac409a6e232b601aece2d",
+ "4058f6e0240d851d619395a75287a88fafd8dc5600b069bf19dc3e1921e117b4"
+ "97b82b3c520269b1d1128164fcd88dd2b46dc85c42ecf67debad21a3b9a15542"
+ "fea22606eab582fc329711ffc07f4eef1f3bbfe0888cbca485bafc1188b0afe8"
+ "09c9aaf8fa3666b9c9058539db1ec6a18e5be0b80144d2c37ca614c090b4a7f1"
+ "3458e0d3a4cb0cb73dcc4d90806f61085889eb5c9b1409def360fd1c2e49438d"
+ "7c67d79dbd9a592ab504c4715f65b29d846509951569a8c37909f5d550eefffa"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.10",
+ "635d2203ed9d5b9120e31bf69d305be6068697e35ce59c553e508dc77b073ffa"
+ "3aaa59f996c30b2e686323819fde22be6c8d53868414b3545abf435768a611f0"
+ "c1a479a0c7660d535e805b5fedc3779cf0c52c3cd040ab6514c7f8133d47b0ac"
+ "c6914e6d4ad3c4737cf51291094e859433ba3066e19d6aa2da896dc9d95ef9e5"
+ "636dab35f7298705c6d876175412f8842519ffe16cf74362ab",
+ "9461a1a841423ed5cfc6089a74dbfc53731103bf4985ddb150b0e9380d3fe0cf"
+ "6d457c5c68a7f25504022d695ff842118ebf61022fea47fa45f7c1cc726e1de5"
+ "0bd064b3bb701657162b88c0b910feb72f487a5c7f4b9ecfee24e07aa2d198d1"
+ "13cb845d817bb59bb1da24a82b91c2fe3fba895183cbd9c0fe0ac0be64fef2e0"
+ "139205b10bcabfe5a3a7a890fc0fe78dabe1adb5bd11448503cb0dcd0b68f160"
+ "196e9613e29fbe9a3f9406ec20c030e81ec30965ea019c17aa971101c2e53059"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.11",
+ "87fba989f3cc15af7ee761c088264ab7715239e0b8c8a9e48e11db68033139c2"
+ "a289ea426ebe269f5fb707090afb891a49ca05c0550d729bf4d37c8f1da7a3ca"
+ "2f4387a40b5f7913a385f55b8141af36be8f571665f857e77a5c9ccce6ba8f2b"
+ "e46323cc5691566ff4b6d7854304b93bba1a1759dfb144c9547cf2bc8eaaedaa"
+ "4f1dd252823b7287ca555d2106089a243e5dfe8fc31d3f46222a68abaf31815a"
+ "947e5857cf6a33170eccb6a5e06d23cc9d48eaf6cdbc",
+ "0b5f1cfc253baad4b983f8fe050d4a017cc466980ebd23c9d55343f5107e041e"
+ "b6547810fdba4686e610832f9282edf06604b0abfeea38013279177940997b28"
+ "902b14db379eeb4f44005dfcb0036803c9f125bce1f2a82c4d3007ae96b848b8"
+ "13ec8c97ca3f710a9ae0dbc28a55e05881b858db557120f33c59cd4360f9208c"
+ "74b27ec65d11ea41fa6a9eacf2a61168ad07c209948f35a161f41f87540ea182"
+ "84aab8d8f9786131f043902b89c17a560d909464475a0dfce58909187cd6e446"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.12",
+ "4b5e80305cbea90d637fdb2347c6feb67842ebac6f903db5a71ebaab8a1c2df1"
+ "1260a1ec907b8b634d37d36ed8de7d0da103bc4a9e933fb7bfee591cc933299f"
+ "ee460f3542c978f307ae052464f30620cebf3c9a9cb6a901530c1d5613df0774"
+ "312d4b5f",
+ "b6f03d35335007a747ae686760f9edad0889d2d4ca0cb88b674312d32c552b7a"
+ "66c5a9528c014b58c849f231a2e045682e3bbb14c7f95ff8bdb6587f2511cc6b"
+ "f9243960081103d47e7769a177ebdb91f12873decd5dc067e45c2b2a044ffa3f"
+ "bb04c20a3dc20138403ff25ca0ebad96e4859fa4a0d732852af350a275699a94"
+ "aa6e47f217e383ef8fce8eb6eed7826d7c6158fc5882e4613545fa26eee0c9f9"
+ "3de7a16508ea161970460d6a7ca770f8de8ba93ceaf397ddf1fbcee282a1537d"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.13",
+ "e5ad627f24f4117a0a6be4a55fdb883d75a67312154a718923d0e8f5730a54d8"
+ "ca7c974e4d59338bb571305cce990cbbcfa91ea9b773b83d7a1f0ffec4c6b143"
+ "fe05058bc90ce146f369cbae3b3d99705ef43d0721b8",
+ "732986d4eddb8a7e9b65dc016dd571efabeb84490e88e3e73b63e80d1cc86a45"
+ "2dec29fc817e8ad4eebddcd97c745bc4797e54fec6ace291b196dc2465f08cf1"
+ "ddd217e77aaf7d50987791de81b04110d11ab8558906604eb9d92b35f90075af"
+ "42280145b088e8753d0db73cd3a32bd19cea3538ee4f09273ef66d0705d45ee7"
+ "109fe595df55767b3d10817227bb6ba39575b85d6a35a2ffb88cb267dbfc282b"
+ "b8a3dee02ec77b0cb8135570f8a7d7ad04341a0864e67ff6fa0259a16974c86a"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.14",
+ "03e39ba7a80c771416d85263e4d43c6393dfe796523b89e0a461628880800d8f"
+ "c2431b66305409e06c95ae7a17d534b1e84c199dfe731da949f164571decc8b1"
+ "66beb8dc087cb4869998c2",
+ "60763beaf7c3e22b3b22dc44d947826e23fcf96b01b7741b24b1b9d93c07f0c6"
+ "4d396798bb589bd425295369bfb879add342cd76280b57e6354f6195e842fa2a"
+ "95f1c46f0b70786c318de9a55a8ac4545ee7cff399c678e578f8939ed49e84bb"
+ "a9aae57c1a36fcc39486466e4012f95887a68110f1a48467e4c234f581c5ec47"
+ "7106ccb3ec8617b4be219337448fe72e25deab53eacb92e5966295b3a5571219"
+ "58dfe79ca472f79efbda1dcfba9dbd0f976732c093b98ff193c902987a426c0f"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.15",
+ "d4c235967d4e87b6711e32ac7037a397f99b1cad95a188946a48640eb6b7b003"
+ "c32f85a121b09ca4c8bec0b82744aaf27d166cefc7a9702ad31dbd15ea2a185f"
+ "5b9ba642f949078bc609b9a8a33692d7184939d1f9eb426a6db740ead94cfea1"
+ "7feb0618d74d9a651688e90b9bb70524305d618c88a55f454450e0c585d3a8d9"
+ "8165818f363b20a252492e1512585890a8c320a7187158ce0d4e4be1c701f8af"
+ "dc545c4dab868d41d41c21c2cb1f67df7953d5f7261c5092bbc4332ac5575b6e"
+ "0e03149c040c3e201c7915ac2022884ea0e6c21403f0b44e0f71343fc9111a7d"
+ "b2f5e9e509c2d89784efb22c31e8165e0e936c",
+ "469f08bdd03b75640e8a44a07ca8de4bacf8331fe39c44d23aa7b581dc3f00f5"
+ "421b5c172d0ffce91497d3d4b104f56a98ec94f719271e58b43efbd876e1c131"
+ "fa97820728a5567555214cd94a18fcce5c2f53b19d1f3c73d09f7be1809738b0"
+ "3ce769e454ed4cbedcaf43c48bd39df2f8bb63b8fc4d0d4d5b204fc220013a66"
+ "8c19f9750293a4711583882645dbf3ac4f839b6fd1cf3b5ee8d734e1da374d91"
+ "d89ea318e9183483f4a09a93514af54f75d0a35651b240f79f20a2977d14578c"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.16",
+ "d06adca4c20f0d9f7be65a20327c294756e3edd9e1d39d0f95c79df1bac33435"
+ "9fab943d8545a3baa37a59295c58b237752b8de7d4323c56e9d7cb0c7f831d54"
+ "9cb38719a081d58b6057ecb7429e2ca607cd1306355943159dc924ad3e9cb13d"
+ "0e71eadcb005e184c0c2ceaaf9d74a1c1df6fec18c97a0",
+ "9fd9525c15c843b8069c15f26d3f95246af37a8b8e6b939ddf5b3828cdb62cfa"
+ "373a92ecc41384a877caa090aa13c847ef2829ddca14142014021481550550da"
+ "a29de2ab7001b855c9342f0c90bfa6c3349b2c396213ef70cbd84bb4ce6ef58b"
+ "176e9f6fccdb6e46cac34114a1b9f98a8a32757bf75d6bfc455ade6a01f96050"
+ "1b79f5fbe3b38fca03464e43d49663c79ff64d32981e4480cdf42d8af8daa7f1"
+ "2b81a5aa965fadaa3c03b7ff22d3cfdffe3cadf4d5989ed14c969a6e8c9a1e04"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.17",
+ "3a6302d79e26b555c77de92a91e078571ed1572ffc3e4fc905ce53f104b32200"
+ "957eb2b5e5f3e3fcbbc162f9e525c706f1dd04fcab516bc18a8e4f88a938a5b2"
+ "5685d78ddc9f104e49bf5ca0b65a4b9657e04a71fb50eb4aac22c0bb93f60cac"
+ "9483f17713553dca4b31e2727b32e350fe204cecd9a7cda4dada2e87ff6f2b73"
+ "e7b0781e212f34fe363610f018a799373755ab46667bb6525d7dc7a0e8289017"
+ "f5487fa692ef2fddce38ad3f4530de7ee5056670a735d378d1efc99481f8c9fb"
+ "eea99f566a0b6e28462644a6d9c6cc88fb",
+ "b757fa747c5c876766f358acbfc7e7b80596368d0d862950e555f471646f640e"
+ "851d612a556f55a74a3292429e4c14f78ba3ebbd9687f308dedb3cfed71f4a9d"
+ "d26fa5122f7f7194aeb63bc8b75c343187115a1dbd359590f7ff3862b70885af"
+ "1ca934b8cebc2cc9e647253fd1327a2ed4244dc8f58555a6897ca3229c801e7b"
+ "f628f525e6c948804d0b1b6dbcd7902acde7a25ba591d886e28daa8ded5ee401"
+ "e34e6412f1e644eec12ae94261906a172611dd5a9867789c419034688429e906"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.18",
+ "9dc7ce1d02cadcf10df1110456b8a7a5ea4376b27e8bf8cc8db81049fda3fbd0"
+ "db8a3d0f6bd7486b8d84bf9ffd4b641752df7edf50865e8e58ad49f7240e47d3"
+ "fc985edb596dabfe01722a227760383ce24d4a05d8b06ef5b96f117d81",
+ "05a95e11b5bfb01dcfde3efa9f313d81bb0dfd46de63b0658056c53af7ad9e89"
+ "438b7de78ff8ea88d072b1749a529f1cc9cf2cf32e5ab720e069b4906d282a03"
+ "dd78d1b3ca2a3f925bf51c7491b73ba0bf54d50d971de5b27726d8fb3ee27734"
+ "97df3549517eedcd9de68d90df35d3f05081151adab5397385abeea72b69bd0d"
+ "e18dcee9a2be00e91a032403b1f81bbc0ae731c6c0d9cfdd06c331ed89d7de1d"
+ "e1df46cf09ce53df1597fb6994681c7fbe94c9b08e50aa1b12419602987f37dd"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.19",
+ "87a645611bb191853f4fd9b740b2de4c163e7562b11762633e72dfb6f6be7efb"
+ "9041a96582943ab2018391c05adfab464dd6e33f960ddbf3b17ac62bb78afc1c"
+ "6a45396c0908707c62361255cbf09bad959b3133da48d532ba7ef1d20fb6572a"
+ "1f0ed6f2c6e1bec1b17cc319baf72a198aa001b83d4e9869c34090f229a9c7f1"
+ "42a74e85ab3ed51c69ac15fab4abe4671573cf5ad2b58e78a944edcceac5ee58"
+ "bfce66f40aac2abe4e5fa072dd0f664fac811aef084210e5641b9cd08c8724f4"
+ "b41eed1d9d4a18778046597bd1a27bbbc056c15e43c038ef375b435e73a7d32f"
+ "015016b78235ce75a7b762049968e9932253e42ca976c8d8dca1bb2dbf",
+ "b8806226fbd3d97b79f0dd1d8cf9a235e51b94b7e223ec68332d686ed3313ed1"
+ "bef6887023af7a5c99df0368a349c6a594795b623536101342690deb5fad9023"
+ "782f6dbe1643a45618574f16728112a7e0ef9f58656f6adbf400409f4aa5013c"
+ "159a368ca59bde6b3918dfe1d802fa6cfa06c9ca31aca78cb263c8ed917af9a9"
+ "a795d5e2c401e729964cf7ac28ccdb36d959ed7fd9af1c47097b6255c64e1b16"
+ "f21d86870455d5f0bf901fcc68c34b72c1bee72e6b8c4e36ae33996c7a59d09a"
+ },{
+ "PKCS#1 v1.5 Signature Example 14.20",
+ "032e283e596e87faa6cfcfb8fa04df6a61e611dfe73bbf668ee67b496bfb0ffb"
+ "7f9dc931a98bcedb25",
+ "b9fdc03dc19970713c4a17e87e7ebb5f13505d59cbb22ba72e9ff16bdf8b659c"
+ "3330a93dcc092a5d385b2d5e1534003146c050b7ddc4f756569da21180158226"
+ "6119f5599b1e65e8ebea6bc96442ee12acb96c6dba083e921094da9c9ecf5afa"
+ "a54b7fde7a0cae3fdfe4d251933a52f02dc23e1b3214c683e19af46e18c74956"
+ "dc6ab3502d46caac3cb26b707cdc3025b6de4e83543b95845b4a159760770a4b"
+ "d09e4635a04e217d665c9594879f381d71100934fada61c7cc22b8d2ff8eb35a"
+ }
+ }
+ },
+ {
+ "A 2048-bit RSA key pair",
+ "df271fd25f8644496b0c81be4bd50297ef099b002a6fd67727eb449cea566ed6"
+ "a3981a71312a141cabc9815c1209e320a25b32464e9999f18ca13a9fd3892558"
+ "f9e0adefdd3650dd23a3f036d60fe398843706a40b0b8462c8bee3bce12f1f28"
+ "60c2444cdc6a44476a75ff4aa24273ccbe3bf80248465f8ff8c3a7f3367dfc0d"
+ "f5b6509a4f82811cedd81cdaaa73c491da412170d544d4ba96b97f0afc806549"
+ "8d3a49fd910992a1f0725be24f465cfe7e0eabf678996c50bc5e7524abf73f15"
+ "e5bef7d518394e3138ce4944506aaaaf3f9b236dcab8fc00f87af596fdc3d9d6"
+ "c75cd508362fae2cbeddcc4c7450b17b776c079ecca1f256351a43b97dbe2153",
+ "010001",
+ "5bd910257830dce17520b03441a51a8cab94020ac6ecc252c808f3743c95b7c8"
+ "3b8c8af1a5014346ebc4242cdfb5d718e30a733e71f291e4d473b61bfba6daca"
+ "ed0a77bd1f0950ae3c91a8f90111882589e1d62765ee671e7baeea309f64d447"
+ "bbcfa9ea12dce05e9ea8939bc5fe6108581279c982b308794b3448e7f7b95229"
+ "2df88c80cb40142c4b5cf5f8ddaa0891678d610e582fcb880f0d707caf47d09a"
+ "84e14ca65841e5a3abc5e9dba94075a9084341f0edad9b68e3b8e082b80b6e6e"
+ "8a0547b44fb5061b6a9131603a5537ddabd01d8e863d8922e9aa3e4bfaea0b39"
+ "d79283ad2cbc8a59cce7a6ecf4e4c81ed4c6591c807defd71ab06866bb5e7745",
+ {
+ {
+ "PKCS#1 v1.5 Signature Example 15.1",
+ "f45d55f35551e975d6a8dc7ea9f488593940cc75694a278f27e578a163d839b3"
+ "4040841808cf9c58c9b8728bf5f9ce8ee811ea91714f47bab92d0f6d5a26fcfe"
+ "ea6cd93b910c0a2c963e64eb1823f102753d41f0335910ad3a977104f1aaf6c3"
+ "742716a9755d11b8eed690477f445c5d27208b2e284330fa3d301423fa7f2d08"
+ "6e0ad0b892b9db544e456d3f0dab85d953c12d340aa873eda727c8a649db7fa6"
+ "3740e25e9af1533b307e61329993110e95194e039399c3824d24c51f22b26bde"
+ "1024cd395958a2dfeb4816a6e8adedb50b1f6b56d0b3060ff0f1c4cb0d0e001d"
+ "d59d73be12",
+ "b75a5466b65d0f300ef53833f2175c8a347a3804fc63451dc902f0b71f908345"
+ "9ed37a5179a3b723a53f1051642d77374c4c6c8dbb1ca20525f5c9f32db77695"
+ "3556da31290e22197482ceb69906c46a758fb0e7409ba801077d2a0a20eae7d1"
+ "d6d392ab4957e86b76f0652d68b83988a78f26e11172ea609bf849fbbd78ad7e"
+ "dce21de662a081368c040607cee29db0627227f44963ad171d2293b633a392e3"
+ "31dca54fe3082752f43f63c161b447a4c65a6875670d5f6600fcc860a1caeb0a"
+ "88f8fdec4e564398a5c46c87f68ce07001f6213abe0ab5625f87d19025f08d81"
+ "dac7bd4586bc9382191f6d2880f6227e5df3eed21e7792d249480487f3655261"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.2",
+ "c14b4c6075b2f9aad661def4ecfd3cb933c623f4e63bf53410d2f016d1ab98e2"
+ "729eccf8006cd8e08050737d95fdbf296b66f5b9792a902936c4f7ac69f51453"
+ "ce4369452dc22d96f037748114662000dd9cd3a5e179f4e0f81fa6a0311ca1ae"
+ "e6519a0f63cec78d27bb726393fb7f1f88cde7c97f8a66cd66301281dac3f3a4"
+ "33248c75d6c2dcd708b6a97b0a3f325e0b2964f8a5819e479b",
+ "afa7343462bea122cc149fca70abdae79446677db5373666af7dc313015f4de7"
+ "86e6e394946fad3cc0e2b02bedba5047fe9e2d7d099705e4a39f28683279cf0a"
+ "c85c1530412242c0e918953be000e939cf3bf182525e199370fa7907eba69d5d"
+ "b4631017c0e36df70379b5db8d4c695a979a8e6173224065d7dc15132ef28cd8"
+ "22795163063b54c651141be86d36e36735bc61f31fca574e5309f3a3bbdf91ef"
+ "f12b99e9cc1744f1ee9a1bd22c5bad96ad481929251f0343fd36bcf0acde7f11"
+ "e5ad60977721202796fe061f9ada1fc4c8e00d6022a8357585ffe9fdd59331a2"
+ "8c4aa3121588fb6cf68396d8ac0546599500c9708500a5972bd54f72cf8db0c8"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.3",
+ "d02371ad7ee48bbfdb2763de7a843b9408ce5eb5abf847ca3d735986df84e906"
+ "0bdbcdd3a55ba55dde20d4761e1a21d225c1a186f4ac4b3019d3adf78fe63346"
+ "67f56f70c901a0a2700c6f0d56add719592dc88f6d2306c7009f6e7a635b4cb3"
+ "a502dfe68ddc58d03be10a1170004fe74dd3e46b82591ff75414f0c4a03e605e"
+ "20524f2416f12eca589f111b75d639c61baa80cafd05cf3500244a219ed9ced9"
+ "f0b10297182b653b526f400f2953ba214d5bcd47884132872ae90d4d6b1f4215"
+ "39f9f34662a56dc0e7b4b923b6231e30d2676797817f7c337b5ac824ba93143b"
+ "3381fa3dce0e6aebd38e67735187b1ebd95c02",
+ "3bac63f86e3b70271203106b9c79aabd9f477c56e4ee58a4fce5baf2cab4960f"
+ "88391c9c23698be75c99aedf9e1abf1705be1dac33140adb48eb31f450bb9efe"
+ "83b7b90db7f1576d33f40c1cba4b8d6b1d3323564b0f1774114fa7c08e6d1e20"
+ "dd8fbba9b6ac7ad41e26b4568f4a8aacbfd178a8f8d2c9d5f5b88112935a8bc9"
+ "ae32cda40b8d20375510735096536818ce2b2db71a9772c9b0dda09ae10152fa"
+ "11466218d091b53d92543061b7294a55be82ff35d5c32fa233f05aaac7585030"
+ "7ecf81383c111674397b1a1b9d3bf7612ccbe5bacd2b38f0a98397b24c83658f"
+ "b6c0b4140ef11970c4630d44344e76eaed74dcbee811dbf6575941f08a6523b8"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.4",
+ "29035584ab7e0226a9ec4b02e8dcf1272dc9a41d73e2820007b0f6e21feccd5b"
+ "d9dbb9ef88cd6758769ee1f956da7ad18441de6fab8386dbc693",
+ "28d8e3fcd5dddb21ffbd8df1630d7377aa2651e14cad1c0e43ccc52f907f946d"
+ "66de7254e27a6c190eb022ee89ecf6224b097b71068cd60728a1aed64b80e545"
+ "7bd3106dd91706c937c9795f2b36367ff153dc2519a8db9bdf2c807430c451de"
+ "17bbcd0ce782b3e8f1024d90624dea7f1eedc7420b7e7caa6577cef43141a726"
+ "4206580e44a167df5e41eea0e69a805454c40eefc13f48e423d7a32d02ed42c0"
+ "ab03d0a7cf70c5860ac92e03ee005b60ff3503424b98cc894568c7c56a023355"
+ "1cebe588cf8b0167b7df13adcad828676810499c704da7ae23414d69e3c0d2db"
+ "5dcbc2613bc120421f9e3653c5a8767297643c7e0740de016355453d6c95ae72"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.5",
+ "bda3a1c79059eae598308d3df609",
+ "a156176cb96777c7fb96105dbd913bc4f74054f6807c6008a1a956ea92c1f81c"
+ "b897dc4b92ef9f4e40668dc7c556901acb6cf269fe615b0fb72b30a513386923"
+ "14b0e5878a88c2c7774bd16939b5abd82b4429d67bd7ac8e5ea7fe924e20a6ec"
+ "662291f2548d734f6634868b039aa5f9d4d906b2d0cb8585bf428547afc91c6e"
+ "2052ddcd001c3ef8c8eefc3b6b2a82b6f9c88c56f2e2c3cb0be4b80da95eba37"
+ "1d8b5f60f92538743ddbb5da2972c71fe7b9f1b790268a0e770fc5eb4d5dd852"
+ "47d48ae2ec3f26255a3985520206a1f268e483e9dbb1d5cab190917606de31e7"
+ "c5182d8f151bf41dfeccaed7cde690b21647106b490c729d54a8fe2802a6d126"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.6",
+ "c187915e4e87da81c08ed4356a0cceac1c4fb5c046b45281b387ec28f1abfd56"
+ "7e546b236b37d01ae71d3b2834365d3df380b75061b736b0130b070be58ae8a4"
+ "6d12166361b613dbc47dfaeb4ca746456c2e888385525cca9dd1c3c7a9ada76d"
+ "6c",
+ "9cab74163608669f7555a333cf196fe3a0e9e5eb1a32d34bb5c85ff689aaab0e"
+ "3e65668ed3b1153f94eb3d8be379b8eef007c4a02c7071ce30d8bb341e58c620"
+ "f73d37b4ecbf48be294f6c9e0ecb5e63fec41f120e5553dfa0ebebbb72640a95"
+ "37badcb451330229d9f710f62e3ed8ec784e50ee1d9262b42671340011d7d098"
+ "c6f2557b2131fa9bd0254636597e88ecb35a240ef0fd85957124df8080fee1e1"
+ "49af939989e86b26c85a5881fae8673d9fd40800dd134eb9bdb6410f420b0aa9"
+ "7b20efcf2eb0c807faeb83a3ccd9b51d4553e41dfc0df6ca80a1e81dc234bb83"
+ "89dd195a38b42de4edc49d346478b9f11f0557205f5b0bd7ffe9c850f396d7c4"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.7",
+ "abfa2ecb7d29bd5bcb9931ce2bad2f74383e95683cee11022f08e8e7d0b8fa05"
+ "8bf9eb7eb5f98868b5bb1fb5c31ceda3a64f1a12cdf20fcd0e5a246d7a1773d8"
+ "dba0e3b277545babe58f2b96e3f4edc18eabf5cd2a560fca75fe96e07d859def"
+ "b2564f3a34f16f11e91b3a717b41af53f6605323001aa406c6",
+ "c4b437bcf703f352e1faf74eb9622039426b5672caf2a7b381c6c4f0191e7e4a"
+ "98f0eebcd6f41784c2537ff0f99e74982c87201bfbc65eae832db71d16dacadb"
+ "0977e5c504679e40be0f9db06ffd848dd2e5c38a7ec021e7f68c47dfd38cc354"
+ "493d5339b4595a5bf31e3f8f13816807373df6ad0dc7e731e51ad19eb4754b13"
+ "4485842fe709d378444d8e36b1724a4fda21cafee653ab80747f7952ee804dea"
+ "b1039d84139945bbf4be82008753f3c54c7821a1d241f42179c794ef7042bbf9"
+ "955656222e45c34369a384697b6ae742e18fa5ca7abad27d9fe71052e3310d0f"
+ "52c8d12ea33bf053a300f4afc4f098df4e6d886779d64594d369158fdbc1f694"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.8",
+ "df4044a89a83e9fcbf1262540ae3038bbc90f2b2628bf2a4467ac67722d8546b"
+ "3a71cb0ea41669d5b4d61859c1b4e47cecc5933f757ec86db0644e311812d00f"
+ "b802f03400639c0e364dae5aebc5791bc655762361bc43c53d3c7886768f7968"
+ "c1c544c6f79f7be820c7e2bd2f9d73e62ded6d2e937e6a6daef90ee37a1a52a5"
+ "4f00e31addd64894cf4c02e16099e29f9eb7f1a7bb7f84c47a2b594813be02a1"
+ "7b7fc43b34c22c91925264126c89f86bb4d87f3ef131296c53a308e0331dac8b"
+ "af3b63422266ecef2b90781535dbda41cbd0cf22a8cbfb532ec68fc6afb2ac06",
+ "1414b38567ae6d973ede4a06842dcc0e0559b19e65a4889bdbabd0fd02806829"
+ "13bacd5dc2f01b30bb19eb810b7d9ded32b284f147bbe771c930c6052aa73413"
+ "90a849f81da9cd11e5eccf246dbae95fa95828e9ae0ca3550325326deef9f495"
+ "30ba441bed4ac29c029c9a2736b1a4190b85084ad150426b46d7f85bd702f48d"
+ "ac5f71330bc423a766c65cc1dcab20d3d3bba72b63b3ef8244d42f157cb7e3a8"
+ "ba5c05272c64cc1ad21a13493c3911f60b4e9f4ecc9900eb056ee59d6fe4b8ff"
+ "6e8048ccc0f38f2836fd3dfe91bf4a386e1ecc2c32839f0ca4d1b27a568fa940"
+ "dd64ad16bd0125d0348e383085f08894861ca18987227d37b42b584a8357cb04"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.9",
+ "ea941ff06f86c226927fcf0e3b11b0872676170c1bfc33bda8e265c77771f9d0"
+ "850164a5eecbcc5ce827fbfa07c85214796d8127e8caa81894ea61ceb1449e72"
+ "fea0a4c943b2da6d9b105fe053b9039a9cc53d420b7539fab2239c6b51d17e69"
+ "4c957d4b0f0984461879a0759c4401beecd4c606a0afbd7a076f50a2dfc2807f"
+ "24f1919baa7746d3a64e268ed3f5f8e6da83a2a5c9152f837cb07812bd5ba7d3"
+ "a07985de88113c1796e9b466ec299c5ac1059e27f09415",
+ "ceeb84ccb4e9099265650721eea0e8ec89ca25bd354d4f64564967be9d4b08b3"
+ "f1c018539c9d371cf8961f2291fbe0dc2f2f95fea47b639f1e12f4bc381cef0c"
+ "2b7a7b95c3adf27605b7f63998c3cbad542808c3822e064d4ad14093679e6e01"
+ "418a6d5c059684cd56e34ed65ab605b8de4fcfa640474a54a8251bbb7326a42d"
+ "08585cfcfc956769b15b6d7fdf7da84f81976eaa41d692380ff10eaecfe0a579"
+ "682909b5521fade854d797b8a0345b9a864e0588f6caddbf65f177998e180d1f"
+ "102443e6dca53a94823caa9c3b35f322583c703af67476159ec7ec93d1769b30"
+ "0af0e7157dc298c6cd2dee2262f8cddc10f11e01741471bbfd6518a175734575"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.10",
+ "d8b81645c13cd7ecf5d00ed2c91b9acd46c15568e5303c4a9775ede76b48403d"
+ "6be56c05b6b1cf77c6e75de096c5cb3551cb6fa964f3c879cf589d28e1da2f9d"
+ "ec",
+ "2745074ca97175d992e2b44791c323c57167165cdd8da579cdef4686b9bb404b"
+ "d36a56504eb1fd770f60bfa188a7b24b0c91e881c24e35b04dc4dd4ce38566bc"
+ "c9ce54f49a175fc9d0b22522d9579047f9ed42eca83f764a10163997947e7d2b"
+ "52ff08980e7e7c2257937b23f3d279d4cd17d6f495546373d983d536efd7d1b6"
+ "7181ca2cb50ac616c5c7abfbb9260b91b1a38e47242001ff452f8de10ca6eaea"
+ "dcaf9edc28956f28a711291fc9a80878b8ba4cfe25b8281cb80bc9cd6d2bd182"
+ "5246eebe252d9957ef93707352084e6d36d423551bf266a85340fb4a6af37088"
+ "0aab07153d01f48d086df0bfbec05e7b443b97e71718970e2f4bf62023e95b67"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.11",
+ "e5739b6c14c92d510d95b826933337ff0d24ef721ac4ef64c2bad264be8b44ef"
+ "a1516e08a27eb6b611d3301df0062daefc73a8c0d92e2c521facbc7b26473876"
+ "7ea6fc97d588a0baf6ce50adf79e600bd29e345fcb1dba71ac5c0289023fe4a8"
+ "2b46a5407719197d2e958e3531fd54aef903aabb4355f88318994ed3c3dd62f4"
+ "20a7",
+ "be40a5fb94f113e1b3eff6b6a33986f202e363f07483b792e68dfa5554df0466"
+ "cc32150950783b4d968b639a04fd2fb97f6eb967021f5adccb9fca95acc8f2cd"
+ "885a380b0a4e82bc760764dbab88c1e6c0255caa94f232199d6f597cc9145b00"
+ "e3d4ba346b559a8833ad1516ad5163f016af6a59831c82ea13c8224d84d0765a"
+ "9d12384da460a8531b4c407e04f4f350709eb9f08f5b220ffb45abf6b75d1579"
+ "fd3f1eb55fc75b00af8ba3b087827fe9ae9fb4f6c5fa63031fe582852fe2834f"
+ "9c89bff53e2552216bc7c1d4a3d5dc2ba6955cd9b17d1363e7fee8ed7629753f"
+ "f3125edd48521ae3b9b03217f4496d0d8ede57acbc5bd4deae74a56f86671de2"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.12",
+ "7af42835917a88d6b3c6716ba2f5b0d5b20bd4e2e6e574e06af1eef7c81131be"
+ "22bf8128b9cbc6ec00275ba80294a5d1172d0824a79e8fdd830183e4c00b9678"
+ "2867b1227fea249aad32ffc5fe007bc51f21792f728deda8b5708aa99cabab20"
+ "a4aa783ed86f0f27b5d563f42e07158cea72d097aa6887ec411dd012912a5e03"
+ "2bbfa678507144bcc95f39b58be7bfd1759adb9a91fa1d6d8226a8343a8b849d"
+ "ae76f7b98224d59e28f781f13ece605f84f6c90bae5f8cf378816f4020a7dda1"
+ "bed90c92a23634d203fac3fcd86d68d3182a7d9ccabe7b0795f5c655e9acc4e3"
+ "ec185140d10cef053464ab175c83bd83935e3dabaf3462eebe63d15f573d269a",
+ "4e78c5902b807914d12fa537ae6871c86db8021e55d1adb8eb0ccf1b8f36ab7d"
+ "ad1f682e947a627072f03e627371781d33221d174abe460dbd88560c22f69011"
+ "6e2fbbe6e964363a3e5283bb5d946ef1c0047eba038c756c40be7923055809b0"
+ "e9f34a03a58815ebdde767931f018f6f1878f2ef4f47dd374051dd48685ded6e"
+ "fb3ea8021f44be1d7d149398f98ea9c08d62888ebb56192d17747b6b8e170954"
+ "31f125a8a8e9962aa31c285264e08fb21aac336ce6c38aa375e42bc92ab0ab91"
+ "038431e1f92c39d2af5ded7e43bc151e6ebea4c3e2583af3437e82c43c5e3b5b"
+ "07cf0359683d2298e35948ed806c063c606ea178150b1efc15856934c7255cfe"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.13",
+ "ebaef3f9f23bdfe5fa6b8af4c208c189f2251bf32f5f137b9de4406378686b3f"
+ "0721f62d24cb8688d6fc41a27cbae21d30e429feacc7111941c277",
+ "c48dbef507114f03c95fafbeb4df1bfa88e0184a33cc4f8a9a1035ff7f822a5e"
+ "38cda18723915ff078244429e0f6081c14fd83331fa65c6ba7bb9a12dbf66223"
+ "74cd0ca57de3774e2bd7ae823677d061d53ae9c4040d2da7ef7014f3bbdc95a3"
+ "61a43855c8ce9b97ecabce174d926285142b534a3087f9f4ef74511ec742b0d5"
+ "685603faf403b5072b985df46adf2d2529a02d40711e2190917052371b79b749"
+ "b83abf0ae29486c3f2f62477b2bd362b039c013c0c5076ef520dbb405f42cee9"
+ "5425c373a975e1cdd032c49622c85079b09e88dab2b13969ef7a723973781040"
+ "459f57d5013638483de2d91cb3c490da81c46de6cd76ea8a0c8f6fe331712d24"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.14",
+ "c5a2711278761dfcdd4f0c99e6f5619d6c48b5d4c1a80982faa6b4cf1cf7a60f"
+ "f327abef93c801429efde086408581461056acc33f3d04f5ada21216cacd5fd1"
+ "f9ed83203e0e2fe6138e3eae8424e5915a083f3f7ab76052c8be55ae882d6ec1"
+ "482b1e45c5dae9f41015405327022ec32f0ea2429763b255043b1958ee3cf6d6"
+ "3983596eb385844f8528cc9a9865835dc5113c02b80d0fca68aa25e72bcaaeb3"
+ "cf9d79d84f984fd417",
+ "6bd5257aa06611fb4660087cb4bc4a9e449159d31652bd980844daf3b1c7b353"
+ "f8e56142f7ea9857433b18573b4deede818a93b0290297783f1a2f23cbc72797"
+ "a672537f01f62484cd4162c3214b9ac628224c5de01f32bb9b76b27354f2b151"
+ "d0e8c4213e4615ad0bc71f515e300d6a64c6743411fffde8e5ff190e54923043"
+ "126ecfc4c4539022668fb675f25c07e20099ee315b98d6afec4b1a9a93dc3349"
+ "6a15bd6fde1663a7d49b9f1e639d38664b37a010b1f35e658682d9cd63e57de0"
+ "f15e8bdd096558f07ec0caa218a8c06f4788453940287c9d34b6d40a3f09bf77"
+ "99fe98ae4eb49f3ff41c5040a50cefc9bdf2394b749cf164480df1ab6880273b"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.15",
+ "9bf8aa253b872ea77a7e23476be26b2329578cf6ac9ea2805b357f6fc3ad130d"
+ "baeb3d869a13cce7a808bbbbc969857e03945c7bb61df1b5c2589b8e046c2a5d"
+ "7e4057b1a74f24c711216364288529ec9570f25197213be1f5c2e596f8bf8b2c"
+ "f3cb38aa56ffe5e31df7395820e94ecf3b1189a965dcf9a9cb4298d3c88b2923"
+ "c19fc6bc34aacecad4e0931a7c4e5d73dc86dfa798a8476d82463eefaa90a8a9"
+ "192ab08b23088dd58e1280f7d72e4548396baac112252dd5c5346adb2004a2f7"
+ "101ccc899cc7fafae8bbe295738896a5b2012285014ef6",
+ "27f7f4da9bd610106ef57d32383a448a8a6245c83dc1309c6d770d357ba89e73"
+ "f2ad0832062eb0fe0ac915575bcd6b8bcadb4e2ba6fa9da73a59175152b2d4fe"
+ "72b070c9b7379e50000e55e6c269f6658c937972797d3add69f130e34b85bdec"
+ "9f3a9b392202d6f3e430d09caca8227759ab825f7012d2ff4b5b62c8504dbad8"
+ "55c05edd5cab5a4cccdc67f01dd6517c7d41c43e2a4957aff19db6f18b17859a"
+ "f0bc84ab67146ec1a4a60a17d7e05f8b4f9ced6ad10908d8d78f7fc88b76adc8"
+ "290f87daf2a7be10ae408521395d54ed2556fb7661854a730ce3d82c71a8d493"
+ "ec49a378ac8a3c74439f7cc555ba13f859070890ee18ff658fa4d741969d70a5"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.16",
+ "32474830e2203754c8bf0681dc4f842afe360930378616c108e833656e5640c8"
+ "6856885bb05d1eb9438efede679263de07cb39553f6a25e006b0a52311a063ca"
+ "088266d2564ff6490c46b5609818548f88764dad34a25e3a85d575023f0b9e66"
+ "5048a03c350579a9d32446c7bb96cc92e065ab94d3c8952e8df68ef0d9fa456b"
+ "3a06bb80e3bbc4b28e6a94b6d0ff7696a64efe05e735fea025d7bdbc4139f3a3"
+ "b546075cba7efa947374d3f0ac80a68d765f5df6210bca069a2d88647af7ea04"
+ "2dac690cb57378ec0777614fb8b65ff453ca6b7dce6098451a2f8c0da9bfecf1"
+ "fdf391bbaa4e2a91ca18a1121a7523a2abd42514f489e8",
+ "6917437257c22ccb5403290c3dee82d9cf7550b31bd31c51bd57bfd35d452ab4"
+ "db7c4be6b2e25ac9a59a1d2a7feb627f0afd4976b3003cc9cffd8896505ec382"
+ "f265104d4cf8c932fa9fe86e008707959912389da4b2d6b369b36a5e72e29d24"
+ "c9a98c9d31a3ab44e643e6941266a47a45e3446ce8776abe241a8f5fc6423b24"
+ "b1ff250dc2c3a8172353561077e850a769b25f0325dac88965a3b9b472c494e9"
+ "5f719b4eac332caa7a65c7dfe46d9aa7e6e00f525f303dd63ab7919218901868"
+ "f9337f8cd26aafe6f33b7fb2c98810af19f7fcb282ba1577912c1d368975fd5d"
+ "440b86e10c199715fa0b6f4250b533732d0befe1545150fc47b876de09b00a94"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.17",
+ "008e59505eafb550aae5e845584cebb00b6de1733e9f95d42c882a5bbeb5ce1c"
+ "57e119e7c0d4daca9f1ff7870217f7cfd8a6b373977cac9cab8e71e420",
+ "922503b673ee5f3e691e1ca85e9ff4173cf72b05ac2c131da5603593e3bc259c"
+ "94c1f7d3a06a5b9891bf113fa39e59ff7c1ed6465e908049cb89e4e125cd37d2"
+ "ffd9227a41b4a0a19c0a44fbbf3de55bab802087a3bb8d4ff668ee6bbb8ad89e"
+ "6857a79a9c72781990dfcf92cd519404c950f13d1143c3184f1d250c90e17ac6"
+ "ce36163b9895627ad6ffec1422441f55e4499dba9be89546ae8bc63cca01dd08"
+ "463ae7f1fce3d893996938778c1812e674ad9c309c5acca3fde44e7dd8695993"
+ "e9c1fa87acda99ece5c8499e468957ad66359bf12a51adbe78d3a213b449bf0b"
+ "5f8d4d496acf03d3033b7ccd196bc22f68fb7bef4f697c5ea2b35062f48a36dd"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.18",
+ "6abc54cf8d1dff1f53b17d8160368878a8788cc6d22fa5c2258c88e660b09a89"
+ "33f9f2c0504ddadc21f6e75e0b833beb555229dee656b9047b92f62e76b8ffcc"
+ "60dab06b80",
+ "0b6daf42f7a862147e417493c2c401efae32636ab4cbd44192bbf5f195b50ae0"
+ "96a475a1614f0a9fa8f7a026cb46c6506e518e33d83e56477a875aca8c7e714c"
+ "e1bdbd61ef5d535239b33f2bfdd61771bab62776d78171a1423cea8731f82e60"
+ "766d6454265620b15f5c5a584f55f95b802fe78c574ed5dacfc831f3cf2b0502"
+ "c0b298f25ccf11f973b31f85e474421985f3cff702df3946ef0a6605682111b2"
+ "f55b1f8ab0d2ea3a683c69985ead93ed449ea48f0358ddf70802cb41de2fd83f"
+ "3c808082d84936948e0c84a131b4927827460527bb5cd24bfab7b48e071b2417"
+ "1930f99763272f9797bcb76f1d2481575558fcf260b1f0e554ebb3df3cfcb958"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.19",
+ "af2d78152cf10efe01d274f217b177f6b01b5e749f1567715da324859cd3dd88"
+ "db848ec79f48dbba7b6f1d33111ef31b64899e7391c2bffd69f49025cf201fc5"
+ "85dbd1542c1c778a2ce7a7ee108a309feca26d133a5ffedc4e869dcd7656596a"
+ "c8427ea3ef6e3fd78fe99d8ddc71d839f6786e0da6e786bd62b3a4f19b891a56"
+ "157a554ec2a2b39e25a1d7c7d37321c7a1d946cf4fbe758d9276f08563449d67"
+ "414a2c030f4251cfe2213d04a541063787",
+ "209c61157857387b71e24bf3dd56414550503bec180ff53bdd9bac062a2d4995"
+ "09bf991281b79527df9136615b7a6d9db3a103b535e0202a2caca197a7b74e53"
+ "56f3dd595b49acfd9d30049a98ca88f625bca1d5f22a392d8a749efb6eed9b78"
+ "21d3110ac0d244199ecb4aa3d735a83a2e8893c6bf8581383ccaee834635b7fa"
+ "1faffa45b13d15c1da33af71e89303d68090ff62ee615fdf5a84d120711da53c"
+ "2889198ab38317a9734ab27d67924cea74156ff99bef9876bb5c339e93745283"
+ "e1b34e072226b88045e017e9f05b2a8c416740258e223b2690027491732273f3"
+ "229d9ef2b1b3807e321018920ad3e53dae47e6d9395c184b93a374c671faa2ce"
+ },{
+ "PKCS#1 v1.5 Signature Example 15.20",
+ "40ee992458d6f61486d25676a96dd2cb93a37f04b178482f2b186cf88215270d"
+ "ba29d786d774b0c5e78c7f6e56a956e7f73950a2b0c0c10a08dbcd67e5b210bb"
+ "21c58e2767d44f7dd4014e3966143bf7e3d66ff0c09be4c55f93b39994b8518d"
+ "9c1d76d5b47374dea08f157d57d70634978f3856e0e5b481afbbdb5a3ac48d48"
+ "4be92c93de229178354c2de526e9c65a31ede1ef68cb6398d7911684fec0babc"
+ "3a781a66660783506974d0e14825101c3bfaea",
+ "927502b824afc42513ca6570de338b8a64c3a85eb828d3193624f27e8b1029c5"
+ "5c119c9733b18f5849b3500918bcc00551d9a8fdf53a97749fa8dc480d6fe974"
+ "2a5871f973926528972a1af49e3925b0adf14a842719b4a5a2d89fa9c0b6605d"
+ "212bed1e6723b93406ad30e86829a5c719b890b389306dc5506486ee2f36a8df"
+ "e0a96af678c9cbd6aff397ca200e3edc1e36bd2f08b31d540c0cb282a9559e4a"
+ "dd4fc9e6492eed0ccbd3a6982e5faa2ddd17be47417c80b4e5452d31f72401a0"
+ "42325109544d954c01939079d409a5c378d7512dfc2d2a71efcc3432a765d1c6"
+ "a52cfce899cd79b15b4fc3723641ef6bd00acc10407e5df58dd1c3c5c559a506"
+ }
+ }
+ }
+ };
--- /dev/null
+/* pkcs1v2.c - Test OAEP and PSS padding
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+#else
+# include <gcrypt.h>
+#endif
+
+
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+static int verbose;
+static int die_on_error;
+static int error_count;
+
+
+static void
+info (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+}
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+ if (die_on_error)
+ exit (1);
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+/* Convert STRING consisting of hex characters into its binary
+ representation and return it as an allocated buffer. The valid
+ length of the buffer is returned at R_LENGTH. The string is
+ delimited by end of string. The function returns NULL on
+ error. */
+static void *
+data_from_hex (const char *string, size_t *r_length)
+{
+ const char *s;
+ unsigned char *buffer;
+ size_t length;
+
+ buffer = gcry_xmalloc (strlen(string)/2+1);
+ length = 0;
+ for (s=string; *s; s +=2 )
+ {
+ if (!hexdigitp (s) || !hexdigitp (s+1))
+ die ("error parsing hex string `%s'\n", string);
+ ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+ }
+ *r_length = length;
+ return buffer;
+}
+
+
+static int
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected,
+ const char *description)
+{
+ gcry_sexp_t l1;
+ const void *a;
+ size_t alen;
+ void *b;
+ size_t blen;
+ int rc = 0;
+
+ l1 = gcry_sexp_find_token (sexp, name, 0);
+ a = gcry_sexp_nth_data (l1, 1, &alen);
+ b = data_from_hex (expected, &blen);
+ if (!a)
+ {
+ info ("%s: parameter \"%s\" missing in key\n", description, name);
+ rc = 1;
+ }
+ else if ( alen != blen || memcmp (a, b, alen) )
+ {
+ info ("%s: parameter \"%s\" does not match expected value\n",
+ description, name);
+ rc = 1;
+ }
+ gcry_free (b);
+ gcry_sexp_release (l1);
+ return rc;
+}
+
+
+/* Check against the OAEP test vectors from
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */
+static void
+check_oaep (void)
+{
+#include "pkcs1v2-oaep.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *seed, *encr;
+ size_t mesg_len, seed_len, encr_len;
+ gcry_sexp_t plain, ciph;
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+
+ err = gcry_sexp_build (&plain, NULL,
+ "(data (flags oaep)(hash-algo sha1)"
+ "(value %b)(random-override %b))",
+ (int)mesg_len, mesg,
+ (int)seed_len, seed);
+ if (err)
+ die ("constructing plain data failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (seed);
+
+ err = gcry_pk_encrypt (&ciph, plain, pub_key);
+ if (err)
+ {
+ show_sexp ("plain:\n", ciph);
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("encrypt result:\n", ciph);
+ fail ("mismatch in gcry_pk_encrypt\n");
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+
+ /* Now test the decryption. */
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
+
+ err = gcry_sexp_build (&ciph, NULL,
+ "(enc-val (flags oaep)(hash-algo sha1)"
+ "(random-override %b)"
+ "(rsa (a %b)))",
+ (int)seed_len, seed,
+ (int)encr_len, encr);
+ if (err)
+ die ("constructing cipher data failed: %s\n", gpg_strerror (err));
+ gcry_free (encr);
+ gcry_free (seed);
+
+ err = gcry_pk_decrypt (&plain, ciph, sec_key);
+ if (err)
+ {
+ show_sexp ("ciph:\n", ciph);
+ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("decrypt result:\n", plain);
+ fail ("mismatch in gcry_pk_decrypt\n");
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against the PSS test vectors from
+ ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */
+static void
+check_pss (void)
+{
+#include "pkcs1v2-pss.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *salt, *sign;
+ size_t mesg_len, salt_len, sign_len;
+ gcry_sexp_t sigtmpl, sig;
+ char mhash[20];
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pss)"
+ "(hash sha1 %b)"
+ "(random-override %b))",
+ 20, mhash,
+ (int)salt_len, salt);
+ if (err)
+ die ("constructing sig template failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (salt);
+
+ err = gcry_pk_sign (&sig, sigtmpl, sec_key);
+ if (err)
+ {
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("sign result:\n", sig);
+ fail ("mismatch in gcry_pk_sign\n");
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ }
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+
+ /* Now test the verification. */
+ salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len);
+ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
+
+ err = gcry_sexp_build (&sig, NULL,
+ "(sig-val(rsa(s %b)))",
+ (int)sign_len, sign);
+ if (err)
+ die ("constructing verify data failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pss)"
+ "(hash sha1 %b)"
+ "(random-override %b))",
+ 20, mhash,
+ (int)salt_len, salt);
+ if (err)
+ die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
+ gcry_free (sign);
+ gcry_free (salt);
+
+ err = gcry_pk_verify (sig, sigtmpl, pub_key);
+ if (err)
+ {
+ show_sexp ("sig:\n", sig);
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against PKCS#1 v1.5 encryption test vectors as found at
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt . */
+static void
+check_v15crypt (void)
+{
+#include "pkcs1v2-v15c.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *seed, *encr;
+ size_t mesg_len, seed_len, encr_len;
+ gcry_sexp_t plain, ciph;
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+
+ err = gcry_sexp_build (&plain, NULL,
+ "(data (flags pkcs1)(hash-algo sha1)"
+ "(value %b)(random-override %b))",
+ (int)mesg_len, mesg,
+ (int)seed_len, seed);
+ if (err)
+ die ("constructing plain data failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+ gcry_free (seed);
+
+ err = gcry_pk_encrypt (&ciph, plain, pub_key);
+ if (err)
+ {
+ show_sexp ("plain:\n", ciph);
+ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("encrypt result:\n", ciph);
+ fail ("mismatch in gcry_pk_encrypt\n");
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+
+ /* Now test the decryption. */
+ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len);
+ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len);
+
+ err = gcry_sexp_build (&ciph, NULL,
+ "(enc-val (flags pkcs1)(hash-algo sha1)"
+ "(random-override %b)"
+ "(rsa (a %b)))",
+ (int)seed_len, seed,
+ (int)encr_len, encr);
+ if (err)
+ die ("constructing cipher data failed: %s\n", gpg_strerror (err));
+ gcry_free (encr);
+ gcry_free (seed);
+
+ err = gcry_pk_decrypt (&plain, ciph, sec_key);
+ if (err)
+ {
+ show_sexp ("ciph:\n", ciph);
+ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("decrypt result:\n", plain);
+ fail ("mismatch in gcry_pk_decrypt\n");
+ }
+ gcry_sexp_release (plain);
+ plain = NULL;
+ }
+ gcry_sexp_release (ciph);
+ ciph = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+/* Check against PKCS#1 v1.5 signature test vectors as found at
+ ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt . */
+static void
+check_v15sign (void)
+{
+#include "pkcs1v2-v15s.h"
+ gpg_error_t err;
+ int tno, mno;
+
+ for (tno = 0; tno < DIM (tbl); tno++)
+ {
+ void *rsa_n, *rsa_e, *rsa_d;
+ size_t rsa_n_len, rsa_e_len, rsa_d_len;
+ gcry_sexp_t sec_key, pub_key;
+
+ if (verbose > 1)
+ info ("(%s)\n", tbl[tno].desc);
+
+ rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len);
+ rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len);
+ rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len);
+ err = gcry_sexp_build (&sec_key, NULL,
+ "(private-key (rsa (n %b)(e %b)(d %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e,
+ (int)rsa_d_len, rsa_d);
+ if (err)
+ die ("constructing private key failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&pub_key, NULL,
+ "(public-key (rsa (n %b)(e %b)))",
+ (int)rsa_n_len, rsa_n,
+ (int)rsa_e_len, rsa_e);
+ if (err)
+ die ("constructing public key failed: %s\n", gpg_strerror (err));
+ gcry_free (rsa_n);
+ gcry_free (rsa_e);
+ gcry_free (rsa_d);
+
+ for (mno = 0; mno < DIM (tbl[0].m); mno++)
+ {
+ void *mesg, *sign;
+ size_t mesg_len, sign_len;
+ gcry_sexp_t sigtmpl, sig;
+ char mhash[20];
+
+ if (verbose)
+ info ("running test: %s\n", tbl[tno].m[mno].desc);
+
+ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len);
+
+ gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len);
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pkcs1)"
+ "(hash sha1 %b))",
+ 20, mhash);
+ if (err)
+ die ("constructing sig template failed: %s\n", gpg_strerror (err));
+ gcry_free (mesg);
+
+ err = gcry_pk_sign (&sig, sigtmpl, sec_key);
+ if (err)
+ {
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
+ }
+ else
+ {
+ if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign,
+ tbl[tno].m[mno].desc))
+ {
+ show_sexp ("sign result:\n", sig);
+ fail ("mismatch in gcry_pk_sign\n");
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ }
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+
+ /* Now test the verification. */
+ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len);
+
+ err = gcry_sexp_build (&sig, NULL,
+ "(sig-val(rsa(s %b)))",
+ (int)sign_len, sign);
+ if (err)
+ die ("constructing verify data failed: %s\n", gpg_strerror (err));
+ err = gcry_sexp_build (&sigtmpl, NULL,
+ "(data (flags pkcs1)"
+ "(hash sha1 %b))",
+ 20, mhash);
+ if (err)
+ die ("constructing verify tmpl failed: %s\n", gpg_strerror (err));
+ gcry_free (sign);
+
+ err = gcry_pk_verify (sig, sigtmpl, pub_key);
+ if (err)
+ {
+ show_sexp ("sig:\n", sig);
+ show_sexp ("sigtmpl:\n", sigtmpl);
+ fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err));
+ }
+ gcry_sexp_release (sig);
+ sig = NULL;
+ gcry_sexp_release (sigtmpl);
+ sigtmpl = NULL;
+ }
+
+ gcry_sexp_release (sec_key);
+ gcry_sexp_release (pub_key);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ int debug = 0;
+ int run_oaep = 0;
+ int run_pss = 0;
+ int run_v15c = 0;
+ int run_v15s = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--die"))
+ {
+ die_on_error = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--oaep"))
+ {
+ run_oaep = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--pss"))
+ {
+ run_pss = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--v15c"))
+ {
+ run_v15c = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--v15s"))
+ {
+ run_v15s = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (!run_oaep && !run_pss && !run_v15c && !run_v15s)
+ run_oaep = run_pss = run_v15c = run_v15s = 1;
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version ("1.5.0"))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+ if (run_oaep)
+ check_oaep ();
+ if (run_pss)
+ check_pss ();
+ if (run_v15c)
+ check_v15crypt ();
+ if (run_v15s)
+ check_v15sign ();
+
+ if (verbose)
+ fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count);
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* prime.c - part of the Libgcrypt test suite.
+ Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+static void
+check_primes (void)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ gcry_mpi_t *factors = NULL;
+ gcry_mpi_t prime = NULL;
+ gcry_mpi_t g;
+ unsigned int i = 0;
+ struct prime_spec
+ {
+ unsigned int prime_bits;
+ unsigned int factor_bits;
+ unsigned int flags;
+ } prime_specs[] =
+ {
+ { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR },
+ { 128, 0, 0 },
+ { 0 },
+ };
+
+ for (i = 0; prime_specs[i].prime_bits; i++)
+ {
+ err = gcry_prime_generate (&prime,
+ prime_specs[i].prime_bits,
+ prime_specs[i].factor_bits,
+ &factors,
+ NULL, NULL,
+ GCRY_WEAK_RANDOM,
+ prime_specs[i].flags);
+ assert (! err);
+ if (verbose)
+ {
+ fprintf (stderr, "test %d: p = ", i);
+ gcry_mpi_dump (prime);
+ putc ('\n', stderr);
+ }
+
+ err = gcry_prime_check (prime, 0);
+ assert (! err);
+
+ err = gcry_prime_group_generator (&g, prime, factors, NULL);
+ assert (!err);
+ gcry_prime_release_factors (factors); factors = NULL;
+
+ if (verbose)
+ {
+ fprintf (stderr, " %d: g = ", i);
+ gcry_mpi_dump (g);
+ putc ('\n', stderr);
+ }
+ gcry_mpi_release (g);
+
+
+ gcry_mpi_add_ui (prime, prime, 1);
+ err = gcry_prime_check (prime, 0);
+ assert (err);
+ }
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
+ verbose = 1;
+ else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
+ verbose = debug = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (! gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ check_primes ();
+
+ return 0;
+}
--- /dev/null
+/* pubkey.c - Public key encryption/decryption tests
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#include "../src/gcrypt.h"
+
+/* Sample RSA keys, taken from basic.c. */
+
+static const char sample_private_key_1[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+ "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
+" )\n"
+")\n";
+
+/* The same key as above but without p, q and u to test the non CRT case. */
+static const char sample_private_key_1_1[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" )\n"
+")\n";
+
+/* The same key as above but just without q to test the non CRT case. This
+ should fail. */
+static const char sample_private_key_1_2[] =
+"(private-key\n"
+" (openpgp-rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+ "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+ "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+ "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
+" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+ "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
+" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+ "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
+" )\n"
+")\n";
+
+static const char sample_public_key_1[] =
+"(public-key\n"
+" (rsa\n"
+" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+ "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+ "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+ "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
+" (e #010001#)\n"
+" )\n"
+")\n";
+
+
+static int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+ char *buf;
+ size_t size;
+
+ if (prefix)
+ fputs (prefix, stderr);
+ size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+ buf = gcry_xmalloc (size);
+
+ gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+ fprintf (stderr, "%.*s", (int)size, buf);
+ gcry_free (buf);
+}
+
+
+static void
+check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
+ gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
+{
+ gcry_sexp_t plain1, cipher, l;
+ gcry_mpi_t x0, x1;
+ int rc;
+ int have_flags;
+
+ /* Extract data from plaintext. */
+ l = gcry_sexp_find_token (plain0, "value", 0);
+ x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
+
+ /* Encrypt data. */
+ rc = gcry_pk_encrypt (&cipher, plain0, pkey);
+ if (rc)
+ die ("encryption failed: %s\n", gcry_strerror (rc));
+
+ l = gcry_sexp_find_token (cipher, "flags", 0);
+ have_flags = !!l;
+ gcry_sexp_release (l);
+
+ /* Decrypt data. */
+ rc = gcry_pk_decrypt (&plain1, cipher, skey);
+ gcry_sexp_release (cipher);
+ if (rc)
+ {
+ if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
+ return; /* This is the expected failure code. */
+ die ("decryption failed: %s\n", gcry_strerror (rc));
+ }
+
+ /* Extract decrypted data. Note that for compatibility reasons, the
+ output of gcry_pk_decrypt depends on whether a flags lists (even
+ if empty) occurs in its input data. Because we passed the output
+ of encrypt directly to decrypt, such a flag value won't be there
+ as of today. We check it anyway. */
+ l = gcry_sexp_find_token (plain1, "value", 0);
+ if (l)
+ {
+ if (!have_flags)
+ die ("compatibility mode of pk_decrypt broken\n");
+ gcry_sexp_release (plain1);
+ x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l);
+ }
+ else
+ {
+ if (have_flags)
+ die ("compatibility mode of pk_decrypt broken\n");
+ x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
+ gcry_sexp_release (plain1);
+ }
+
+ /* Compare. */
+ if (gcry_mpi_cmp (x0, x1))
+ die ("data corrupted\n");
+}
+
+static void
+check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
+ gpg_err_code_t decrypt_fail_code)
+{
+ gcry_sexp_t plain;
+ gcry_mpi_t x;
+ int rc;
+
+ /* Create plain text. */
+ x = gcry_mpi_new (nbits_data);
+ gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
+
+ rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
+ if (rc)
+ die ("converting data for encryption failed: %s\n",
+ gcry_strerror (rc));
+
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
+ gcry_sexp_release (plain);
+ gcry_mpi_release (x);
+
+ /* Create plain text. */
+ x = gcry_mpi_new (nbits_data);
+ gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
+
+ rc = gcry_sexp_build (&plain, NULL,
+ "(data (flags raw no-blinding) (value %m))", x);
+ if (rc)
+ die ("converting data for encryption failed: %s\n",
+ gcry_strerror (rc));
+
+ check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
+ gcry_sexp_release (plain);
+}
+
+static void
+get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
+{
+ gcry_sexp_t pub_key, sec_key;
+ int rc;
+ static const char *secret;
+
+
+ switch (secret_variant)
+ {
+ case 0: secret = sample_private_key_1; break;
+ case 1: secret = sample_private_key_1_1; break;
+ case 2: secret = sample_private_key_1_2; break;
+ default: die ("BUG\n");
+ }
+
+ rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
+ strlen (sample_public_key_1));
+ if (!rc)
+ rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
+ if (rc)
+ die ("converting sample keys failed: %s\n", gcry_strerror (rc));
+
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+static void
+get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new (&key_spec,
+ "(genkey (rsa (nbits 4:1024)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated RSA key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (! pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (! sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new (&key_spec,
+ "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating RSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated RSA (X9.31) key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ (fixed_x
+ ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
+ : "(genkey (elg (nbits 3:512)))"),
+ 0, 1);
+
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated ELG key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new (&key_spec,
+ transient_key
+ ? "(genkey (dsa (nbits 4:1024)(transient-key)))"
+ : "(genkey (dsa (nbits 4:1024)))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key (fips 186):\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey (dsa (transient-key)(domain"
+ "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
+ "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
+ "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
+ ")))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+static void
+get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey (dsa (transient-key)(use-fips186)(domain"
+ "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
+ "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
+ "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
+ "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
+ "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
+ "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
+ "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
+ "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
+ "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
+ ")))", 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key:\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
+{
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ int rc;
+
+ rc = gcry_sexp_new
+ (&key_spec,
+ "(genkey"
+ " (dsa"
+ " (nbits 4:1024)"
+ " (use-fips186)"
+ " (transient-key)"
+ " (derive-parms"
+ " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
+ 0, 1);
+ if (rc)
+ die ("error creating S-expression: %s\n", gcry_strerror (rc));
+ rc = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (rc)
+ die ("error generating DSA key: %s\n", gcry_strerror (rc));
+
+ if (verbose > 1)
+ show_sexp ("generated DSA key (fips 186 with seed):\n", key);
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key\n");
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key\n");
+
+ gcry_sexp_release (key);
+ *pkey = pub_key;
+ *skey = sec_key;
+}
+
+
+static void
+check_run (void)
+{
+ gpg_error_t err;
+ gcry_sexp_t pkey, skey;
+ int variant;
+
+ for (variant=0; variant < 3; variant++)
+ {
+ if (verbose)
+ fprintf (stderr, "Checking sample key (%d).\n", variant);
+ get_keys_sample (&pkey, &skey, variant);
+ /* Check gcry_pk_testkey which requires all elements. */
+ err = gcry_pk_testkey (skey);
+ if ((variant == 0 && err)
+ || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
+ die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
+ /* Run the usual check but expect an error from variant 2. */
+ check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Checking generated RSA key.\n");
+ get_keys_new (&pkey, &skey);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking generated RSA key (X9.31).\n");
+ get_keys_x931_new (&pkey, &skey);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking generated Elgamal key.\n");
+ get_elg_key_new (&pkey, &skey, 0);
+ check_keys (pkey, skey, 400, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
+ get_elg_key_new (&pkey, &skey, 1);
+ check_keys (pkey, skey, 800, 0);
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key.\n");
+ get_dsa_key_new (&pkey, &skey, 0);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (!gcry_fips_mode_active ())
+ {
+ if (verbose)
+ fprintf (stderr, "Generating transient DSA key.\n");
+ get_dsa_key_new (&pkey, &skey, 1);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+ }
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key (FIPS 186).\n");
+ get_dsa_key_fips186_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given domain.\n");
+ get_dsa_key_with_domain_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n");
+ get_dsa_key_fips186_with_domain_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+
+ if (verbose)
+ fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
+ get_dsa_key_fips186_with_seed_new (&pkey, &skey);
+ /* Fixme: Add a check function for DSA keys. */
+ gcry_sexp_release (pkey);
+ gcry_sexp_release (skey);
+}
+
+
+
+static gcry_mpi_t
+key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
+{
+ gcry_sexp_t l1, l2;
+ gcry_mpi_t result;
+
+ l1 = gcry_sexp_find_token (sexp, topname, 0);
+ if (!l1)
+ return NULL;
+
+ l2 = gcry_sexp_find_token (l1, name, 0);
+ if (!l2)
+ {
+ gcry_sexp_release (l1);
+ return NULL;
+ }
+
+ result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (l2);
+ gcry_sexp_release (l1);
+ return result;
+}
+
+
+static void
+check_x931_derived_key (int what)
+{
+ static struct {
+ const char *param;
+ const char *expected_d;
+ } testtable[] = {
+ { /* First example from X9.31 (D.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
+ " (Xp2 #192E8AAC41C576C822D93EA433#)\n"
+ " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
+ " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
+ " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
+ " B98BD984#)\n"
+ " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
+ " (Xq2 #134E4CAA16D2350A21D775C404#)\n"
+ " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
+ " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
+ " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
+ " 321DE34A#))))\n",
+ "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
+ "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
+ "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
+ "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
+ "241D3C4B"
+ },
+
+ { /* Second example from X9.31 (D.2.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1536)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #18272558B61316348297EACA74#)\n"
+ " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
+ " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
+ " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
+ " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
+ " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
+ " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
+ " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
+ " (Xq2 #18AB178ECA907D72472F65E480#)\n"
+ " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
+ " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
+ " B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
+ " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
+ " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
+ "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
+ "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
+ "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
+ "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
+ "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
+ "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
+ "BBCCB9F65C83"
+ /* Note that this example in X9.31 gives this value for D:
+
+ "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
+ "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
+ "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
+ "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
+ "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
+ "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
+ "EF32E7D9720B"
+
+ This is a bug in X9.31, obviously introduced by using
+
+ d = e^{-1} mod (p-1)(q-1)
+
+ instead of using the universal exponent as required by 4.1.3:
+
+ d = e^{-1} mod lcm(p-1,q-1)
+
+ The examples in X9.31 seem to be pretty buggy, see
+ cipher/primegen.c for another bug. Not only that I had to
+ spend 100 USD for the 66 pages of the document, it also took
+ me several hours to figure out that the bugs are in the
+ document and not in my code.
+ */
+ },
+
+ { /* First example from NIST RSAVS (B.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1024)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
+ " (Xp2 #16e5457b8844967ce83cab8c11#)\n"
+ " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
+ " ab262da1dcda8194720672a4e02229a0c71f60ae\n"
+ " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
+ " cab44595#)\n"
+ " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
+ " (Xq2 #1f9cca85f185341516d92e82fd#)\n"
+ " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
+ " c225655a9310cceac9f4cf1bce653ec916d45788\n"
+ " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
+ " 2f389eda#))))\n",
+ "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
+ "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
+ "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
+ "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
+ "dc7e8feb"
+ },
+
+ { /* Second example from NIST RSAVS (B.1.1). */
+ "(genkey\n"
+ " (rsa\n"
+ " (nbits 4:1536)\n"
+ " (rsa-use-e 1:3)\n"
+ " (derive-parms\n"
+ " (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
+ " (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
+ " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n"
+ " d7bc71d412511cd93981ddde8f91b967da404056\n"
+ " c39f105f7f239abdaff92923859920f6299e82b9\n"
+ " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
+ " 26974eb7bb1f14843841281b363b9cdb#)\n"
+ " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
+ " (Xq2 #143edd7b22d828913abf24ca4d#)\n"
+ " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
+ " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
+ " 7552195fae8b061077e03920814d8b9cfb5a3958\n"
+ " b3a82c2a7fc97e55db543948d3396289245336ec\n"
+ " 9e3cb308cc655aebd766340da8921383#))))\n",
+ "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
+ "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
+ "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
+ "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
+ "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
+ "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
+ "2ccf8a84835b"
+ }
+ };
+ gpg_error_t err;
+ gcry_sexp_t key_spec, key, pub_key, sec_key;
+ gcry_mpi_t d_expected, d_have;
+
+ if (what < 0 && what >= sizeof testtable)
+ die ("invalid WHAT value\n");
+
+ err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
+ if (err)
+ die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
+
+ err = gcry_pk_genkey (&key, key_spec);
+ gcry_sexp_release (key_spec);
+ if (err)
+ die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
+
+ pub_key = gcry_sexp_find_token (key, "public-key", 0);
+ if (!pub_key)
+ die ("public part missing in key [%d]\n", what);
+
+ sec_key = gcry_sexp_find_token (key, "private-key", 0);
+ if (!sec_key)
+ die ("private part missing in key [%d]\n", what);
+
+ err = gcry_mpi_scan
+ (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
+ if (err)
+ die ("error converting string [%d]\n", what);
+
+ if (verbose > 1)
+ show_sexp ("generated key:\n", key);
+
+ d_have = key_param_from_sexp (sec_key, "rsa", "d");
+ if (!d_have)
+ die ("parameter d not found in RSA secret key [%d]\n", what);
+ if (gcry_mpi_cmp (d_expected, d_have))
+ {
+ show_sexp (NULL, sec_key);
+ die ("parameter d does match expected value [%d]\n", what);
+ }
+ gcry_mpi_release (d_expected);
+ gcry_mpi_release (d_have);
+
+ gcry_sexp_release (key);
+ gcry_sexp_release (pub_key);
+ gcry_sexp_release (sec_key);
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+ int i;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ {
+ verbose = 2;
+ debug = 1;
+ }
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+ /* No valuable keys are create, so we can speed up our RNG. */
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+ for (i=0; i < 2; i++)
+ check_run ();
+
+ for (i=0; i < 4; i++)
+ check_x931_derived_key (i);
+
+ return 0;
+}
--- /dev/null
+/* random.c - part of the Libgcrypt test suite.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+static void
+print_hex (const char *text, const void *buf, size_t n)
+{
+ const unsigned char *p = buf;
+
+ fputs (text, stdout);
+ for (; n; n--, p++)
+ printf ("%02X", *p);
+ putchar ('\n');
+}
+
+
+static int
+writen (int fd, const void *buf, size_t nbytes)
+{
+ size_t nleft = nbytes;
+ int nwritten;
+
+ while (nleft > 0)
+ {
+ nwritten = write (fd, buf, nleft);
+ if (nwritten < 0)
+ {
+ if (errno == EINTR)
+ nwritten = 0;
+ else
+ return -1;
+ }
+ nleft -= nwritten;
+ buf = (const char*)buf + nwritten;
+ }
+
+ return 0;
+}
+
+static int
+readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
+{
+ size_t nleft = buflen;
+ int nread;
+
+ while ( nleft > 0 )
+ {
+ nread = read ( fd, buf, nleft );
+ if (nread < 0)
+ {
+ if (nread == EINTR)
+ nread = 0;
+ else
+ return -1;
+ }
+ else if (!nread)
+ break; /* EOF */
+ nleft -= nread;
+ buf = (char*)buf + nread;
+ }
+ if (ret_nread)
+ *ret_nread = buflen - nleft;
+ return 0;
+}
+
+
+
+/* Check that forking won't return the same random. */
+static void
+check_forking (void)
+{
+ pid_t pid;
+ int rp[2];
+ int i, status;
+ size_t nread;
+ char tmp1[16], tmp1c[16], tmp1p[16];
+
+ /* We better make sure that the RNG has been initialzied. */
+ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+ if (verbose)
+ print_hex ("initial random: ", tmp1, sizeof tmp1);
+
+ if (pipe (rp) == -1)
+ die ("pipe failed: %s\n", strerror (errno));
+
+ pid = fork ();
+ if (pid == (pid_t)(-1))
+ die ("fork failed: %s\n", strerror (errno));
+ if (!pid)
+ {
+ gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
+ if (writen (rp[1], tmp1c, sizeof tmp1c))
+ die ("write failed: %s\n", strerror (errno));
+ if (verbose)
+ {
+ print_hex (" child random: ", tmp1c, sizeof tmp1c);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+ gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
+ if (verbose)
+ print_hex (" parent random: ", tmp1p, sizeof tmp1p);
+
+ close (rp[1]);
+ if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
+ die ("read failed: %s\n", strerror (errno));
+ if (nread != sizeof tmp1c)
+ die ("read too short\n");
+
+ while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (i != (pid_t)(-1)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ ;
+ else
+ die ("child failed\n");
+
+ if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
+ die ("parent and child got the same random number\n");
+}
+
+
+
+/* Check that forking won't return the same nonce. */
+static void
+check_nonce_forking (void)
+{
+ pid_t pid;
+ int rp[2];
+ int i, status;
+ size_t nread;
+ char nonce1[10], nonce1c[10], nonce1p[10];
+
+ /* We won't get the same nonce back if we never initialized the
+ nonce subsystem, thus we get one nonce here and forget about
+ it. */
+ gcry_create_nonce (nonce1, sizeof nonce1);
+ if (verbose)
+ print_hex ("initial nonce: ", nonce1, sizeof nonce1);
+
+ if (pipe (rp) == -1)
+ die ("pipe failed: %s\n", strerror (errno));
+
+ pid = fork ();
+ if (pid == (pid_t)(-1))
+ die ("fork failed: %s\n", strerror (errno));
+ if (!pid)
+ {
+ gcry_create_nonce (nonce1c, sizeof nonce1c);
+ if (writen (rp[1], nonce1c, sizeof nonce1c))
+ die ("write failed: %s\n", strerror (errno));
+ if (verbose)
+ {
+ print_hex (" child nonce: ", nonce1c, sizeof nonce1c);
+ fflush (stdout);
+ }
+ _exit (0);
+ }
+ gcry_create_nonce (nonce1p, sizeof nonce1p);
+ if (verbose)
+ print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);
+
+ close (rp[1]);
+ if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
+ die ("read failed: %s\n", strerror (errno));
+ if (nread != sizeof nonce1c)
+ die ("read too short\n");
+
+ while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+ ;
+ if (i != (pid_t)(-1)
+ && WIFEXITED (status) && !WEXITSTATUS (status))
+ ;
+ else
+ die ("child failed\n");
+
+ if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
+ die ("parent and child got the same nonce\n");
+}
+
+
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
+ verbose = 1;
+ else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
+ verbose = debug = 1;
+
+ signal (SIGPIPE, SIG_IGN);
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ check_forking ();
+ check_nonce_forking ();
+
+ return 0;
+}
--- /dev/null
+/* register.c - Test for registering of additional cipher modules.
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "../src/gcrypt.h"
+
+static int verbose;
+static int in_fips_mode;
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr ;
+
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ exit (1);
+}
+
+gcry_err_code_t
+foo_setkey (void *c, const unsigned char *key, unsigned keylen)
+{
+ (void)c;
+ (void)key;
+ (void)keylen;
+
+ return 0;
+}
+
+#define FOO_BLOCKSIZE 16
+
+void
+foo_encrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ int i;
+
+ (void)c;
+
+ for (i = 0; i < FOO_BLOCKSIZE; i++)
+ outbuf[i] = inbuf[i] ^ 0x42;
+}
+
+void
+foo_decrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
+{
+ int i;
+
+ (void)c;
+
+ for (i = 0; i < FOO_BLOCKSIZE; i++)
+ outbuf[i] = inbuf[i] ^ 0x42;
+}
+
+gcry_cipher_spec_t cipher_spec_foo =
+ {
+ "FOO", NULL, NULL, 16, 0, 0,
+ foo_setkey, foo_encrypt, foo_decrypt,
+ NULL, NULL,
+ };
+
+int
+check_list (int algorithm)
+{
+ gcry_error_t err = GPG_ERR_NO_ERROR;
+ int *list, list_length;
+ int i, ret = 0;
+
+ err = gcry_cipher_list (NULL, &list_length);
+ assert (! err);
+ list = malloc (sizeof (int) * list_length);
+ assert (list);
+ err = gcry_cipher_list (list, &list_length);
+
+ for (i = 0; i < list_length && (! ret); i++)
+ if (list[i] == algorithm)
+ ret = 1;
+
+ return ret;
+}
+
+void
+check_run (void)
+{
+ int err, algorithm;
+ gcry_cipher_hd_t h;
+ char plain[16] = "Heil Discordia!";
+ char encrypted[16], decrypted[16];
+ gcry_module_t module;
+ int ret;
+
+ err = gcry_cipher_register (&cipher_spec_foo, &algorithm, &module);
+ if (in_fips_mode)
+ {
+ if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
+ die ("register cipher failed in fips mode: %s\n", gpg_strerror (err));
+ return;
+ }
+ else
+ {
+ if (err)
+ die ("register cipher failed: %s\n", gpg_strerror (err));
+ }
+
+ err = gcry_cipher_open (&h, algorithm, GCRY_CIPHER_MODE_CBC, 0);
+ if (err)
+ die ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
+
+ err = gcry_cipher_encrypt (h,
+ (unsigned char *) encrypted, sizeof (encrypted),
+ (unsigned char *) plain, sizeof (plain));
+ assert (! err);
+ assert (memcmp ((void *) plain, (void *) encrypted, sizeof (plain)));
+
+ err = gcry_cipher_reset (h);
+ assert (! err);
+
+ err = gcry_cipher_decrypt (h,
+ (unsigned char *) decrypted, sizeof (decrypted),
+ (unsigned char *) encrypted, sizeof (encrypted));
+ assert (! err);
+ assert (! memcmp ((void *) plain, (void *) decrypted, sizeof (plain)));
+
+ ret = check_list (algorithm);
+ assert (ret);
+
+ gcry_cipher_close (h);
+
+ gcry_cipher_unregister (module);
+
+ ret = check_list (algorithm);
+ assert (! ret);
+}
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+ int i = 1;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+
+ if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) )
+ in_fips_mode = 1;
+
+ for (; i > 0; i--)
+ check_run ();
+
+ /* In fips mode we let the Makefile skip this test because a PASS
+ would not make much sense with all egistering disabled. */
+ return in_fips_mode? 77:0;
+}
--- /dev/null
+(key-data
+ (public-key
+ (rsa
+ (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#)
+ (e #010001#)
+ )
+ )
+ (private-key
+ (rsa
+ (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#)
+ (e #010001#)
+ (d #0125A7ED14E014111AE2BD8FD81A69B0BDED886DBE477D9CC08C6B07F1F82BD5BD73797FF9FFFB0D2542BE97FD1DCE9FE30F516F117DB449B513C85EF779DC91DD57B6B2E1BDD077A1EBE148486C2ADC8FEAC7FE1BD40BDD45E6833B26FB75388D05293177EE12678B197B42EFD59A38985B4BB471A3761E41F1BA8AB3A2AFA5A241B999096B8A9809BC7C5DBB3BDF476049AE7671A47213C9922B7E4C1A5545BA92C555100DB00AB77254C8E1DFC283F3EDE901819B611CD5E551133D14E8FD18840F6331D29E2EED47118E7094C1E36E53DA2AA90133856A351367224B51F80C184A5C3C4CDA5CC822126B3DF696AE96BFB8B836FA56E4E8D7D8A545E5F668F23203AC6968BE0A8A0C3BEEAC0AC9CFAE994B8EA5E293A5B9817D49B89761528595BB99D83C2B1AA4054FA2FF1D1D4F8ADBC3E863D8F4BD8C76C38E057D81740FB4FB12BC3CF80AB510223934FE8D3FD461D17E9B4EA07380A7E5202DD93A40B1F2E6C2048160949A247AC9A3F962A4E2F4EE809F00C76AF8DA4737D1398E6A95BE4637C949A33492C9691B254EB239EA7B1EC0E2D4261A27183F90577F04B356FD10FDB5E23A4471068952930EAFF4EDC757ACE25781DBA807A0C153FEDDCCB55A08B774AB44AD2CC75BD319D4822BFC6AF24C9F837C72D1A615109882906ADC2B2C679630A6FAE363144B77A134F2856DF1D8E9A77AAEC08A72FD67C122BD280D591A6C4045D0497362FB91C8C38C00A457A0BBE8D625210E4BF55FC4041FBE0A1515B70EA98C4F4284B3C96C15DD21C8CC15305DB5BFA2C21EB9520C9ACD823F5E7ABCDA3993D89A7B561C101FEC08A8AE6621245CAA1406D7536FBC6E835692D2B1BB540B8F2B2EAB7A1406B2FE83873CDEDFB0A0E717A037CD3A6322AE0B6F5E36187646866A0D406F7F54007FEC9711311BCE87FC6B4F44C5D1F7BEDD2DED081F1439F38312FA27CB65665B1595F88713378797AB624C728CA6632653EC8E762A76E3E597AAD4C3C3FE41648AEB07FCB8BFE9C70A1818E4F1B19124BECD320E4CDA6A9FD02B0A422114B5DE31376549C3B5FE1A896F8FCB256B814BD100FFBF5359510D8FD243DB014DBCFA3036C857A41DCBAE29ECE25012AF0B88827A1B3F3FA6E75EDF1790B0CCD794D0E733315743EF50FA18E5E1A93DC5D1EB28F555C0A8541B729954EA1865C6FDBE810D153CB50C024E8E7A59D324C22B626A30F4AAA0FA46EDCA4CC42F4B2D033B147DA54A67D103633A88EBFFF0EFFB61AA98DD2B057700FAC0986A9FB27C2CC29EE30B699DE063C76A1E2863D13951C35C5ABD357555781D2A5E68B0BFACF2E11747006E0810DD0CF97D585318A3B0DF7A67465EC3761004AA9B7C141B4E5444D9EB649BBD94F983FCFAEC982D994C7A620DE2D8AEE012BFD22AA9322F3DD3BD5CE90C17660D18F8CB679B02BDABC0D4D0F876B0DD6D258E08DC50B35544A4BDBE5F75604493D5FDF98B7FB812475C7B7122DDEC512322E1855C31105397AF284B7C2B4DC315D2E8D5017BBD2400885D5EB6C321B5093EF98A14EB4C29DC2B7DF9565D9E23A2BE6A2E334CE3485A8677E463DD86F49E3B56D2974F7D930FFDD60BA54AB49AE9DCDC588A4FC7AFCDB89A7713C51FA97BFA8868EE207C3C0032FDB302E45DFA0DFD8A2DE4D50A959A424626CC92CE74F8A2627C3B20406D714BB64825FBAE1B44A2F7569E32A8CBB41DBA3D9115691B07C3951A2D1394BF06BB0690B710D438CCC4E5B92B0CF302109A60C836E3AB40E4D3579C2E1C77F432C62925A751D92A564440A563B3C373D9A46FFCB0EB478962450C11192FDE187718F9AEDFF61DFE39AE98714B1DD49C356593F23F2BADE0E753B25BDCB3D618E3CDC5C5D8F37974A449E6E2D21B46FA90435F399AFF98988DEA9048B8031E1AE2E4B2B7C3FBB7CA775B6058500DB8852FF7358251CBF12A3CA233719760D251939A29778D7B4BDE15B5244B8AB47555C18925222331443DD6B227282A101443F14851734796FF4E323B66ED8304E594973EDBCA57B9413BB83574673623CB9BA282F92FBE49BFC7D6D18644C1741DAFEE86B58A174AA1B576F2599CAA8F15C9AC513CCC3778EAB81D6EF90557E73E207E96BC2D83BD3FED3717B0E8E527AE27BD05B28962280099AD1AF8C8D0B0E668EDC73AB3BD7E21C9C9134BFBC837BBC8E68FE8DF48365491371D378CB768A24A956F0D625D47EDBBAB051E4B4EE5D59574A4F2C4371D491ED182CD945DDAF11EB17382A58F2AFB6B79DE3EA1636C67449340F77A1CF14DFEDCB42B18BFFB866DD007B9A606C7BAEA70F9C5EAC98CBB52ECE5932F2925ACEAAE412E6114090CB54145A751E430EF1CA3A418C4D76EA7D797FF882401FD21984F4FBC347C4BFBB5B2B946B65F4FE0C7B9E5E16CBC1B6612325A0C83A8740D5D885C443EB8D02289BFC72E3BD2925E599B863F117C8A32E81F4B6F2C0C5D8CEA6E75C03E564E3F8D1663B5F3D21D844B6F80FB982484809303019670115FF5CC5FF6681E1C9B9AB01EA719AECAB7A4C4F1044017449741C726A4D1D97D0FB0D390F37DE0F838038270AEDD5E058113252D4F8E91B1377FD24F528EEDF58AE575327BE17F4A9D68E24B39DDF1187C8ABCEB1A84AB6BAB0735F3756E512641E62D3B51DF0316D065949379DD06C07606A82126A129A2A70F91EF54096CFCBC3447B49D5DD5F7DC7AA9F3E86E8ECD581F51731DF726194CD3143CC1E608AE882EA8848CDFD9F3FF6282AC6D722C2D5F51F2652724FEB601E02E1F078E32B36892ED9E2DE0A637836A005B01CEFDADF90534049565E8B965224B3E7EFF5707F3DEB6BFDB8D8045549168CD1C81910E584978A555DE877CFBDCB8D7388D3081F9DD8067198562521FEE99C57E3401#)
+ (p #00E6BBCBEBFCA813CED7907F5FA73C4C2D3532AF7A7650C4A88563DF805D54D0CEA528347A60F703C8FFE91997505F8C238383E03C53DFD347D0E385A5CFFE4E2A944DD45ACBC481D54D7B22F4C59A2BFC8C686E527B907AD9C5ECE870D102550D8D4A02B404DAE7023CC8F0436DE5F50A7CE1F4E741147F676B5DC9437CB47727B93155AE5C1EBE236E9F436D723FF770104305A1460C21BE9361582CB107CAF036F0600BCC6D78DE73C1F44C25F377B9A65349E9B73C446E5C6281DCB68EC65AF684AB39F6C84CF96E4CD909B61FA2D8BBB69A7994B78865FFEACD3838F851C944039C2422B75AE4F9C2A1702B005641EB41CE9FB042757E86F6E9651428EBA4D908D60A99AD61E5D09E7A05C7E59A9615DE965200CFB75A228B1D5DB8D2C040A65D940D5516C9FC5069B94D2F1903EF6B07F70ECF3E8D720F74139A4647D79131835CF7F15EA839350A00BD9D733359503497BCE39A2497CACCAD41B0AE7A36E6F01FECA1B0B062F9C3232BD6F6734C97DB2EE7DE050370087210F8161B07237E712E29E0BA6B2B661EC22DAD0509D50EF75255D40B954D2B3694C30E5982EB2D15B72A8709BC4F9B6FEFC4E6F01FF04D128311209B4C4353AF43BDE58D631DB7E047D7B469CDE4A9176415F6F7B60BC129E0BA8363D77140DA0FC685DB76FCB968C8C58657DB86FC908E7D11F41D907CA367C17AD3EF81280721FD40E6AEDC118538AFE109B8FA818502982578BB2EAE3ACC3028EF79C4CAB575CC8473E05FF5D911186058BCA7F5269FAA66CBB68CE47EE0748F2A8E52EEB8475030D34E54C365572BA282226730ADA3BEF16D582A409F15AB89188F1737F7CA82EE0D96BD2B3A2153CDF6EE27FD04F4AEF4AA3FC6EB02E92EC21359864507EAD3E09D3117EEDD61AF34265412C362EE01B26B925BC74A2679A1C112C653AE88FD124220742A05DDCB1CDE7DF2342669FDF76E1C3F9BF8FE13633ADF33050FA491FA708A918ECA787FF074E90F9A0AA216ACB1160D22BE7A9817DEF5FA2E27FC906ACF5B5774A5DB069A66F5F1752D7521E1CE49F8888218BA24C97A92C287DAB8B08B4433EC1DDEB5C7A3D96956EBCC46A2DE2B95CACA91BECBCB15DCA20D13C977F50F6DC0D705DB78B597581F850E20E0EEB6EA9A7A9D2708A650A3CD0748EE1DDAEA559C80D2A00F2DBD29C3EF58C13CB0B84AFA30C508BC8AD71A4FC3E14690F16B52943013D7BB09F5627D7D1343DAED88198D5ADA23E0B94484E06A827FE49227540110ECEC9E354F87E27496B7FF5ED31521817C8B5B182129EE0C521C85A996BF5EAF1F87583BDFE69386EDCE63337252F58D37AEC742702D97F3B97CE0FD06EE60EE4380C2E48D7AAD49E26F76CE981237ADB617B0BB6D59DAE31B6335866E7F9670F8A25D9BC44D7C32602BA3D58002BD53473E3F781249AB17C1C78C496611#)
+ (q #00ED6FA36442A240865581B5C398C93F55AFD5386A801AF1D8BF8A9FF8AB9C578F97DA02AFC44180AB581A1E10A4D65B7D1E9C0B04D57FB1FD13B7ECF1AD7C0296F1F5D52C3223CB117E6C6BED1FDA701A7A4079FBD35B180D2295B216FEAB284F85594EDDDC179C9AAE6E6CA545D2FBCA308B0961B21A1B4A4E9DE27CF8D6922FC902C35313B05F0FFB5CC667E64E0706D5210D3919074B384CA5968359CBA5F4BCA096323AD48E2CDE9D25F08E2EF945A1DD46457F48B4BF8EBEC2DC3737CC09E333E30F17A3ACD19567A5C5D200E7A4303A97A893F0884ED3CD976B41C2BCEEF04D9FCE4F30218CC9AAE26FFC5749B10011B805ADA9C4857B691A7A820F2564DF5979F570F8D524DDE268F702891E9CCDBD9F821C2ECF27F60C795E743AC67CADB07D22D3A7BD322DA9C3E7A35AC6A35333F871FE6DE0162BA2A1F9565E411ADD424FF0727B2280BAFDDF522C272D3A2910EFE27F5590F8E0F6C38BEA1895A0893755F44BDF41FECF3BF3BA27C6D6F036A1AA70736DE71465FA78EA46F34341E05DE7AB37A5074B4E99E0BAB54D658629503E1242ACAFDE08721058F208D3F62FAE742D158CAE521994514CF0BEC580F075046319FBFC8E971F0FF5EED9E2AB7D194CD21ECCCB2E54D239AA3B0254F4AB1641E6E8E1512FF1D1ED579205F1807898828CFA24B80D230FA6C52C6A92348E1A069C239F7B6F2E7CC995BD3CD1B413FC86C626FE962C7EC3CF19FA193B3A732AF17E51E6B57CC263DE82A5C45CB9E37C2BAB44E88E5792FBBC40748F86134D221BF775E2BF57F98A884FCBA494718661A3FF73AAE04A6F5CDFB6F143D680D09BA4CCD6C6F186E92569B8F67A35B5796B9F2ED404F11C54ED290D7D7836501473F06D8A623D53AB586B644F3F5BDF8B0B670CA696A23B7B52319C91D2CA27FCDF421030CEA8A6B079FEC2E467BE0427AFCEA12648F3E12F09745166D20D3D1CD6965EABA2732469C077B3C4E44D3503D882937DA5139076144FAEAB75083BF4E16725BB9625A99DE92F6F226DE343F73E974577F8D6F5B57CFBEB60763627240A28C90A73BC7A9E47D74CBABB6486988C983A5A3DC91A4D8E353AE6C608499D21391E32D8EF3A030925959B52C1BC03F17AAE2FEE4E28B2B51889EC2A5FE587C60139C9CF29AF46555B089B54B5EF0BB3B92BCC0EA0E6E94F944FE8E9741DDA902F185E0D16876A10351AD22FE6ABD4378AD74A13CD2BD9696F0B59A069CD6582F92458A89B15648E833614598D6FDABAC026791CDB3FA87873CA86E3DF7187C9230AFFB1089EF83B8CB54856ADC234D07DF479514A8F47EC9903930E47F9E93AE1F96D7358F4208E19CCED8AEC063AFE8A31E39C921F7D7867D57E8F68B1494793E6DCD06F3DC68809BD455DBB44076D6AB64586E0A09A42CEBA2829A5F81BDEA5EDB23DC251D69C373D2E275201#)
+ (u #00EA2CBBEFBFFBD4BD3850584AEA315F88ED892F7398E5C4ECD17F8E4588B073DA32AC708DADC0E55417553FB4DC25130F42A9A04E435C63E1091744232D53FF98ABA450E3B91AF512631E28BF453BE4FCB9713112F890F368523FE175B0909385F0B404B3E6370FA6DB33490DC216CE3DE548FDDF68C81FE49BB9683C30FA6D1DE8B019A94683E508B720F2EDA20133325FD4644620D086182F1E8283215D2BCBBC1B302DEA714CE1E59FE8E996489018078F8CCDDAEF086EFDF82BA45DF424E539ABC9D61ABEC14346275AA9256031514AAC59FF40C7D1B4363AC7C74E8CC3854C9E57F6913C2CFC599E9DBB446D553482C9B531563A7CADD562D64151B3961FB52A0D542406D491F8090EBB737C388016F95918313C0EC987F701F2A25AE3F0CEF2B9F3460A9E48AEE382F01CB09B0A9372104FAC2EE692BB2B14E6FE376A29891687E157C40F09FB3283402E4D319C9791E7A06025C542B4411EEA71890D22E34E8038B3002AC7FB75A50ED29AAEAFF36588950A06A8D2139B0420673DCB37087E8196A034D0A5C78A824BCD0A74BBD7E08B04B8F08F473C09F6350508CEB476DEE1E41D0CF960CA3E87AE8489811577F7D49CB1EF885453F7087B8126FB99028B5771EC9E159040109102DEE175DAFA038EE7B62B96797E56E6361C37DFC42398020114765E28C3F3B4B6A4C33A86A995A0D5647068B7147552F4E6130866527D4833949E9F9204406F096735F33BFD1BB57734E15D0B4035A37CCA7C897C18162B12951A684F586F1B7FF041A85B7F44FAC125A80AC782AD3F4D7EC52C318EEA52CFA6AF09EBA50813B5BAC8367B1FF80A99DB8BDEC3E3842455A06D22DA99F0BE5B52330D1D5C0CCACB3661D703BE1D96E7832A159C8858E08CC23101FBC0DE783D3209A80A3ED4EBCF57661B01D84EBCFBE70A0EC921588B8CD9B9BF21918D86C3C97B0F6BBF4037E80C99A349A1A2B78F337CC4029415FF0DB54AC9A3A1DF7E07482DC9F04E638C9D5BBAAD32A627F2EF1DC3E17AEC365E416C703C449AA40104DEC358202F7F78CCF77115ADAD567CDAE6B4B2C81DA4FBE6A97BBF2A704389911E4A5B39C3C1F187101E53B3DF7A0CE05C4B7956F4ED31DD225B46036C5344B3CDB236E5B1A12E159008D106D1CF6C14C5F7335A4A5D80E008F0106F636EF750723B50511F37B3BA6FFBEB27A270828B9CB123D7F59EA0BE956C0D024C77AC06086460998F18610ECB94651DF47AB37DDDCDB9797203A4321CBC1E6E85EC64919EB74AC7E2F3C15FEB5DFCCFC2359D353C8B6B600152D4211A55477FF31026B34C10C5F1FC1A1DD1C1EF6A14B26CFD1AF70D6BAA4461B4387631E4DCFDFFAB118F710A8B8B2D12EEC4924751720B9AA9D94527B9F19E8B352222567F662FC6753AA4BE22C2A851F2378AD5EE5539C1E0F4DD90400DD7DC6F1EA675D9#)
+ )
+ )
+ )
--- /dev/null
+/* rsacvt.c - A debug tool to convert RSA formats.
+ Copyright (C) 2009 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Input data format:
+
+=======
+# A hash denotes a comment line
+e861b700e17e8afe68[...]f1
+f7a7ca5367c661f8e6[...]61
+10001
+
+# After an empty line another input block may follow.
+7861b700e17e8afe68[...]f3
+e7a7ca5367c661f8e6[...]71
+3
+=========
+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <ctype.h>
+#ifdef HAVE_W32_SYSTEM
+# include <fcntl.h> /* We need setmode(). */
+#else
+# include <signal.h>
+#endif
+#include <assert.h>
+#include <unistd.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt.h"
+#else
+# include <gcrypt.h>
+# define PACKAGE_BUGREPORT "devnull@example.org"
+# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]"
+#endif
+
+
+#define PGM "rsacvt"
+
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member) DIM(((type *)0)->member)
+
+
+/* Verbose mode flag. */
+static int verbose;
+
+/* Prefix output with labels. */
+static int with_labels;
+
+/* Do not suppress leading zeroes. */
+static int keep_lz;
+
+/* Create parameters as specified by OpenPGP (rfc4880). That is we
+ don't store dmp1 and dmp1 but d and make sure that p is less than q. */
+static int openpgp_mode;
+
+
+/* Print a error message and exit the process with an error code. */
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ fputs (PGM ": ", stderr);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+static char *
+read_textline (FILE *fp)
+{
+ char line[4096];
+ char *p;
+ int any = 0;
+
+ /* Read line but skip over initial empty lines. */
+ do
+ {
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return NULL;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p = 0;
+ p = line + (*line? (strlen (line)-1):0);
+ for ( ;p > line; p--)
+ if (my_isascii (*p) && isspace (*p))
+ *p = 0;
+ }
+ while (!any && !*line);
+ any = 1;
+ }
+ while (*line == '#'); /* Always skip comment lines. */
+ if (verbose > 1)
+ fprintf (stderr, PGM ": received line: %s\n", line);
+ return gcry_xstrdup (line);
+}
+
+
+static gcry_mpi_t
+read_hexmpi_line (FILE *fp, int *got_eof)
+{
+ gpg_error_t err;
+ gcry_mpi_t a;
+ char *line;
+
+ *got_eof = 0;
+ line = read_textline (fp);
+ if (!line)
+ {
+ *got_eof = 1;
+ return NULL;
+ }
+ err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
+ gcry_free (line);
+ if (err)
+ a = NULL;
+ return a;
+}
+
+
+static int
+skip_to_empty_line (FILE *fp)
+{
+ char line[256];
+ char *p;
+
+ do
+ {
+ if (!fgets (line, sizeof line, fp))
+ {
+ if (feof (fp))
+ return -1;
+ die ("error reading input line: %s\n", strerror (errno));
+ }
+ p = strchr (line, '\n');
+ if (p)
+ *p =0;
+ }
+ while (*line);
+ return 0;
+}
+
+
+/* Print an MPI on a line. */
+static void
+print_mpi_line (const char *label, gcry_mpi_t a)
+{
+ unsigned char *buf, *p;
+ gcry_error_t err;
+ int writerr = 0;
+
+ if (with_labels && label)
+ printf ("%s = ", label);
+
+ err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+ if (err)
+ die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err));
+
+ p = buf;
+ if (!keep_lz && p[0] == '0' && p[1] == '0' && p[2])
+ p += 2;
+
+ printf ("%s\n", p);
+ if (ferror (stdout))
+ writerr++;
+ if (!writerr && fflush (stdout) == EOF)
+ writerr++;
+ if (writerr)
+ die ("writing output failed: %s\n", strerror (errno));
+ gcry_free (buf);
+}
+
+
+/* Compute and print missing RSA parameters. */
+static void
+compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e)
+{
+ gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u;
+ gcry_mpi_t phi, tmp_g, tmp_f;
+
+ rsa_n = gcry_mpi_new (0);
+ rsa_d = gcry_mpi_new (0);
+ rsa_pm1 = gcry_mpi_new (0);
+ rsa_qm1 = gcry_mpi_new (0);
+ rsa_u = gcry_mpi_new (0);
+
+ phi = gcry_mpi_new (0);
+ tmp_f = gcry_mpi_new (0);
+ tmp_g = gcry_mpi_new (0);
+
+ /* Check that p < q; if not swap p and q. */
+ if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0)
+ {
+ fprintf (stderr, PGM ": swapping p and q\n");
+ gcry_mpi_swap (rsa_p, rsa_q);
+ }
+
+ gcry_mpi_mul (rsa_n, rsa_p, rsa_q);
+
+
+ /* Compute the Euler totient: phi = (p-1)(q-1) */
+ gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1);
+ gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1);
+ gcry_mpi_mul (phi, rsa_pm1, rsa_qm1);
+
+ if (!gcry_mpi_gcd (tmp_g, rsa_e, phi))
+ die ("parameter 'e' does match 'p' and 'q'\n");
+
+ /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
+ gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1);
+ gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1);
+
+ /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */
+ gcry_mpi_invm (rsa_d, rsa_e, tmp_f);
+
+ /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */
+ gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1);
+ gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1);
+
+ /* Compute the CRT value: OpenPGP: u = p^{-1} mod q
+ Standard: iqmp = q^{-1} mod p */
+ if (openpgp_mode)
+ gcry_mpi_invm (rsa_u, rsa_p, rsa_q);
+ else
+ gcry_mpi_invm (rsa_u, rsa_q, rsa_p);
+
+ gcry_mpi_release (phi);
+ gcry_mpi_release (tmp_f);
+ gcry_mpi_release (tmp_g);
+
+ /* Print everything. */
+ print_mpi_line ("n", rsa_n);
+ print_mpi_line ("e", rsa_e);
+ if (openpgp_mode)
+ print_mpi_line ("d", rsa_d);
+ print_mpi_line ("p", rsa_p);
+ print_mpi_line ("q", rsa_q);
+ if (openpgp_mode)
+ print_mpi_line ("u", rsa_u);
+ else
+ {
+ print_mpi_line ("dmp1", rsa_pm1);
+ print_mpi_line ("dmq1", rsa_qm1);
+ print_mpi_line ("iqmp", rsa_u);
+ }
+
+ gcry_mpi_release (rsa_n);
+ gcry_mpi_release (rsa_d);
+ gcry_mpi_release (rsa_pm1);
+ gcry_mpi_release (rsa_qm1);
+ gcry_mpi_release (rsa_u);
+}
+
+
+\f
+static void
+usage (int show_help)
+{
+ if (!show_help)
+ {
+ fputs ("usage: " PGM
+ " [OPTION] [FILE] (try --help for more information)\n", stderr);
+ exit (2);
+ }
+ fputs
+ ("Usage: " PGM " [OPTIONS] [FILE]\n"
+ "Take RSA parameters p, n, e and compute missing parameters.\n"
+ "OPTIONS:\n"
+ " --openpgp Compute as specified by RFC4880\n"
+ " --labels Prefix output with labels\n"
+ " --keep-lz Keep all leading zeroes in the output\n"
+ " --verbose Print additional information\n"
+ " --version Print version information\n"
+ " --help Print this text\n"
+ "With no FILE, or if FILE is -, read standard input.\n"
+ "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
+ exit (0);
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int last_argc = -1;
+ FILE *input;
+ gcry_mpi_t rsa_p, rsa_q, rsa_e;
+ int got_eof;
+ int any = 0;
+
+ if (argc)
+ { argc--; argv++; }
+
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ usage (1);
+ }
+ else if (!strcmp (*argv, "--version"))
+ {
+ fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout);
+ printf ("libgcrypt %s\n", gcry_check_version (NULL));
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose++;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--labels"))
+ {
+ with_labels = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--keep-lz"))
+ {
+ keep_lz = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--openpgp"))
+ {
+ openpgp_mode = 1;
+ argc--; argv++;
+ }
+ }
+
+ if (argc > 1)
+ usage (0);
+
+#if !defined (HAVE_W32_SYSTEM) && !defined (_WIN32)
+ signal (SIGPIPE, SIG_IGN);
+#endif
+
+ if (argc == 1 && strcmp (argv[0], "-"))
+ {
+ input = fopen (argv[0], "r");
+ if (!input)
+ die ("can't open `%s': %s\n", argv[0], strerror (errno));
+ }
+ else
+ input = stdin;
+
+ gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+ if (!gcry_check_version ("1.4.0"))
+ die ("Libgcrypt is not sufficient enough\n");
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ do
+ {
+ rsa_p = read_hexmpi_line (input, &got_eof);
+ if (!rsa_p && got_eof)
+ break;
+ if (!rsa_p)
+ die ("RSA parameter 'p' missing or not properly hex encoded\n");
+ rsa_q = read_hexmpi_line (input, &got_eof);
+ if (!rsa_q)
+ die ("RSA parameter 'q' missing or not properly hex encoded\n");
+ rsa_e = read_hexmpi_line (input, &got_eof);
+ if (!rsa_e)
+ die ("RSA parameter 'e' missing or not properly hex encoded\n");
+ got_eof = skip_to_empty_line (input);
+
+ if (any)
+ putchar ('\n');
+
+ compute_missing (rsa_p, rsa_q, rsa_e);
+
+ gcry_mpi_release (rsa_p);
+ gcry_mpi_release (rsa_q);
+ gcry_mpi_release (rsa_e);
+
+ any = 1;
+ }
+ while (!got_eof);
+
+ return 0;
+}
--- /dev/null
+/* t-kdf.c - KDF regression tests
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "../src/gcrypt.h"
+
+#ifndef DIM
+# define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#endif
+
+/* Program option flags. */
+static int verbose;
+static int error_count;
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+
+static void
+check_openpgp (void)
+{
+ /* Test vectors manually created with gpg 1.4 derived code: In
+ passphrase.c:hash_passpharse, add this code to the end of the
+ function:
+
+ ===8<===
+ printf ("{\n"
+ " \"");
+ for (i=0; i < pwlen; i++)
+ {
+ if (i && !(i%16))
+ printf ("\"\n \"");
+ printf ("\\x%02x", ((const unsigned char *)pw)[i]);
+ }
+ printf ("\", %d,\n", pwlen);
+
+ printf (" %s, %s,\n",
+ s2k->mode == 0? "GCRY_KDF_SIMPLE_S2K":
+ s2k->mode == 1? "GCRY_KDF_SALTED_S2K":
+ s2k->mode == 3? "GCRY_KDF_ITERSALTED_S2K":"?",
+ s2k->hash_algo == DIGEST_ALGO_MD5 ? "GCRY_MD_MD5" :
+ s2k->hash_algo == DIGEST_ALGO_SHA1 ? "GCRY_MD_SHA1" :
+ s2k->hash_algo == DIGEST_ALGO_RMD160? "GCRY_MD_RMD160" :
+ s2k->hash_algo == DIGEST_ALGO_SHA256? "GCRY_MD_SHA256" :
+ s2k->hash_algo == DIGEST_ALGO_SHA384? "GCRY_MD_SHA384" :
+ s2k->hash_algo == DIGEST_ALGO_SHA512? "GCRY_MD_SHA512" :
+ s2k->hash_algo == DIGEST_ALGO_SHA224? "GCRY_MD_SHA224" : "?");
+
+ if (s2k->mode == 0)
+ printf (" NULL, 0,\n");
+ else
+ {
+ printf (" \"");
+ for (i=0; i < 8; i++)
+ printf ("\\x%02x", (unsigned int)s2k->salt[i]);
+ printf ("\", %d,\n", 8);
+ }
+
+ if (s2k->mode == 3)
+ printf (" %lu,\n", (unsigned long)S2K_DECODE_COUNT(s2k->count));
+ else
+ printf (" 0,\n");
+
+ printf (" %d,\n", (int)dek->keylen);
+
+ printf (" \"");
+ for (i=0; i < dek->keylen; i++)
+ {
+ if (i && !(i%16))
+ printf ("\"\n \"");
+ printf ("\\x%02x", ((unsigned char *)dek->key)[i]);
+ }
+ printf ("\"\n},\n");
+ ===>8===
+
+ Then prepare a file x.inp with utf8 encoding:
+
+ ===8<===
+ 0 aes md5 1024 a
+ 0 aes md5 1024 ab
+ 0 aes md5 1024 abc
+ 0 aes md5 1024 abcd
+ 0 aes md5 1024 abcde
+ 0 aes md5 1024 abcdef
+ 0 aes md5 1024 abcdefg
+ 0 aes md5 1024 abcdefgh
+ 0 aes md5 1024 abcdefghi
+ 0 aes md5 1024 abcdefghijklmno
+ 0 aes md5 1024 abcdefghijklmnop
+ 0 aes md5 1024 abcdefghijklmnopq
+ 0 aes md5 1024 Long_sentence_used_as_passphrase
+ 0 aes md5 1024 With_utf8_umlauts:äüÖß
+ 0 aes sha1 1024 a
+ 0 aes sha1 1024 ab
+ 0 aes sha1 1024 abc
+ 0 aes sha1 1024 abcd
+ 0 aes sha1 1024 abcde
+ 0 aes sha1 1024 abcdef
+ 0 aes sha1 1024 abcdefg
+ 0 aes sha1 1024 abcdefgh
+ 0 aes sha1 1024 abcdefghi
+ 0 aes sha1 1024 abcdefghijklmno
+ 0 aes sha1 1024 abcdefghijklmnop
+ 0 aes sha1 1024 abcdefghijklmnopq
+ 0 aes sha1 1024 abcdefghijklmnopqr
+ 0 aes sha1 1024 abcdefghijklmnopqrs
+ 0 aes sha1 1024 abcdefghijklmnopqrst
+ 0 aes sha1 1024 abcdefghijklmnopqrstu
+ 0 aes sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes256 sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes sha1 1024 With_utf8_umlauts:äüÖß
+ 3 aes sha1 1024 a
+ 3 aes sha1 1024 ab
+ 3 aes sha1 1024 abc
+ 3 aes sha1 1024 abcd
+ 3 aes sha1 1024 abcde
+ 3 aes sha1 1024 abcdef
+ 3 aes sha1 1024 abcdefg
+ 3 aes sha1 1024 abcdefgh
+ 3 aes sha1 1024 abcdefghi
+ 3 aes sha1 1024 abcdefghijklmno
+ 3 aes sha1 1024 abcdefghijklmnop
+ 3 aes sha1 1024 abcdefghijklmnopq
+ 3 aes sha1 1024 abcdefghijklmnopqr
+ 3 aes sha1 1024 abcdefghijklmnopqrs
+ 3 aes sha1 1024 abcdefghijklmnopqrst
+ 3 aes sha1 1024 abcdefghijklmnopqrstu
+ 3 aes sha1 1024 With_utf8_umlauts:äüÖß
+ 3 aes sha1 1024 Long_sentence_used_as_passphrase
+ 3 aes sha1 10240 Long_sentence_used_as_passphrase
+ 3 aes sha1 102400 Long_sentence_used_as_passphrase
+ 3 aes192 sha1 1024 a
+ 3 aes192 sha1 1024 abcdefg
+ 3 aes192 sha1 1024 abcdefghi
+ 3 aes192 sha1 1024 abcdefghi
+ 3 aes192 sha1 1024 Long_sentence_used_as_passphrase
+ 3 aes256 sha1 1024 a
+ 3 aes256 sha1 1024 abcdefg
+ 3 aes256 sha1 1024 abcdefghi
+ 3 aes256 sha1 1024 abcdefghi
+ 3 aes256 sha1 1024 Long_sentence_used_as_passphrase
+ 0 aes sha256 1024 Long_sentence_used_as_passphrase
+ 1 aes sha256 1024 Long_sentence_used_as_passphrase
+ 3 aes sha256 1024 Long_sentence_used_as_passphrase
+ 3 aes sha256 10240 Long_sentence_used_as_passphrase
+ 3 aes sha384 1024 Long_sentence_used_as_passphrase
+ 3 aes sha512 1024 Long_sentence_used_as_passphrase
+ 3 aes256 sha512 1024 Long_sentence_used_as_passphrase
+ 3 3des sha512 1024 Long_sentence_used_as_passphrase
+ ===>8===
+
+ and finally using a proper utf-8 enabled shell, run:
+
+ cat x.inp | while read mode cipher digest count pass dummy; do \
+ ./gpg </dev/null -o /dev/null -c --passphrase "$pass" \
+ --s2k-mode $mode --s2k-digest $digest --s2k-count $count \
+ --cipher-algo $cipher ; done >x.out
+ */
+ static struct {
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ int algo;
+ int hashalgo;
+ const char *salt;
+ size_t saltlen;
+ unsigned long c; /* Iterations. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+ {
+ "\x61", 1,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x18\x7e\xf4\x43\x61\x22\xd1\xcc\x2f\x40\xdc\x2b\x92\xf0\xeb\xa0"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe2\xfc\x71\x4c\x47\x27\xee\x93\x95\xf3\x24\xcd\x2e\x7f\x33\x1f"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xab\x56\xb4\xd9\x2b\x40\x71\x3a\xcc\x5a\xf8\x99\x85\xd4\xb7\x86"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe8\x0b\x50\x17\x09\x89\x50\xfc\x58\xaa\xd8\x3c\x8c\x14\x97\x8e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x7a\xc6\x6c\x0f\x14\x8d\xe9\x51\x9b\x8b\xd2\x64\x31\x2c\x4d\x64"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe8\xdc\x40\x81\xb1\x34\x34\xb4\x51\x89\xa7\x20\xb7\x7b\x68\x18"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x8a\xa9\x9b\x1f\x43\x9f\xf7\x12\x93\xe9\x53\x57\xba\xc6\xfd\x94"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x8a\x73\x19\xdb\xf6\x54\x4a\x74\x22\xc9\xe2\x54\x52\x58\x0e\xa5"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x1d\x64\xdc\xe2\x39\xc4\x43\x7b\x77\x36\x04\x1d\xb0\x89\xe1\xb9"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x9a\x8d\x98\x45\xa6\xb4\xd8\x2d\xfc\xb2\xc2\xe3\x51\x62\xc8\x30"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x35\x2a\xf0\xfc\xdf\xe9\xbb\x62\x16\xfc\x99\x9d\x8d\x58\x05\xcb"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5,
+ NULL, 0,
+ 0,
+ 16,
+ "\x21\xa4\xeb\xd8\xfd\xf0\x59\x25\xd1\x32\x31\xdb\xe7\xf2\x13\x5d"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x86\xf7\xe4\x37\xfa\xa5\xa7\xfc\xe1\x5d\x1d\xdc\xb9\xea\xea\xea"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xda\x23\x61\x4e\x02\x46\x9a\x0d\x7c\x7b\xd1\xbd\xab\x5c\x9c\x47"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x81\xfe\x8b\xfe\x87\x57\x6c\x3e\xcb\x22\x42\x6f\x8e\x57\x84\x73"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x03\xde\x6c\x57\x0b\xfe\x24\xbf\xc3\x28\xcc\xd7\xca\x46\xb7\x6e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x1f\x8a\xc1\x0f\x23\xc5\xb5\xbc\x11\x67\xbd\xa8\x4b\x83\x3e\x5c"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x2f\xb5\xe1\x34\x19\xfc\x89\x24\x68\x65\xe7\xa3\x24\xf4\x76\xec"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x42\x5a\xf1\x2a\x07\x43\x50\x2b\x32\x2e\x93\xa0\x15\xbc\xf8\x68"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xc6\x3b\x19\xf1\xe4\xc8\xb5\xf7\x6b\x25\xc4\x9b\x8b\x87\xf5\x7d"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x29\x38\xdc\xc2\xe3\xaa\x77\x98\x7c\x7e\x5d\x4a\x0f\x26\x96\x67"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x14\xf3\x99\x52\x88\xac\xd1\x89\xe6\xe5\x0a\x7a\xf4\x7e\xe7\x09"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xd8\x3d\x62\x1f\xcd\x2d\x4d\x29\x85\x54\x70\x43\xa7\xa5\xfd\x4d"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72", 18,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe3\x81\xfe\x42\xc5\x7e\x48\xa0\x82\x17\x86\x41\xef\xfd\x1c\xb9"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73", 19,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x89\x3e\x69\xff\x01\x09\xf3\x45\x9c\x42\x43\x01\x3b\x3d\xe8\xb1"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74", 20,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x14\xa2\x3a\xd7\x0f\x2a\x5d\xd7\x25\x57\x5d\xe6\xc4\x3e\x1c\xdd"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75", 21,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xec\xa9\x86\xb9\x5d\x58\x7f\x34\xd7\x1c\xa7\x75\x2a\x4e\x00\x10"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 32,
+ "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f"
+ "\xc3\x7b\x3a\xb2\xef\x4d\x68\xaa\x9c\xd7\xe4\x88\xee\xd1\x5e\x70"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1,
+ NULL, 0,
+ 0,
+ 16,
+ "\xe0\x4e\x1e\xe3\xad\x0b\x49\x7c\x7a\x5f\x37\x3b\x4d\x90\x3c\x2e"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x6d\x47\xe3\x68\x5d\x2c\x36\x16", 8,
+ 1024,
+ 16,
+ "\x41\x9f\x48\x6e\xbf\xe6\xdd\x05\x9a\x72\x23\x17\x44\xd8\xd3\xf3"
+ },
+ {
+ "\x61\x62", 2,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7c\x34\x78\xfb\x28\x2d\x25\xc7", 8,
+ 1024,
+ 16,
+ "\x0a\x9d\x09\x06\x43\x3d\x4f\xf9\x87\xd6\xf7\x48\x90\xde\xd1\x1c"
+ },
+ {
+ "\x61\x62\x63", 3,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xc3\x16\x37\x2e\x27\xf6\x9f\x6f", 8,
+ 1024,
+ 16,
+ "\xf8\x27\xa0\x07\xc6\xcb\xdd\xf1\xfe\x5c\x88\x3a\xfc\xcd\x84\x4d"
+ },
+ {
+ "\x61\x62\x63\x64", 4,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xf0\x0c\x73\x38\xb7\xc3\xd5\x14", 8,
+ 1024,
+ 16,
+ "\x9b\x5f\x26\xba\x52\x3b\xcd\xd9\xa5\x2a\xef\x3c\x03\x4d\xd1\x52"
+ },
+ {
+ "\x61\x62\x63\x64\x65", 5,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xe1\x7d\xa2\x36\x09\x59\xee\xc5", 8,
+ 1024,
+ 16,
+ "\x94\x9d\x5b\x1a\x5a\x66\x8c\xfa\x8f\x6f\x22\xaf\x8b\x60\x9f\xaf"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66", 6,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xaf\xa7\x0c\x68\xdf\x7e\xaa\x27", 8,
+ 1024,
+ 16,
+ "\xe5\x38\xf4\x39\x62\x27\xcd\xcc\x91\x37\x7f\x1b\xdc\x58\x64\x27"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x40\x57\xb2\x9d\x5f\xbb\x11\x4f", 8,
+ 1024,
+ 16,
+ "\xad\xa2\x33\xd9\xdd\xe0\xfb\x94\x8e\xcc\xec\xcc\xb3\xa8\x3a\x9e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68", 8,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x38\xf5\x65\xc5\x0f\x8c\x19\x61", 8,
+ 1024,
+ 16,
+ "\xa0\xb0\x3e\x29\x76\xe6\x8f\xa0\xd8\x34\x8f\xa4\x2d\xfd\x65\xee"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xc3\xb7\x99\xcc\xda\x2d\x05\x7b", 8,
+ 1024,
+ 16,
+ "\x27\x21\xc8\x99\x5f\xcf\x20\xeb\xf2\xd9\xff\x6a\x69\xff\xad\xe8"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7d\xd8\x68\x8a\x1c\xc5\x47\x22", 8,
+ 1024,
+ 16,
+ "\x0f\x96\x7a\x12\x23\x54\xf6\x92\x61\x67\x07\xb4\x68\x17\xb8\xaa"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x8a\x95\xd4\x88\x0b\xb8\xe9\x9d", 8,
+ 1024,
+ 16,
+ "\xcc\xe4\xc8\x82\x53\x32\xf1\x93\x5a\x00\xd4\x7f\xd4\x46\xfa\x07"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71", 17,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xb5\x22\x48\xa6\xc4\xad\x74\x67", 8,
+ 1024,
+ 16,
+ "\x0c\xe3\xe0\xee\x3d\x8f\x35\xd2\x35\x14\x14\x29\x0c\xf1\xe3\x34"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72", 18,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xac\x9f\x04\x63\x83\x0e\x3c\x95", 8,
+ 1024,
+ 16,
+ "\x49\x0a\x04\x68\xa8\x2a\x43\x6f\xb9\x73\x94\xb4\x85\x9a\xaa\x0e"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73", 19,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x03\x6f\x60\x30\x3a\x19\x61\x0d", 8,
+ 1024,
+ 16,
+ "\x15\xe5\x9b\xbf\x1c\xf0\xbe\x74\x95\x1a\xb2\xc4\xda\x09\xcd\x99"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74", 20,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x51\x40\xa5\x57\xf5\x28\xfd\x03", 8,
+ 1024,
+ 16,
+ "\xa6\xf2\x7e\x6b\x30\x4d\x8d\x67\xd4\xa2\x7f\xa2\x57\x27\xab\x96"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
+ "\x71\x72\x73\x74\x75", 21,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x4c\xf1\x10\x11\x04\x70\xd3\x6e", 8,
+ 1024,
+ 16,
+ "\x2c\x50\x79\x8d\x83\x23\xac\xd6\x22\x29\x37\xaf\x15\x0d\xdd\x8f"
+ },
+ {
+ "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74"
+ "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xfe\x3a\x25\xcb\x78\xef\xe1\x21", 8,
+ 1024,
+ 16,
+ "\x2a\xb0\x53\x08\xf3\x2f\xd4\x6e\xeb\x01\x49\x5d\x87\xf6\x27\xf6"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x04\x97\xd0\x02\x6a\x44\x2d\xde", 8,
+ 1024,
+ 16,
+ "\x57\xf5\x70\x41\xa0\x9b\x8c\x09\xca\x74\xa9\x22\xa5\x82\x2d\x17"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xdd\xf3\x31\x7c\xce\xf4\x81\x26", 8,
+ 10240,
+ 16,
+ "\xc3\xdd\x01\x6d\xaf\xf6\x58\xc8\xd7\x79\xb4\x40\x00\xb5\xe8\x0b"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x95\xd6\x72\x4e\xfb\xe1\xc3\x1a", 8,
+ 102400,
+ 16,
+ "\xf2\x3f\x36\x7f\xb4\x6a\xd0\x3a\x31\x9e\x65\x11\x8e\x2b\x99\x9b"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x6d\x69\x15\x18\xe4\x13\x42\x82", 8,
+ 1024,
+ 24,
+ "\x28\x0c\x7e\xf2\x31\xf6\x1c\x6b\x5c\xef\x6a\xd5\x22\x64\x97\x91"
+ "\xe3\x5e\x37\xfd\x50\xe2\xfc\x6c"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x9b\x76\x5e\x81\xde\x13\xdf\x15", 8,
+ 1024,
+ 24,
+ "\x91\x1b\xa1\xc1\x7b\x4f\xc3\xb1\x80\x61\x26\x08\xbe\x53\xe6\x50"
+ "\x40\x6f\x28\xed\xc6\xe6\x67\x55"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x7a\xac\xcc\x6e\x15\x56\xbd\xa1", 8,
+ 1024,
+ 24,
+ "\xfa\x7e\x20\x07\xb6\x47\xb0\x09\x46\xb8\x38\xfb\xa1\xaf\xf7\x75"
+ "\x2a\xfa\x77\x14\x06\x54\xcb\x34"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x1c\x68\xf8\xfb\x98\xf7\x8c\x39", 8,
+ 1024,
+ 24,
+ "\xcb\x1e\x86\xf5\xe0\xe4\xfb\xbf\x71\x34\x99\x24\xf4\x39\x8c\xc2"
+ "\x8e\x25\x1c\x4c\x96\x47\x22\xe8"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x10\xa9\x4e\xc1\xa5\xec\x17\x52", 8,
+ 1024,
+ 24,
+ "\x0f\x83\xa2\x77\x92\xbb\xe4\x58\x68\xc5\xf2\x14\x6e\x6e\x2e\x6b"
+ "\x98\x17\x70\x92\x07\x44\xe0\x51"
+ },
+ {
+ "\x61", 1,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xef\x8f\x37\x61\x8f\xab\xae\x4f", 8,
+ 1024,
+ 32,
+ "\x6d\x65\xae\x86\x23\x91\x39\x98\xec\x1c\x23\x44\xb6\x0d\xad\x32"
+ "\x54\x46\xc7\x23\x26\xbb\xdf\x4b\x54\x6e\xd4\xc2\xfa\xc6\x17\x17"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67", 7,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xaa\xfb\xd9\x06\x7d\x7c\x40\xaf", 8,
+ 1024,
+ 32,
+ "\x7d\x10\x54\x13\x3c\x43\x7a\xb3\x54\x1f\x38\xd4\x8f\x70\x0a\x09"
+ "\xe2\xfa\xab\x97\x9a\x70\x16\xef\x66\x68\xca\x34\x2e\xce\xfa\x1f"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x58\x03\x4f\x56\x8b\x97\xd4\x98", 8,
+ 1024,
+ 32,
+ "\xf7\x40\xb1\x25\x86\x0d\x35\x8f\x9f\x91\x2d\xce\x04\xee\x5a\x04"
+ "\x9d\xbd\x44\x23\x4c\xa6\xbb\xab\xb0\xd0\x56\x82\xa9\xda\x47\x16"
+ },
+ {
+ "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\x5d\x41\x3d\xa3\xa7\xfc\x5d\x0c", 8,
+ 1024,
+ 32,
+ "\x4c\x7a\x86\xed\x81\x8a\x94\x99\x7d\x4a\xc4\xf7\x1c\xf8\x08\xdb"
+ "\x09\x35\xd9\xa3\x2d\x22\xde\x32\x2d\x74\x38\xe5\xc8\xf2\x50\x6e"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1,
+ "\xca\xa7\xdc\x59\xce\x31\xe7\x49", 8,
+ 1024,
+ 32,
+ "\x67\xe9\xd6\x29\x49\x1c\xb6\xa0\x85\xe8\xf9\x8b\x85\x47\x3a\x7e"
+ "\xa7\xee\x89\x52\x6f\x19\x00\x53\x93\x07\x0a\x8b\xb9\xa8\x86\x94"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA256,
+ NULL, 0,
+ 0,
+ 16,
+ "\x88\x36\x78\x6b\xd9\x5a\x62\xff\x47\xd3\xfb\x79\xc9\x08\x70\x56"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_SALTED_S2K, GCRY_MD_SHA256,
+ "\x05\x8b\xfe\x31\xaa\xf3\x29\x11", 8,
+ 0,
+ 16,
+ "\xb2\x42\xfe\x5e\x09\x02\xd9\x62\xb9\x35\xf3\xa8\x43\x80\x9f\xb1"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
+ "\xd3\x4a\xea\xc9\x97\x1b\xcc\x83", 8,
+ 1024,
+ 16,
+ "\x35\x37\x99\x62\x07\x26\x68\x23\x05\x47\xb2\xa0\x0b\x2b\x2b\x8d"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256,
+ "\x5e\x71\xbd\x00\x5f\x96\xc4\x23", 8,
+ 10240,
+ 16,
+ "\xa1\x6a\xee\xba\xde\x73\x25\x25\xd1\xab\xa0\xc5\x7e\xc6\x39\xa7"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA384,
+ "\xc3\x08\xeb\x17\x62\x08\x89\xef", 8,
+ 1024,
+ 16,
+ "\x9b\x7f\x0c\x81\x6f\x71\x59\x9b\xd5\xf6\xbf\x3a\x86\x20\x16\x33"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xe6\x7d\x13\x6b\x39\xe3\x44\x05", 8,
+ 1024,
+ 16,
+ "\xc8\xcd\x4b\xa4\xf3\xf1\xd5\xb0\x59\x06\xf0\xbb\x89\x34\x6a\xad"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xed\x7d\x30\x47\xe4\xc3\xf8\xb6", 8,
+ 1024,
+ 32,
+ "\x89\x7a\xef\x70\x97\xe7\x10\xdb\x75\xcc\x20\x22\xab\x7b\xf3\x05"
+ "\x4b\xb6\x2e\x17\x11\x9f\xd6\xeb\xbf\xdf\x4d\x70\x59\xf0\xf9\xe5"
+ },
+ {
+ "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73"
+ "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32,
+ GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512,
+ "\xbb\x1a\x45\x30\x68\x62\x6d\x63", 8,
+ 1024,
+ 24,
+ "\xde\x5c\xb8\xd5\x75\xf6\xad\x69\x5b\xc9\xf6\x2f\xba\xeb\xfb\x36"
+ "\x34\xf2\xb8\xee\x3b\x37\x21\xb7"
+ }
+ };
+ int tvidx;
+ gpg_error_t err;
+ unsigned char outbuf[32];
+ int i;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ if (tv[tvidx].disabled)
+ continue;
+ if (verbose)
+ fprintf (stderr, "checking S2K test vector %d\n", tvidx);
+ assert (tv[tvidx].dklen <= sizeof outbuf);
+ err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+ tv[tvidx].algo, tv[tvidx].hashalgo,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].c, tv[tvidx].dklen, outbuf);
+ if (err)
+ fail ("s2k test %d failed: %s\n", tvidx, gpg_strerror (err));
+ else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+ {
+ fail ("s2k test %d failed: mismatch\n", tvidx);
+ fputs ("got:", stderr);
+ for (i=0; i < tv[tvidx].dklen; i++)
+ fprintf (stderr, " %02x", outbuf[i]);
+ putc ('\n', stderr);
+ }
+ }
+}
+
+
+static void
+check_pbkdf2 (void)
+{
+ /* Test vectors are from RFC-6070. */
+ static struct {
+ const char *p; /* Passphrase. */
+ size_t plen; /* Length of P. */
+ const char *salt;
+ size_t saltlen;
+ unsigned long c; /* Iterations. */
+ int dklen; /* Requested key length. */
+ const char *dk; /* Derived key. */
+ int disabled;
+ } tv[] = {
+ {
+ "password", 8,
+ "salt", 4,
+ 1,
+ 20,
+ "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9"
+ "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ 2,
+ 20,
+ "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e"
+ "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ 4096,
+ 20,
+ "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad"
+ "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1"
+ },
+ {
+ "password", 8,
+ "salt", 4,
+ 16777216,
+ 20,
+ "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94"
+ "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84",
+ 1 /* This test takes too long. */
+ },
+ {
+ "passwordPASSWORDpassword", 24,
+ "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36,
+ 4096,
+ 25,
+ "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8"
+ "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96"
+ "\x4c\xf2\xf0\x70\x38"
+ },
+ {
+ "pass\0word", 9,
+ "sa\0lt", 5,
+ 4096,
+ 16,
+ "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
+ "\xd7\xf0\x34\x25\xe0\xc3"
+ }
+ };
+ int tvidx;
+ gpg_error_t err;
+ unsigned char outbuf[32];
+ int i;
+
+ for (tvidx=0; tvidx < DIM(tv); tvidx++)
+ {
+ if (tv[tvidx].disabled)
+ continue;
+ if (verbose)
+ fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx);
+ assert (tv[tvidx].dklen <= sizeof outbuf);
+ err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+ GCRY_KDF_PBKDF2, GCRY_MD_SHA1,
+ tv[tvidx].salt, tv[tvidx].saltlen,
+ tv[tvidx].c, tv[tvidx].dklen, outbuf);
+ if (err)
+ fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err));
+ else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+ {
+ fail ("pbkdf2 test %d failed: mismatch\n", tvidx);
+ fputs ("got:", stderr);
+ for (i=0; i < tv[tvidx].dklen; i++)
+ fprintf (stderr, " %02x", outbuf[i]);
+ putc ('\n', stderr);
+ }
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ check_openpgp ();
+ check_pbkdf2 ();
+
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* t-mpi-bit.c - Tests for bit level functions
+ * Copyright (C) 2006 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+#define PGM "t-mpi-bit"
+
+static const char *wherestr;
+static int verbose;
+static int error_count;
+
+#define xmalloc(a) gcry_xmalloc ((a))
+#define xcalloc(a,b) gcry_xcalloc ((a),(b))
+#define xfree(a) gcry_free ((a))
+#define pass() do { ; } while (0)
+
+static void
+show (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ if (!verbose)
+ return;
+ fprintf (stderr, "%s: ", PGM);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+}
+
+static void
+fail (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+ fprintf (stderr, "%s: ", PGM);
+ if (wherestr)
+ fprintf (stderr, "%s: ", wherestr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ fflush (stdout);
+ fprintf (stderr, "%s: ", PGM);
+ if (wherestr)
+ fprintf (stderr, "%s: ", wherestr);
+ va_start (arg_ptr, format);
+ vfprintf (stderr, format, arg_ptr);
+ va_end (arg_ptr);
+ exit (1);
+}
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI
+ A. Return the LENGTH least significant bits. Caller needs to xfree
+ the result. */
+static char *
+mpi2bitstr (gcry_mpi_t a, size_t length)
+{
+ char *p, *buf;
+
+ buf = p = xmalloc (length+1);
+ while (length--)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p = 0;
+
+ return buf;
+}
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do
+ not return any leading zero bits. Caller needs to xfree the
+ result. */
+static char *
+mpi2bitstr_nlz (gcry_mpi_t a)
+{
+ char *p, *buf;
+ size_t length = gcry_mpi_get_nbits (a);
+
+ if (!length)
+ {
+ buf = p = xmalloc (2);
+ *p++ = '0';
+ }
+ else
+ {
+ buf = p = xmalloc (length + 1);
+ while (length-- > 1)
+ *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+ *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+ }
+ *p = 0;
+ return buf;
+}
+
+/* Shift a bit string to the right. */
+static void
+rshiftbitstring (char *string, size_t n)
+{
+ size_t len = strlen (string);
+
+ if (n > len)
+ n = len;
+
+ memmove (string+n, string, len-n);
+ memset (string, '0', n);
+}
+
+/* Shift a bit string to the left. Caller needs to free the result. */
+static char *
+lshiftbitstring (const char *string, size_t n)
+{
+ size_t len = strlen (string);
+ char *result;
+
+ if (len+n+1 < len)
+ die ("internal overflow\n");
+ /* Allocate enough space. */
+ result = xmalloc (len+n+1);
+ for (; *string == '0' && string[1]; string++, len--)
+ ;
+ memcpy (result, string, len);
+ if (*string == '0' && !string[1])
+ n = 0; /* Avoid extra nulls for an only 0 string. */
+ else
+ memset (result+len, '0', n);
+ result[len+n] = 0;
+ return result;
+}
+
+
+/* This is to check a bug reported by bpgcrypt at itaparica.org on
+ 2006-07-31 against libgcrypt 1.2.2. */
+static void
+one_bit_only (int highbit)
+{
+ gcry_mpi_t a;
+ char *result;
+ int i;
+
+ wherestr = "one_bit_only";
+ show ("checking that set_%sbit does only set one bit\n", highbit?"high":"");
+
+ a = gcry_mpi_new (0);
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+ gcry_mpi_set_ui (a, 0);
+
+ if (highbit)
+ gcry_mpi_set_highbit (a, 42);
+ else
+ gcry_mpi_set_bit (a, 42);
+ if (!gcry_mpi_test_bit (a, 42))
+ fail ("failed to set a bit\n");
+ gcry_mpi_clear_bit (a, 42);
+ if (gcry_mpi_test_bit (a, 42))
+ fail ("failed to clear a bit\n");
+ result = mpi2bitstr (a, 70);
+ assert (strlen (result) == 70);
+ for (i=0; result[i]; i++)
+ if ( result[i] != '0' )
+ break;
+ if (result[i])
+ fail ("spurious bits detected\n");
+ xfree (result);
+ gcry_mpi_release (a);
+}
+
+/* Check that right shifting actually works for an amount larger than
+ the number of bits per limb. */
+static void
+test_rshift (int pass)
+{
+ gcry_mpi_t a, b;
+ char *result, *result2;
+ int i;
+
+ wherestr = "test_rshift";
+ show ("checking that rshift works as expected (pass %d)\n", pass);
+
+ a = gcry_mpi_new (0);
+ b = gcry_mpi_new (0);
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_rshift (b, a, i);
+
+ result = mpi2bitstr (b, 72);
+ result2 = mpi2bitstr (a, 72);
+ rshiftbitstring (result2, i);
+ if (strcmp (result, result2))
+ {
+ show ("got =%s\n", result);
+ show ("want=%s\n", result2);
+ fail ("rshift by %d failed\n", i);
+ }
+ xfree (result);
+ xfree (result2);
+ }
+
+ /* Again. This time using in-place operation. */
+ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_release (b);
+ b = gcry_mpi_copy (a);
+ gcry_mpi_rshift (b, b, i);
+
+ result = mpi2bitstr (b, 72);
+ result2 = mpi2bitstr (a, 72);
+ rshiftbitstring (result2, i);
+ if (strcmp (result, result2))
+ {
+ show ("got =%s\n", result);
+ show ("want=%s\n", result2);
+ fail ("in-place rshift by %d failed\n", i);
+ }
+ xfree (result2);
+ xfree (result);
+ }
+
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+}
+
+/* Check that left shifting works correctly. */
+static void
+test_lshift (int pass)
+{
+ static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0};
+ int size_idx;
+ gcry_mpi_t a, b;
+ char *tmpstr, *result, *result2;
+ int i;
+
+ wherestr = "test_lshift";
+ show ("checking that lshift works as expected (pass %d)\n", pass);
+
+ for (size_idx=0; size_list[size_idx]; size_idx++)
+ {
+ a = gcry_mpi_new (0);
+ b = gcry_mpi_new (0);
+
+ /* gcry_mpi_randomize rounds up to full bytes, thus we need to
+ use gcry_mpi_clear_highbit to fix that. */
+ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
+ gcry_mpi_clear_highbit (a, size_list[size_idx]);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_lshift (b, a, i);
+
+ result = mpi2bitstr_nlz (b);
+ tmpstr = mpi2bitstr_nlz (a);
+ result2 = lshiftbitstring (tmpstr, i);
+ xfree (tmpstr);
+ if (strcmp (result, result2))
+ {
+ show ("got =%s\n", result);
+ show ("want=%s\n", result2);
+ fail ("lshift by %d failed\n", i);
+ }
+ xfree (result);
+ xfree (result2);
+ }
+
+ /* Again. This time using in-place operation. */
+ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
+ gcry_mpi_clear_highbit (a, size_list[size_idx]);
+
+ for (i=0; i < 75; i++)
+ {
+ gcry_mpi_release (b);
+ b = gcry_mpi_copy (a);
+ gcry_mpi_lshift (b, b, i);
+
+ result = mpi2bitstr_nlz (b);
+ tmpstr = mpi2bitstr_nlz (a);
+ result2 = lshiftbitstring (tmpstr, i);
+ xfree (tmpstr);
+ if (strcmp (result, result2))
+ {
+ show ("got =%s\n", result);
+ show ("want=%s\n", result2);
+ fail ("in-place lshift by %d failed\n", i);
+ }
+ xfree (result2);
+ xfree (result);
+ }
+
+ gcry_mpi_release (b);
+ gcry_mpi_release (a);
+ }
+}
+
+
+int
+main (int argc, char **argv)
+{
+ int debug = 0;
+ int i;
+
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+ else if (argc > 1 && !strcmp (argv[1], "--debug"))
+ verbose = debug = 1;
+
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch\n");
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+ one_bit_only (0);
+ one_bit_only (1);
+ for (i=0; i < 5; i++)
+ test_rshift (i); /* Run several times due to random initializations. */
+
+ for (i=0; i < 5; i++)
+ test_lshift (i); /* Run several times due to random initializations. */
+
+ show ("All tests completed. Errors: %d\n", error_count);
+ return error_count ? 1 : 0;
+}
--- /dev/null
+/* testapi.c - for libgcrypt
+ * Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser general Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <gcrypt.h>
+
+
+#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
+ exit(2);} while(0)
+
+/* an ElGamal public key */
+struct {
+ const char *p,*g,*y;
+} elg_testkey1 = {
+ "0x9D559F31A6D30492C383213844AEBB7772963A85D3239F3611AAB93A2A985F64FB735B9259EC326BF5720F909980D609D37C288C9223B0350FBE493C3B5AF54CA23031E952E92F8A3DBEDBC5A684993D452CD54F85B85160166FCD25BD7AB6AE9B1EB4FCC9D300DAFF081C4CBA6694906D3E3FF18196A5CCF7F0A6182962166B",
+ "0x5",
+ "0x9640024BB2A277205813FF685048AA27E2B192B667163E7C59E381E27003D044C700C531CE8FD4AA781B463BC9FFE74956AF09A38A098322B1CF72FC896F009E3A6BFF053D3B1D1E1994BF9CC07FA12963D782F027B51511DDE8C5F43421FBC12734A9C070F158C729A370BEE5FC51A772219438EDA8202C35FA3F5D8CD1997B"
+};
+
+void
+test_sexp ( int argc, char **argv )
+{
+ int rc, nbits;
+ gcry_sexp_t sexp;
+ gcry_mpi_t key[3];
+ size_t n;
+ char *buf;
+
+ if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, NULL ) )
+ BUG();
+ if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, NULL ) )
+ BUG();
+ if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, NULL ) )
+ BUG();
+
+ /* get nbits from a key */
+ rc = gcry_sexp_build ( &sexp, NULL,
+ "(public-key(elg(p%m)(g%m)(y%m)))",
+ key[0], key[1], key[2] );
+ fputs ( "DUMP of PK:\n", stderr );
+ gcry_sexp_dump ( sexp );
+ { gcry_sexp_t x;
+ x = gcry_sexp_cdr ( sexp );
+ fputs ( "DUMP of CDR:\n", stderr );
+ gcry_sexp_dump ( x );
+ gcry_sexp_release ( x );
+ }
+ nbits = gcry_pk_get_nbits( sexp );
+ printf ( "elg_testkey1 - nbits=%d\n", nbits );
+ n = gcry_sexp_sprint ( sexp, 0, NULL, 0 );
+ buf = gcry_xmalloc ( n );
+ n = gcry_sexp_sprint ( sexp, 0, buf, n );
+ printf ( "sprint length=%u\n", (unsigned int)n );
+ gcry_free ( buf );
+ gcry_sexp_release( sexp );
+}
+
+
+void
+test_genkey ( int argc, char **argv )
+{
+ int rc, nbits = 1024;
+ gcry_sexp_t s_parms, s_key;
+
+ gcry_control( GCRYCTL_INIT_SECMEM, 16384, 0 );
+ rc = gcry_sexp_build ( &s_parms, NULL, "(genkey(dsa(nbits %d)))", nbits );
+ rc = gcry_pk_genkey( &s_key, s_parms );
+ if ( rc ) {
+ fprintf ( stderr, "genkey failed: %s\n", gpg_strerror (rc) );
+ return;
+ }
+ gcry_sexp_release( s_parms );
+ gcry_sexp_dump ( s_key );
+ gcry_sexp_release( s_key );
+}
+
+int
+main( int argc, char **argv )
+{
+ if ( argc < 2 )
+ printf("%s\n", gcry_check_version ( NULL ) );
+ else if ( !strcmp ( argv[1], "version") )
+ printf("%s\n", gcry_check_version ( argc > 2 ? argv[2] : NULL ) );
+ else if ( !strcmp ( argv[1], "sexp" ) )
+ test_sexp ( argc-2, argv+2 );
+ else if ( !strcmp ( argv[1], "genkey" ) )
+ test_genkey ( argc-2, argv+2 );
+ else {
+ fprintf (stderr, "usage: testapi mode-string [mode-args]\n");
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+/* tsexp.c - S-expression regression tests
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include "../src/gcrypt.h"
+
+#define PGMNAME "tsexp"
+
+static int verbose;
+static int error_count;
+
+static void
+info (const char *format, ...)
+{
+ va_list arg_ptr;
+
+ if (verbose)
+ {
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ }
+}
+
+static void
+fail ( const char *format, ... )
+{
+ va_list arg_ptr ;
+
+ fputs (PGMNAME ": ", stderr);
+ va_start( arg_ptr, format ) ;
+ vfprintf (stderr, format, arg_ptr );
+ va_end(arg_ptr);
+ error_count++;
+}
+
+
+/* fixme: we need better tests */
+static void
+basic (void)
+{
+ int pass;
+ gcry_sexp_t sexp;
+ int idx;
+ char *secure_buffer;
+ size_t secure_buffer_len;
+ const char *string;
+ static struct {
+ const char *token;
+ const char *parm;
+ } values[] = {
+ { "public-key", NULL },
+ { "dsa", NULL },
+ { "dsa", "p" },
+ { "dsa", "y" },
+ { "dsa", "q" },
+ { "dsa", "g" },
+ { NULL }
+ };
+
+ info ("doing some pretty pointless tests\n");
+
+ secure_buffer_len = 99;
+ secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
+ memset (secure_buffer, 'G', secure_buffer_len);
+
+ for (pass=0;;pass++)
+ {
+ switch (pass)
+ {
+ case 0:
+ string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
+ "(q #61626364656667#) (g %m)))");
+
+ if ( gcry_sexp_build (&sexp, NULL, string,
+ gcry_mpi_set_ui (NULL, 42)) )
+ {
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ break;
+
+ case 1:
+ string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
+ "(q %b) (g %m)))");
+
+ if ( gcry_sexp_build (&sexp, NULL, string,
+ 15, "foo\0\x01\0x02789012345",
+ gcry_mpi_set_ui (NULL, 42)) )
+ {
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ break;
+
+ case 2:
+ string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
+ "(q %b) (g %m)))");
+
+ if ( gcry_sexp_build (&sexp, NULL, string,
+ secure_buffer_len, secure_buffer,
+ gcry_mpi_set_ui (NULL, 17)) )
+ {
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ if (!gcry_is_secure (sexp))
+ fail ("gcry_sexp_build did not switch to secure memory\n");
+ break;
+
+ case 3:
+ {
+ gcry_sexp_t help_sexp;
+
+ if (gcry_sexp_new (&help_sexp,
+ "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
+ {
+ fail (" scanning fixed string failed\n");
+ return;
+ }
+
+ string = ("(public-key (dsa (p #41424344#) (parm %S) "
+ "(y dummy)(q %b) (g %m)))");
+ if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
+ secure_buffer_len, secure_buffer,
+ gcry_mpi_set_ui (NULL, 17)) )
+ {
+ fail (" scanning `%s' failed\n", string);
+ return;
+ }
+ gcry_sexp_release (help_sexp);
+ }
+ break;
+
+
+ default:
+ return; /* Ready. */
+ }
+
+
+ /* now find something */
+ for (idx=0; values[idx].token; idx++)
+ {
+ const char *token = values[idx].token;
+ const char *parm = values[idx].parm;
+ gcry_sexp_t s1, s2;
+ gcry_mpi_t a;
+ const char *p;
+ size_t n;
+
+ s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
+ if (!s1)
+ {
+ fail ("didn't found `%s'\n", token);
+ continue;
+ }
+
+ p = gcry_sexp_nth_data (s1, 0, &n);
+ if (!p)
+ {
+ fail ("no car for `%s'\n", token);
+ continue;
+ }
+ info ("car=`%.*s'\n", (int)n, p);
+
+ s2 = gcry_sexp_cdr (s1);
+ if (!s2)
+ {
+ fail ("no cdr for `%s'\n", token);
+ continue;
+ }
+
+ p = gcry_sexp_nth_data (s2, 0, &n);
+ if (p)
+ {
+ fail ("data at car of `%s'\n", token);
+ continue;
+ }
+
+ if (parm)
+ {
+ s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
+ if (!s2)
+ {
+ fail ("didn't found `%s'\n", parm);
+ continue;
+ }
+ p = gcry_sexp_nth_data (s2, 0, &n);
+ if (!p)
+ {
+ fail("no car for `%s'\n", parm );
+ continue;
+ }
+ info ("car=`%.*s'\n", (int)n, p);
+ p = gcry_sexp_nth_data (s2, 1, &n);
+ if (!p)
+ {
+ fail("no cdr for `%s'\n", parm );
+ continue;
+ }
+ info ("cdr=`%.*s'\n", (int)n, p);
+
+ a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
+ if (!a)
+ {
+ fail("failed to cdr the mpi for `%s'\n", parm);
+ continue;
+ }
+ }
+ }
+
+ gcry_sexp_release (sexp);
+ sexp = NULL;
+ }
+ gcry_free (secure_buffer);
+}
+
+
+static void
+canon_len (void)
+{
+ static struct {
+ size_t textlen; /* length of the buffer */
+ size_t expected;/* expected length or 0 on error and then ... */
+ size_t erroff; /* ... and at this offset */
+ gcry_error_t errcode; /* ... with this error code */
+ const char *text;
+ } values[] = {
+ { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
+ { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
+ { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
+ { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
+ { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
+ { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
+ { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
+ { 2, 2, 0, GPG_ERR_NO_ERROR, "()"},
+ { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"},
+ { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"},
+ { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
+ { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
+ { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
+ { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
+ /* fixme: we need much more cases */
+ { 0 },
+ };
+ int idx;
+ gcry_error_t errcode;
+ size_t n, erroff;
+
+ info ("checking canoncial length test function\n");
+ for (idx=0; values[idx].text; idx++)
+ {
+ n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
+ values[idx].textlen,
+ &erroff, &errcode);
+
+ if (n && n == values[idx].expected)
+ ; /* success */
+ else if (!n && !values[idx].expected)
+ { /* we expected an error - check that this is the right one */
+ if (values[idx].erroff != erroff)
+ fail ("canonical length test %d - wrong error offset %u\n",
+ idx, (unsigned int)erroff);
+ if (gcry_err_code (errcode) != values[idx].errcode)
+ fail ("canonical length test %d - wrong error code %d\n",
+ idx, errcode);
+ }
+ else
+ fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
+ idx, (unsigned int)n, (unsigned int)erroff, errcode);
+ }
+}
+
+
+static void
+back_and_forth_one (int testno, const char *buffer, size_t length)
+{
+ gcry_error_t rc;
+ gcry_sexp_t se, se1;
+ size_t n, n1;
+ char *p1;
+
+ rc = gcry_sexp_new (&se, buffer, length, 1);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
+ return;
+ }
+ n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
+ if (!n1)
+ {
+ fail ("baf %d: get required length for canon failed\n", testno);
+ return;
+ }
+ p1 = gcry_xmalloc (n1);
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
+ if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
+ {
+ fail ("baf %d: length mismatch for canon\n", testno);
+ return;
+ }
+ rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_create failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ gcry_sexp_release (se1);
+
+ /* Again but with memory checking. */
+ p1 = gcry_xmalloc (n1+2);
+ *p1 = '\x55';
+ p1[n1+1] = '\xaa';
+ n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
+ if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
+ {
+ fail ("baf %d: length mismatch for canon\n", testno);
+ return;
+ }
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (1)\n", testno);
+ rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
+ if (rc)
+ {
+ fail ("baf %d: gcry_sexp_create failed: %s\n",
+ testno, gpg_strerror (rc));
+ return;
+ }
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (2)\n", testno);
+ gcry_sexp_release (se1);
+ if (*p1 != '\x55' || p1[n1+1] != '\xaa')
+ fail ("baf %d: memory corrupted (3)\n", testno);
+ gcry_free (p1);
+
+ /* FIXME: we need a lot more tests */
+
+ gcry_sexp_release (se);
+}
+
+
+
+static void
+back_and_forth (void)
+{
+ static struct { const char *buf; int len; } tests[] = {
+ { "(7:g34:fgh1::2:())", 0 },
+ { "(7:g34:fgh1::2:())", 18 },
+ {
+"(protected-private-key \n"
+" (rsa \n"
+" (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
+" (e #010001#)\n"
+" (protected openpgp-s2k3-sha1-aes-cbc \n"
+" (\n"
+" (sha1 #C2A5673BD3882405# \"96\")\n"
+" #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
+" #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
+" )\n"
+" )\n", 0 },
+ { NULL, 0 }
+ };
+ int idx;
+
+ for (idx=0; tests[idx].buf; idx++)
+ back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
+}
+
+
+static void
+check_sscan (void)
+{
+ static struct {
+ const char *text;
+ gcry_error_t expected_err;
+ } values[] = {
+ /* Bug reported by Olivier L'Heureux 2003-10-07 */
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
+ GPG_ERR_NO_ERROR },
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
+ GPG_ERR_SEXP_UNMATCHED_PAREN },
+ { "(7:sig-val(3:dsa"
+ "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
+ "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
+ "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
+ "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
+ GPG_ERR_SEXP_UNMATCHED_PAREN },
+ { NULL, 0 }
+ };
+ int idx;
+ gcry_error_t err;
+ gcry_sexp_t s;
+
+ info ("checking gcry_sexp_sscan\n");
+ for (idx=0; values[idx].text; idx++)
+ {
+ err = gcry_sexp_sscan (&s, NULL,
+ values[idx].text,
+ strlen (values[idx].text));
+ if (gpg_err_code (err) != values[idx].expected_err)
+ fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
+ gcry_sexp_release (s);
+ }
+}
+
+
+
+
+int
+main (int argc, char **argv)
+{
+ if (argc > 1 && !strcmp (argv[1], "--verbose"))
+ verbose = 1;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
+ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+
+ basic ();
+ canon_len ();
+ back_and_forth ();
+ check_sscan ();
+
+ return error_count? 1:0;
+}
--- /dev/null
+/* version.c - This version test should be run first.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+
+ This file is part of Libgcrypt.
+
+ Libgcrypt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of
+ the License, or (at your option) any later version.
+
+ Libgcrypt 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* This test should be run first because due to a failing config.links
+ script or bad configure parameters the just build libgcrypt may
+ crash in case MPI function for specific CPU revisions have been
+ enabled. Running this test first will print out information so to
+ make it easier to figure out the problem. */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+#define PGM "version"
+
+
+int
+main (int argc, char **argv)
+{
+ (void)argc;
+ (void)argv;
+
+ gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
+ {
+ int oops = !gcry_check_version (GCRYPT_VERSION);
+ fprintf (stderr, PGM ": %sversion mismatch; pgm=%s, library=%s\n",
+ oops? "":"warning: ", GCRYPT_VERSION, gcry_check_version (NULL));
+ if (oops)
+ exit (1);
+ }
+
+ gcry_control (GCRYCTL_PRINT_CONFIG, NULL);
+
+ return 0;
+}